Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Latest 25 from a total of 1,174 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Cancel | 37170245 | 2 hrs ago | IN | 0 ETH | 0.00000669 | ||||
| Match Orders | 37157229 | 3 hrs ago | IN | 0.00185 ETH | 0.00001923 | ||||
| Match Orders | 37157131 | 3 hrs ago | IN | 0.00185 ETH | 0.00002594 | ||||
| Match Orders | 37157037 | 3 hrs ago | IN | 0.00175 ETH | 0.00002623 | ||||
| Match Orders | 37117347 | 7 hrs ago | IN | 0.00185 ETH | 0.00001922 | ||||
| Match Orders | 37117199 | 7 hrs ago | IN | 0.00185 ETH | 0.00002541 | ||||
| Match Orders | 37108281 | 8 hrs ago | IN | 0 ETH | 0.00002349 | ||||
| Match Orders | 37086822 | 11 hrs ago | IN | 0.00175 ETH | 0.0000255 | ||||
| Match Orders | 37081735 | 11 hrs ago | IN | 0.00185 ETH | 0.000025 | ||||
| Match Orders | 37078813 | 12 hrs ago | IN | 0.00185 ETH | 0.00002498 | ||||
| Cancel | 37075407 | 12 hrs ago | IN | 0 ETH | 0.00000634 | ||||
| Match Orders | 37070947 | 12 hrs ago | IN | 0.0019 ETH | 0.00002651 | ||||
| Match Orders | 37070716 | 12 hrs ago | IN | 0.0034 ETH | 0.0000255 | ||||
| Match Orders | 37068361 | 13 hrs ago | IN | 0.0035 ETH | 0.0000255 | ||||
| Cancel | 37053923 | 15 hrs ago | IN | 0 ETH | 0.00000457 | ||||
| Cancel | 37053727 | 15 hrs ago | IN | 0 ETH | 0.00000669 | ||||
| Match Orders | 37046863 | 15 hrs ago | IN | 0.0035 ETH | 0.00001889 | ||||
| Match Orders | 37046819 | 15 hrs ago | IN | 0.0035 ETH | 0.00001889 | ||||
| Match Orders | 37046775 | 16 hrs ago | IN | 0.0035 ETH | 0.00001889 | ||||
| Match Orders | 37045999 | 16 hrs ago | IN | 0.0035 ETH | 0.0000255 | ||||
| Match Orders | 37045001 | 16 hrs ago | IN | 0.019 ETH | 0.00002332 | ||||
| Match Orders | 37042936 | 16 hrs ago | IN | 0.00185 ETH | 0.0000255 | ||||
| Match Orders | 37009693 | 20 hrs ago | IN | 0 ETH | 0.00001825 | ||||
| Match Orders | 37009619 | 20 hrs ago | IN | 0 ETH | 0.00001825 | ||||
| Match Orders | 37009546 | 20 hrs ago | IN | 0 ETH | 0.00002018 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 37157229 | 3 hrs ago | 0.00169275 ETH | ||||
| 37157229 | 3 hrs ago | 0.000037 ETH | ||||
| 37157229 | 3 hrs ago | 0.00012025 ETH | ||||
| 37157229 | 3 hrs ago | 0.00185 ETH | ||||
| 37157131 | 3 hrs ago | 0.00169275 ETH | ||||
| 37157131 | 3 hrs ago | 0.000037 ETH | ||||
| 37157131 | 3 hrs ago | 0.00012025 ETH | ||||
| 37157131 | 3 hrs ago | 0.00185 ETH | ||||
| 37157037 | 3 hrs ago | 0.00160125 ETH | ||||
| 37157037 | 3 hrs ago | 0.000035 ETH | ||||
| 37157037 | 3 hrs ago | 0.00011375 ETH | ||||
| 37157037 | 3 hrs ago | 0.00175 ETH | ||||
| 37117347 | 7 hrs ago | 0.00169275 ETH | ||||
| 37117347 | 7 hrs ago | 0.000037 ETH | ||||
| 37117347 | 7 hrs ago | 0.00012025 ETH | ||||
| 37117347 | 7 hrs ago | 0.00185 ETH | ||||
| 37117199 | 7 hrs ago | 0.00169275 ETH | ||||
| 37117199 | 7 hrs ago | 0.000037 ETH | ||||
| 37117199 | 7 hrs ago | 0.00012025 ETH | ||||
| 37117199 | 7 hrs ago | 0.00185 ETH | ||||
| 37086822 | 11 hrs ago | 0.00160125 ETH | ||||
| 37086822 | 11 hrs ago | 0.000035 ETH | ||||
| 37086822 | 11 hrs ago | 0.00011375 ETH | ||||
| 37086822 | 11 hrs ago | 0.00175 ETH | ||||
| 37081735 | 11 hrs ago | 0.00169275 ETH |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
ExchangeMetaV2
Compiler Version
v0.7.6+commit.7338295f
ZkSolc Version
v1.3.18
Optimization Enabled:
Yes with Mode z
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "./ExchangeV2Core.sol";
import "@rarible/meta-tx/contracts/EIP712MetaTransaction.sol";
import "@rarible/transfer-manager/contracts/RaribleTransferManager.sol";
contract ExchangeMetaV2 is ExchangeV2Core, RaribleTransferManager, EIP712MetaTransaction {
function __ExchangeV2_init(
address _transferProxy,
address _erc20TransferProxy,
uint newProtocolFee,
address newDefaultFeeReceiver,
IRoyaltiesProvider newRoyaltiesProvider
) external initializer {
__Context_init_unchained();
__Ownable_init_unchained();
__OrderValidator_init_unchained();
__MetaTransaction_init_unchained("ExchangeMetaV2", "1");
__TransferExecutor_init_unchained(_transferProxy, _erc20TransferProxy);
__RaribleTransferManager_init_unchained(newProtocolFee, newDefaultFeeReceiver, newRoyaltiesProvider);
}
function _msgSender() internal view virtual override(ContextUpgradeable, EIP712MetaTransaction) returns (address payable) {
return super._msgSender();
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal initializer {
__Context_init_unchained();
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal initializer {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../proxy/Initializable.sol";
/**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
*
* The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
* thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
* they need in their contracts using a combination of `abi.encode` and `keccak256`.
*
* This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
* scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
* ({_hashTypedDataV4}).
*
* The implementation of the domain separator was designed to be as efficient as possible while still properly updating
* the chain id to protect against replay attacks on an eventual fork of the chain.
*
* NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
* https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
*
* _Available since v3.4._
*/
abstract contract EIP712Upgradeable is Initializable {
/* solhint-disable var-name-mixedcase */
bytes32 private _HASHED_NAME;
bytes32 private _HASHED_VERSION;
bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
/* solhint-enable var-name-mixedcase */
/**
* @dev Initializes the domain separator and parameter caches.
*
* The meaning of `name` and `version` is specified in
* https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
*
* - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
* - `version`: the current major version of the signing domain.
*
* NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
* contract upgrade].
*/
function __EIP712_init(string memory name, string memory version) internal initializer {
__EIP712_init_unchained(name, version);
}
function __EIP712_init_unchained(string memory name, string memory version) internal initializer {
bytes32 hashedName = keccak256(bytes(name));
bytes32 hashedVersion = keccak256(bytes(version));
_HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion;
}
/**
* @dev Returns the domain separator for the current chain.
*/
function _domainSeparatorV4() internal view returns (bytes32) {
return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());
}
function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) {
return keccak256(
abi.encode(
typeHash,
name,
version,
_getChainId(),
address(this)
)
);
}
/**
* @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
* function returns the hash of the fully encoded EIP712 message for this domain.
*
* This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
*
* ```solidity
* bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
* keccak256("Mail(address to,string contents)"),
* mailTo,
* keccak256(bytes(mailContents))
* )));
* address signer = ECDSA.recover(digest, signature);
* ```
*/
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", _domainSeparatorV4(), structHash));
}
function _getChainId() private view returns (uint256 chainId) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
// solhint-disable-next-line no-inline-assembly
assembly {
chainId := chainid()
}
}
/**
* @dev The hash of the name parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712NameHash() internal virtual view returns (bytes32) {
return _HASHED_NAME;
}
/**
* @dev The hash of the version parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712VersionHash() internal virtual view returns (bytes32) {
return _HASHED_VERSION;
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC165Upgradeable.sol";
import "../proxy/Initializable.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
function __ERC165_init() internal initializer {
__ERC165_init_unchained();
}
function __ERC165_init_unchained() internal initializer {
// Derived contracts need only register support for their own interfaces,
// we register support for ERC165 itself here
_registerInterface(_INTERFACE_ID_ERC165);
}
/**
* @dev See {IERC165-supportsInterface}.
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165Upgradeable {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMathUpgradeable {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: MIT
// solhint-disable-next-line compiler-version
pragma solidity >=0.4.24 <0.8.0;
import "../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
/// @dev Returns true if and only if the function is running in the constructor
function _isConstructor() private view returns (bool) {
return !AddressUpgradeable.isContract(address(this));
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC1155ReceiverUpgradeable.sol";
import "../../introspection/ERC165Upgradeable.sol";
import "../../proxy/Initializable.sol";
/**
* @dev _Available since v3.1._
*/
abstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {
function __ERC1155Receiver_init() internal initializer {
__ERC165_init_unchained();
__ERC1155Receiver_init_unchained();
}
function __ERC1155Receiver_init_unchained() internal initializer {
_registerInterface(
ERC1155ReceiverUpgradeable(address(0)).onERC1155Received.selector ^
ERC1155ReceiverUpgradeable(address(0)).onERC1155BatchReceived.selector
);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC1155Upgradeable.sol";
import "./IERC1155MetadataURIUpgradeable.sol";
import "./IERC1155ReceiverUpgradeable.sol";
import "../../utils/ContextUpgradeable.sol";
import "../../introspection/ERC165Upgradeable.sol";
import "../../math/SafeMathUpgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../proxy/Initializable.sol";
/**
*
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/
contract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {
using SafeMathUpgradeable for uint256;
using AddressUpgradeable for address;
// Mapping from token ID to account balances
mapping (uint256 => mapping(address => uint256)) private _balances;
// Mapping from account to operator approvals
mapping (address => mapping(address => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/*
* bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
* bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a
* bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6
*
* => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^
* 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26
*/
bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;
/*
* bytes4(keccak256('uri(uint256)')) == 0x0e89341c
*/
bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;
/**
* @dev See {_setURI}.
*/
function __ERC1155_init(string memory uri_) internal initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155_init_unchained(uri_);
}
function __ERC1155_init_unchained(string memory uri_) internal initializer {
_setURI(uri_);
// register the supported interfaces to conform to ERC1155 via ERC165
_registerInterface(_INTERFACE_ID_ERC1155);
// register the supported interfaces to conform to ERC1155MetadataURI via ERC165
_registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256) external view virtual override returns (string memory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: balance query for the zero address");
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(
address[] memory accounts,
uint256[] memory ids
)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
require(_msgSender() != operator, "ERC1155: setting approval status for self");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
)
public
virtual
override
{
require(to != address(0), "ERC1155: transfer to the zero address");
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][from] = _balances[id][from].sub(amount, "ERC1155: insufficient balance for transfer");
_balances[id][to] = _balances[id][to].add(amount);
emit TransferSingle(operator, from, to, id, amount);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
)
public
virtual
override
{
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: transfer caller is not owner nor approved"
);
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
_balances[id][from] = _balances[id][from].sub(
amount,
"ERC1155: insufficient balance for transfer"
);
_balances[id][to] = _balances[id][to].add(amount);
}
emit TransferBatch(operator, from, to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {
require(account != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][account] = _balances[id][account].add(amount);
emit TransferSingle(operator, address(0), account, id, amount);
_doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint i = 0; i < ids.length; i++) {
_balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `account`
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens of token type `id`.
*/
function _burn(address account, uint256 id, uint256 amount) internal virtual {
require(account != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
_balances[id][account] = _balances[id][account].sub(
amount,
"ERC1155: burn amount exceeds balance"
);
emit TransferSingle(operator, account, address(0), id, amount);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/
function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {
require(account != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
for (uint i = 0; i < ids.length; i++) {
_balances[ids[i]][account] = _balances[ids[i]][account].sub(
amounts[i],
"ERC1155: burn amount exceeds balance"
);
}
emit TransferBatch(operator, account, address(0), ids, amounts);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
)
internal
virtual
{ }
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
)
private
{
if (to.isContract()) {
try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155ReceiverUpgradeable(to).onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
)
private
{
if (to.isContract()) {
try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {
if (response != IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
uint256[47] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "./IERC1155Upgradeable.sol";
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*
* _Available since v3.1._
*/
interface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/
function uri(uint256 id) external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../../introspection/IERC165Upgradeable.sol";
/**
* _Available since v3.1._
*/
interface IERC1155ReceiverUpgradeable is IERC165Upgradeable {
/**
@dev Handles the receipt of a single ERC1155 token type. This function is
called at the end of a `safeTransferFrom` after the balance has been updated.
To accept the transfer, this must return
`bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
(i.e. 0xf23a6e61, or its own function selector).
@param operator The address which initiated the transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param id The ID of the token being transferred
@param value The amount of tokens being transferred
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
)
external
returns(bytes4);
/**
@dev Handles the receipt of a multiple ERC1155 token types. This function
is called at the end of a `safeBatchTransferFrom` after the balances have
been updated. To accept the transfer(s), this must return
`bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
(i.e. 0xbc197c81, or its own function selector).
@param operator The address which initiated the batch transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param ids An array containing ids of each token being transferred (order and length must match values array)
@param values An array containing amounts of each token being transferred (order and length must match ids array)
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
)
external
returns(bytes4);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "../../introspection/IERC165Upgradeable.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155Upgradeable is IERC165Upgradeable {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../../utils/ContextUpgradeable.sol";
import "./IERC20Upgradeable.sol";
import "../../math/SafeMathUpgradeable.sol";
import "../../proxy/Initializable.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin guidelines: functions revert instead
* of returning `false` on failure. This behavior is nonetheless conventional
* and does not conflict with the expectations of ERC20 applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {
using SafeMathUpgradeable for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
/**
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with
* a default value of 18.
*
* To select a different value for {decimals}, use {_setupDecimals}.
*
* All three of these values are immutable: they can only be set once during
* construction.
*/
function __ERC20_init(string memory name_, string memory symbol_) internal initializer {
__Context_init_unchained();
__ERC20_init_unchained(name_, symbol_);
}
function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {
_name = name_;
_symbol = symbol_;
_decimals = 18;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
* called.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return _decimals;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `to` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Sets {decimals} to a value other than the default one of 18.
*
* WARNING: This function should only be called from the constructor. Most
* applications that interact with token contracts will not expect
* {decimals} to ever change, and may work incorrectly if it does.
*/
function _setupDecimals(uint8 decimals_) internal virtual {
_decimals = decimals_;
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
uint256[44] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20Upgradeable {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../../utils/ContextUpgradeable.sol";
import "./IERC721Upgradeable.sol";
import "./IERC721MetadataUpgradeable.sol";
import "./IERC721EnumerableUpgradeable.sol";
import "./IERC721ReceiverUpgradeable.sol";
import "../../introspection/ERC165Upgradeable.sol";
import "../../math/SafeMathUpgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/EnumerableSetUpgradeable.sol";
import "../../utils/EnumerableMapUpgradeable.sol";
import "../../utils/StringsUpgradeable.sol";
import "../../proxy/Initializable.sol";
/**
* @title ERC721 Non-Fungible Token Standard basic implementation
* @dev see https://eips.ethereum.org/EIPS/eip-721
*/
contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {
using SafeMathUpgradeable for uint256;
using AddressUpgradeable for address;
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;
using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;
using StringsUpgradeable for uint256;
// Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
// which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
// Mapping from holder address to their (enumerable) set of owned tokens
mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;
// Enumerable mapping from token ids to their owners
EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;
// Mapping from token ID to approved address
mapping (uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping (address => mapping (address => bool)) private _operatorApprovals;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Optional mapping for token URIs
mapping (uint256 => string) private _tokenURIs;
// Base URI
string private _baseURI;
/*
* bytes4(keccak256('balanceOf(address)')) == 0x70a08231
* bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
* bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
* bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
*
* => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
* 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
*/
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
/*
* bytes4(keccak256('name()')) == 0x06fdde03
* bytes4(keccak256('symbol()')) == 0x95d89b41
* bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
*
* => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
*/
bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
/*
* bytes4(keccak256('totalSupply()')) == 0x18160ddd
* bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
* bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
*
* => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
*/
bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
function __ERC721_init(string memory name_, string memory symbol_) internal initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name_, symbol_);
}
function __ERC721_init_unchained(string memory name_, string memory symbol_) internal initializer {
_name = name_;
_symbol = symbol_;
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_INTERFACE_ID_ERC721);
_registerInterface(_INTERFACE_ID_ERC721_METADATA);
_registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _holderTokens[owner].length();
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(base, tokenId.toString()));
}
/**
* @dev Returns the base URI set via {_setBaseURI}. This will be
* automatically added as a prefix in {tokenURI} to each token's URI, or
* to the token ID if no specific URI is set for that token ID.
*/
function baseURI() public view virtual returns (string memory) {
return _baseURI;
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
return _holderTokens[owner].at(index);
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
// _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
return _tokenOwners.length();
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
(uint256 tokenId, ) = _tokenOwners.at(index);
return tokenId;
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721Upgradeable.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(_msgSender() == owner || ERC721Upgradeable.isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
require(operator != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(address from, address to, uint256 tokenId) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `_data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _tokenOwners.contains(tokenId);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721Upgradeable.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || ERC721Upgradeable.isApprovedForAll(owner, spender));
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
d*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
_mint(to, tokenId);
require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(address(0), to, tokenId);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721Upgradeable.ownerOf(tokenId); // internal owner
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
// Clear metadata (if any)
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
_holderTokens[owner].remove(tokenId);
_tokenOwners.remove(tokenId);
emit Transfer(owner, address(0), tokenId);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(address from, address to, uint256 tokenId) internal virtual {
require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_holderTokens[from].remove(tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(from, to, tokenId);
}
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
/**
* @dev Internal function to set the base URI for all token IDs. It is
* automatically added as a prefix to the value returned in {tokenURI},
* or to the token ID if {tokenURI} is empty.
*/
function _setBaseURI(string memory baseURI_) internal virtual {
_baseURI = baseURI_;
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
private returns (bool)
{
if (!to.isContract()) {
return true;
}
bytes memory returndata = to.functionCall(abi.encodeWithSelector(
IERC721ReceiverUpgradeable(to).onERC721Received.selector,
_msgSender(),
from,
tokenId,
_data
), "ERC721: transfer to non ERC721Receiver implementer");
bytes4 retval = abi.decode(returndata, (bytes4));
return (retval == _ERC721_RECEIVED);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits an {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
uint256[41] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "./IERC721Upgradeable.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721EnumerableUpgradeable is IERC721Upgradeable {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "./IERC721Upgradeable.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721MetadataUpgradeable is IERC721Upgradeable {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721ReceiverUpgradeable {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
*/
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "../../introspection/IERC165Upgradeable.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721Upgradeable is IERC165Upgradeable {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
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");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
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");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../proxy/Initializable.sol";
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal initializer {
__Context_init_unchained();
}
function __Context_init_unchained() internal initializer {
}
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Library for managing an enumerable variant of Solidity's
* https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
* type.
*
* Maps have the following properties:
*
* - Entries are added, removed, and checked for existence in constant time
* (O(1)).
* - Entries are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableMap for EnumerableMap.UintToAddressMap;
*
* // Declare a set state variable
* EnumerableMap.UintToAddressMap private myMap;
* }
* ```
*
* As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are
* supported.
*/
library EnumerableMapUpgradeable {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Map type with
// bytes32 keys and values.
// The Map implementation uses private functions, and user-facing
// implementations (such as Uint256ToAddressMap) are just wrappers around
// the underlying Map.
// This means that we can only create new EnumerableMaps for types that fit
// in bytes32.
struct MapEntry {
bytes32 _key;
bytes32 _value;
}
struct Map {
// Storage of map keys and values
MapEntry[] _entries;
// Position of the entry defined by a key in the `entries` array, plus 1
// because index 0 means a key is not in the map.
mapping (bytes32 => uint256) _indexes;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {
// We read and store the key's index to prevent multiple reads from the same storage slot
uint256 keyIndex = map._indexes[key];
if (keyIndex == 0) { // Equivalent to !contains(map, key)
map._entries.push(MapEntry({ _key: key, _value: value }));
// The entry is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
map._indexes[key] = map._entries.length;
return true;
} else {
map._entries[keyIndex - 1]._value = value;
return false;
}
}
/**
* @dev Removes a key-value pair from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function _remove(Map storage map, bytes32 key) private returns (bool) {
// We read and store the key's index to prevent multiple reads from the same storage slot
uint256 keyIndex = map._indexes[key];
if (keyIndex != 0) { // Equivalent to contains(map, key)
// To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one
// in the array, and then remove the last entry (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = keyIndex - 1;
uint256 lastIndex = map._entries.length - 1;
// When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
MapEntry storage lastEntry = map._entries[lastIndex];
// Move the last entry to the index where the entry to delete is
map._entries[toDeleteIndex] = lastEntry;
// Update the index for the moved entry
map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved entry was stored
map._entries.pop();
// Delete the index for the deleted slot
delete map._indexes[key];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function _contains(Map storage map, bytes32 key) private view returns (bool) {
return map._indexes[key] != 0;
}
/**
* @dev Returns the number of key-value pairs in the map. O(1).
*/
function _length(Map storage map) private view returns (uint256) {
return map._entries.length;
}
/**
* @dev Returns the key-value pair stored at position `index` in the map. O(1).
*
* Note that there are no guarantees on the ordering of entries inside the
* array, and it may change when more entries are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
require(map._entries.length > index, "EnumerableMap: index out of bounds");
MapEntry storage entry = map._entries[index];
return (entry._key, entry._value);
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
uint256 keyIndex = map._indexes[key];
if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)
return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function _get(Map storage map, bytes32 key) private view returns (bytes32) {
uint256 keyIndex = map._indexes[key];
require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key)
return map._entries[keyIndex - 1]._value; // All indexes are 1-based
}
/**
* @dev Same as {_get}, with a custom error message when `key` is not in the map.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {_tryGet}.
*/
function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
uint256 keyIndex = map._indexes[key];
require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
return map._entries[keyIndex - 1]._value; // All indexes are 1-based
}
// UintToAddressMap
struct UintToAddressMap {
Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
return _remove(map._inner, bytes32(key));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
return _contains(map._inner, bytes32(key));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(UintToAddressMap storage map) internal view returns (uint256) {
return _length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the set. O(1).
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
(bytes32 key, bytes32 value) = _at(map._inner, index);
return (uint256(key), address(uint160(uint256(value))));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*
* _Available since v3.4._
*/
function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
(bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
return (success, address(uint160(uint256(value))));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
return address(uint160(uint256(_get(map._inner, bytes32(key)))));
}
/**
* @dev Same as {get}, with a custom error message when `key` is not in the map.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryGet}.
*/
function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSetUpgradeable {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) { // Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev String operations.
*/
library StringsUpgradeable {
/**
* @dev Converts a `uint256` to its ASCII `string` representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
uint256 index = digits - 1;
temp = value;
while (temp != 0) {
buffer[index--] = bytes1(uint8(48 + temp % 10));
temp /= 10;
}
return string(buffer);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165 is IERC165 {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
constructor () internal {
// Derived contracts need only register support for their own interfaces,
// we register support for ERC165 itself here
_registerInterface(_INTERFACE_ID_ERC165);
}
/**
* @dev See {IERC165-supportsInterface}.
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./Proxy.sol";
import "../utils/Address.sol";
import "./IBeacon.sol";
/**
* @dev This contract implements a proxy that gets the implementation address for each call from a {UpgradeableBeacon}.
*
* The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't
* conflict with the storage layout of the implementation behind the proxy.
*
* _Available since v3.4._
*/
contract BeaconProxy is Proxy {
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 private constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Initializes the proxy with `beacon`.
*
* If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This
* will typically be an encoded function call, and allows initializating the storage of the proxy like a Solidity
* constructor.
*
* Requirements:
*
* - `beacon` must be a contract with the interface {IBeacon}.
*/
constructor(address beacon, bytes memory data) public payable {
assert(_BEACON_SLOT == bytes32(uint256(keccak256("eip1967.proxy.beacon")) - 1));
_setBeacon(beacon, data);
}
/**
* @dev Returns the current beacon address.
*/
function _beacon() internal view virtual returns (address beacon) {
bytes32 slot = _BEACON_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
beacon := sload(slot)
}
}
/**
* @dev Returns the current implementation address of the associated beacon.
*/
function _implementation() internal view virtual override returns (address) {
return IBeacon(_beacon()).implementation();
}
/**
* @dev Changes the proxy to use a new beacon.
*
* If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.
*
* Requirements:
*
* - `beacon` must be a contract.
* - The implementation returned by `beacon` must be a contract.
*/
function _setBeacon(address beacon, bytes memory data) internal virtual {
require(
Address.isContract(beacon),
"BeaconProxy: beacon is not a contract"
);
require(
Address.isContract(IBeacon(beacon).implementation()),
"BeaconProxy: beacon implementation is not a contract"
);
bytes32 slot = _BEACON_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(slot, beacon)
}
if (data.length > 0) {
Address.functionDelegateCall(_implementation(), data, "BeaconProxy: function call failed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
* instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
* be specified by overriding the virtual {_implementation} function.
*
* Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
* different contract through the {_delegate} function.
*
* The success and return data of the delegated call will be returned back to the caller of the proxy.
*/
abstract contract Proxy {
/**
* @dev Delegates the current call to `implementation`.
*
* This function does not return to its internall call site, it will return directly to the external caller.
*/
function _delegate(address implementation) internal virtual {
// solhint-disable-next-line no-inline-assembly
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
/**
* @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
* and {_fallback} should delegate.
*/
function _implementation() internal view virtual returns (address);
/**
* @dev Delegates the current call to the address returned by `_implementation()`.
*
* This function does not return to its internall call site, it will return directly to the external caller.
*/
function _fallback() internal virtual {
_beforeFallback();
_delegate(_implementation());
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
*/
fallback () external payable virtual {
_fallback();
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
* is empty.
*/
receive () external payable virtual {
_fallback();
}
/**
* @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
* call, or as part of the Solidity `fallback` or `receive` functions.
*
* If overriden should call `super._beforeFallback()`.
*/
function _beforeFallback() internal virtual {
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../access/Ownable.sol";
import "./TransparentUpgradeableProxy.sol";
/**
* @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an
* explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.
*/
contract ProxyAdmin is Ownable {
/**
* @dev Returns the current implementation of `proxy`.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
// We need to manually run the static call since the getter cannot be flagged as view
// bytes4(keccak256("implementation()")) == 0x5c60da1b
(bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b");
require(success);
return abi.decode(returndata, (address));
}
/**
* @dev Returns the current admin of `proxy`.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
// We need to manually run the static call since the getter cannot be flagged as view
// bytes4(keccak256("admin()")) == 0xf851a440
(bool success, bytes memory returndata) = address(proxy).staticcall(hex"f851a440");
require(success);
return abi.decode(returndata, (address));
}
/**
* @dev Changes the admin of `proxy` to `newAdmin`.
*
* Requirements:
*
* - This contract must be the current admin of `proxy`.
*/
function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {
proxy.changeAdmin(newAdmin);
}
/**
* @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {
proxy.upgradeTo(implementation);
}
/**
* @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See
* {TransparentUpgradeableProxy-upgradeToAndCall}.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {
proxy.upgradeToAndCall{value: msg.value}(implementation, data);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./UpgradeableProxy.sol";
/**
* @dev This contract implements a proxy that is upgradeable by an admin.
*
* To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector
* clashing], which can potentially be used in an attack, this contract uses the
* https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two
* things that go hand in hand:
*
* 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if
* that call matches one of the admin functions exposed by the proxy itself.
* 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the
* implementation. If the admin tries to call a function on the implementation it will fail with an error that says
* "admin cannot fallback to proxy target".
*
* These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing
* the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due
* to sudden errors when trying to call a function from the proxy implementation.
*
* Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
* you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.
*/
contract TransparentUpgradeableProxy is UpgradeableProxy {
/**
* @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
* optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.
*/
constructor(address _logic, address admin_, bytes memory _data) public payable UpgradeableProxy(_logic, _data) {
assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
_setAdmin(admin_);
}
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
*/
modifier ifAdmin() {
if (msg.sender == _admin()) {
_;
} else {
_fallback();
}
}
/**
* @dev Returns the current admin.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function admin() external ifAdmin returns (address admin_) {
admin_ = _admin();
}
/**
* @dev Returns the current implementation.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
*/
function implementation() external ifAdmin returns (address implementation_) {
implementation_ = _implementation();
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.
*/
function changeAdmin(address newAdmin) external virtual ifAdmin {
require(newAdmin != address(0), "TransparentUpgradeableProxy: new admin is the zero address");
emit AdminChanged(_admin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev Upgrade the implementation of the proxy.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.
*/
function upgradeTo(address newImplementation) external virtual ifAdmin {
_upgradeTo(newImplementation);
}
/**
* @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified
* by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the
* proxied contract.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.
*/
function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {
_upgradeTo(newImplementation);
Address.functionDelegateCall(newImplementation, data);
}
/**
* @dev Returns the current admin.
*/
function _admin() internal view virtual returns (address adm) {
bytes32 slot = _ADMIN_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
adm := sload(slot)
}
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
bytes32 slot = _ADMIN_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(slot, newAdmin)
}
}
/**
* @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.
*/
function _beforeFallback() internal virtual override {
require(msg.sender != _admin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target");
super._beforeFallback();
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IBeacon.sol";
import "../access/Ownable.sol";
import "../utils/Address.sol";
/**
* @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their
* implementation contract, which is where they will delegate all function calls.
*
* An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.
*/
contract UpgradeableBeacon is IBeacon, Ownable {
address private _implementation;
/**
* @dev Emitted when the implementation returned by the beacon is changed.
*/
event Upgraded(address indexed implementation);
/**
* @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the
* beacon.
*/
constructor(address implementation_) public {
_setImplementation(implementation_);
}
/**
* @dev Returns the current implementation address.
*/
function implementation() public view virtual override returns (address) {
return _implementation;
}
/**
* @dev Upgrades the beacon to a new implementation.
*
* Emits an {Upgraded} event.
*
* Requirements:
*
* - msg.sender must be the owner of the contract.
* - `newImplementation` must be a contract.
*/
function upgradeTo(address newImplementation) public virtual onlyOwner {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Sets the implementation contract address for this beacon
*
* Requirements:
*
* - `newImplementation` must be a contract.
*/
function _setImplementation(address newImplementation) private {
require(Address.isContract(newImplementation), "UpgradeableBeacon: implementation is not a contract");
_implementation = newImplementation;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./Proxy.sol";
import "../utils/Address.sol";
/**
* @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
* implementation address that can be changed. This address is stored in storage in the location specified by
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
* implementation behind the proxy.
*
* Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see
* {TransparentUpgradeableProxy}.
*/
contract UpgradeableProxy is Proxy {
/**
* @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
*
* If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
* function call, and allows initializating the storage of the proxy like a Solidity constructor.
*/
constructor(address _logic, bytes memory _data) public payable {
assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
_setImplementation(_logic);
if(_data.length > 0) {
Address.functionDelegateCall(_logic, _data);
}
}
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation address.
*/
function _implementation() internal view virtual override returns (address impl) {
bytes32 slot = _IMPLEMENTATION_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
impl := sload(slot)
}
}
/**
* @dev Upgrades the proxy to a new implementation.
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal virtual {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(Address.isContract(newImplementation), "UpgradeableProxy: new implementation is not a contract");
bytes32 slot = _IMPLEMENTATION_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(slot, newImplementation)
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC1155.sol";
import "./IERC1155MetadataURI.sol";
import "./IERC1155Receiver.sol";
import "../../utils/Context.sol";
import "../../introspection/ERC165.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
/**
*
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
using SafeMath for uint256;
using Address for address;
// Mapping from token ID to account balances
mapping (uint256 => mapping(address => uint256)) private _balances;
// Mapping from account to operator approvals
mapping (address => mapping(address => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/*
* bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
* bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a
* bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6
*
* => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^
* 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26
*/
bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;
/*
* bytes4(keccak256('uri(uint256)')) == 0x0e89341c
*/
bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;
/**
* @dev See {_setURI}.
*/
constructor (string memory uri_) public {
_setURI(uri_);
// register the supported interfaces to conform to ERC1155 via ERC165
_registerInterface(_INTERFACE_ID_ERC1155);
// register the supported interfaces to conform to ERC1155MetadataURI via ERC165
_registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256) external view virtual override returns (string memory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: balance query for the zero address");
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(
address[] memory accounts,
uint256[] memory ids
)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
require(_msgSender() != operator, "ERC1155: setting approval status for self");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
)
public
virtual
override
{
require(to != address(0), "ERC1155: transfer to the zero address");
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][from] = _balances[id][from].sub(amount, "ERC1155: insufficient balance for transfer");
_balances[id][to] = _balances[id][to].add(amount);
emit TransferSingle(operator, from, to, id, amount);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
)
public
virtual
override
{
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: transfer caller is not owner nor approved"
);
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
_balances[id][from] = _balances[id][from].sub(
amount,
"ERC1155: insufficient balance for transfer"
);
_balances[id][to] = _balances[id][to].add(amount);
}
emit TransferBatch(operator, from, to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {
require(account != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][account] = _balances[id][account].add(amount);
emit TransferSingle(operator, address(0), account, id, amount);
_doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint i = 0; i < ids.length; i++) {
_balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `account`
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens of token type `id`.
*/
function _burn(address account, uint256 id, uint256 amount) internal virtual {
require(account != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
_balances[id][account] = _balances[id][account].sub(
amount,
"ERC1155: burn amount exceeds balance"
);
emit TransferSingle(operator, account, address(0), id, amount);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/
function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {
require(account != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
for (uint i = 0; i < ids.length; i++) {
_balances[ids[i]][account] = _balances[ids[i]][account].sub(
amounts[i],
"ERC1155: burn amount exceeds balance"
);
}
emit TransferBatch(operator, account, address(0), ids, amounts);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
)
internal
virtual
{ }
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
)
private
{
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155Receiver(to).onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
)
private
{
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {
if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./ERC1155Receiver.sol";
/**
* @dev _Available since v3.1._
*/
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;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC1155Receiver.sol";
import "../../introspection/ERC165.sol";
/**
* @dev _Available since v3.1._
*/
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
constructor() internal {
_registerInterface(
ERC1155Receiver(address(0)).onERC1155Received.selector ^
ERC1155Receiver(address(0)).onERC1155BatchReceived.selector
);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "../../introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "./IERC1155.sol";
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*
* _Available since v3.1._
*/
interface IERC1155MetadataURI is IERC1155 {
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/
function uri(uint256 id) external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../../introspection/IERC165.sol";
/**
* _Available since v3.1._
*/
interface IERC1155Receiver is IERC165 {
/**
@dev Handles the receipt of a single ERC1155 token type. This function is
called at the end of a `safeTransferFrom` after the balance has been updated.
To accept the transfer, this must return
`bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
(i.e. 0xf23a6e61, or its own function selector).
@param operator The address which initiated the transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param id The ID of the token being transferred
@param value The amount of tokens being transferred
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
)
external
returns(bytes4);
/**
@dev Handles the receipt of a multiple ERC1155 token types. This function
is called at the end of a `safeBatchTransferFrom` after the balances have
been updated. To accept the transfer(s), this must return
`bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
(i.e. 0xbc197c81, or its own function selector).
@param operator The address which initiated the batch transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param ids An array containing ids of each token being transferred (order and length must match values array)
@param values An array containing amounts of each token being transferred (order and length must match ids array)
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
)
external
returns(bytes4);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC721Receiver.sol";
/**
* @dev Implementation of the {IERC721Receiver} interface.
*
* Accepts all token transfers.
* Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
*/
contract ERC721Holder is IERC721Receiver {
/**
* @dev See {IERC721Receiver-onERC721Received}.
*
* Always returns `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
*/
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
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");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
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");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor () internal {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/exchange-interfaces/contracts/IAssetMatcher.sol";
import "@rarible/lazy-mint/contracts/erc-721/LibERC721LazyMint.sol";
import "@rarible/lazy-mint/contracts/erc-1155/LibERC1155LazyMint.sol";
/*
* Custom matcher for collection (assetClass, that need any/all elements from collection)
*/
contract AssetMatcherCollection is IAssetMatcher {
bytes constant EMPTY = "";
function matchAssets(LibAsset.AssetType memory leftAssetType, LibAsset.AssetType memory rightAssetType) external view override returns (LibAsset.AssetType memory) {
if (
(rightAssetType.assetClass == LibAsset.ERC721_ASSET_CLASS) ||
(rightAssetType.assetClass == LibERC721LazyMint.ERC721_LAZY_ASSET_CLASS) ||
(rightAssetType.assetClass == LibAsset.ERC1155_ASSET_CLASS) ||
(rightAssetType.assetClass == LibERC1155LazyMint.ERC1155_LAZY_ASSET_CLASS) ||
(rightAssetType.assetClass == LibAsset.CRYPTO_PUNKS)
) {
(address leftToken) = abi.decode(leftAssetType.data, (address));
(address rightToken,) = abi.decode(rightAssetType.data, (address, uint));
if (leftToken == rightToken) {
return LibAsset.AssetType(rightAssetType.assetClass, rightAssetType.data);
}
}
return LibAsset.AssetType(0, EMPTY);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/lib-asset/contracts/LibAsset.sol";
interface IAssetMatcher {
function matchAssets(
LibAsset.AssetType memory leftAssetType,
LibAsset.AssetType memory rightAssetType
) external view returns (LibAsset.AssetType memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
interface IERC20TransferProxy {
function erc20safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol";
interface INftTransferProxy {
function erc721safeTransferFrom(IERC721Upgradeable token, address from, address to, uint256 tokenId) external;
function erc1155safeTransferFrom(IERC1155Upgradeable token, address from, address to, uint256 id, uint256 value, bytes calldata data) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "@rarible/lib-part/contracts/LibPart.sol";
interface IRoyaltiesProvider {
function getRoyalties(address token, uint tokenId) external returns (LibPart.Part[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
import "@rarible/lib-asset/contracts/LibAsset.sol";
interface ITransferProxy {
function transfer(LibAsset.Asset calldata asset, address from, address to) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/exchange-interfaces/contracts/IAssetMatcher.sol";
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
abstract contract AssetMatcher is Initializable, OwnableUpgradeable {
bytes constant EMPTY = "";
mapping(bytes4 => address) internal matchers;
event MatcherChange(bytes4 indexed assetType, address matcher);
function setAssetMatcher(bytes4 assetType, address matcher) external onlyOwner {
matchers[assetType] = matcher;
emit MatcherChange(assetType, matcher);
}
function matchAssets(LibAsset.AssetType memory leftAssetType, LibAsset.AssetType memory rightAssetType) internal view returns (LibAsset.AssetType memory) {
LibAsset.AssetType memory result = matchAssetOneSide(leftAssetType, rightAssetType);
if (result.assetClass == 0) {
return matchAssetOneSide(rightAssetType, leftAssetType);
} else {
return result;
}
}
function matchAssetOneSide(LibAsset.AssetType memory leftAssetType, LibAsset.AssetType memory rightAssetType) private view returns (LibAsset.AssetType memory) {
bytes4 classLeft = leftAssetType.assetClass;
bytes4 classRight = rightAssetType.assetClass;
if (classLeft == LibAsset.ETH_ASSET_CLASS) {
if (classRight == LibAsset.ETH_ASSET_CLASS) {
return leftAssetType;
}
return LibAsset.AssetType(0, EMPTY);
}
if (classLeft == LibAsset.ERC20_ASSET_CLASS) {
if (classRight == LibAsset.ERC20_ASSET_CLASS) {
return simpleMatch(leftAssetType, rightAssetType);
}
return LibAsset.AssetType(0, EMPTY);
}
if (classLeft == LibAsset.ERC721_ASSET_CLASS) {
if (classRight == LibAsset.ERC721_ASSET_CLASS) {
return simpleMatch(leftAssetType, rightAssetType);
}
return LibAsset.AssetType(0, EMPTY);
}
if (classLeft == LibAsset.ERC1155_ASSET_CLASS) {
if (classRight == LibAsset.ERC1155_ASSET_CLASS) {
return simpleMatch(leftAssetType, rightAssetType);
}
return LibAsset.AssetType(0, EMPTY);
}
address matcher = matchers[classLeft];
if (matcher != address(0)) {
return IAssetMatcher(matcher).matchAssets(leftAssetType, rightAssetType);
}
if (classLeft == classRight) {
return simpleMatch(leftAssetType, rightAssetType);
}
revert("not found IAssetMatcher");
}
function simpleMatch(LibAsset.AssetType memory leftAssetType, LibAsset.AssetType memory rightAssetType) private pure returns (LibAsset.AssetType memory) {
bytes32 leftHash = keccak256(leftAssetType.data);
bytes32 rightHash = keccak256(rightAssetType.data);
if (leftHash == rightHash) {
return leftAssetType;
}
return LibAsset.AssetType(0, EMPTY);
}
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "./ExchangeV2Core.sol";
import "@rarible/transfer-manager/contracts/RaribleTransferManager.sol";
contract ExchangeV2 is ExchangeV2Core, RaribleTransferManager {
function __ExchangeV2_init(
address _transferProxy,
address _erc20TransferProxy,
uint newProtocolFee,
address newDefaultFeeReceiver,
IRoyaltiesProvider newRoyaltiesProvider
) external initializer {
__Context_init_unchained();
__Ownable_init_unchained();
__TransferExecutor_init_unchained(_transferProxy, _erc20TransferProxy);
__RaribleTransferManager_init_unchained(newProtocolFee, newDefaultFeeReceiver, newRoyaltiesProvider);
__OrderValidator_init_unchained();
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "./libraries/LibFill.sol";
import "./libraries/LibOrderData.sol";
import "./libraries/LibDirectTransfer.sol";
import "./OrderValidator.sol";
import "./AssetMatcher.sol";
import "@rarible/transfer-manager/contracts/TransferExecutor.sol";
import "@rarible/transfer-manager/contracts/interfaces/ITransferManager.sol";
import "@rarible/transfer-manager/contracts/lib/LibDeal.sol";
abstract contract ExchangeV2Core is Initializable, OwnableUpgradeable, AssetMatcher, TransferExecutor, OrderValidator, ITransferManager {
using SafeMathUpgradeable for uint;
using LibTransfer for address;
uint256 private constant UINT256_MAX = type(uint256).max;
//state of the orders
mapping(bytes32 => uint) public fills;
//events
event Cancel(bytes32 hash);
event Match(bytes32 leftHash, bytes32 rightHash, uint newLeftFill, uint newRightFill);
function cancel(LibOrder.Order memory order) external {
require(_msgSender() == order.maker, "not a maker");
require(order.salt != 0, "0 salt can't be used");
bytes32 orderKeyHash = LibOrder.hashKey(order);
fills[orderKeyHash] = UINT256_MAX;
emit Cancel(orderKeyHash);
}
/**
* @dev function, generate sellOrder and buyOrder from parameters and call validateAndMatch() for purchase transaction
*/
function directPurchase(
LibDirectTransfer.Purchase calldata direct
) external payable{
LibAsset.AssetType memory paymentAssetType = getPaymentAssetType(direct.paymentToken);
LibOrder.Order memory sellOrder = LibOrder.Order(
direct.sellOrderMaker,
LibAsset.Asset(
LibAsset.AssetType(
direct.nftAssetClass,
direct.nftData
),
direct.sellOrderNftAmount
),
address(0),
LibAsset.Asset(
paymentAssetType,
direct.sellOrderPaymentAmount
),
direct.sellOrderSalt,
direct.sellOrderStart,
direct.sellOrderEnd,
direct.sellOrderDataType,
direct.sellOrderData
);
LibOrder.Order memory buyOrder = LibOrder.Order(
address(0),
LibAsset.Asset(
paymentAssetType,
direct.buyOrderPaymentAmount
),
address(0),
LibAsset.Asset(
LibAsset.AssetType(
direct.nftAssetClass,
direct.nftData
),
direct.buyOrderNftAmount
),
0,
0,
0,
direct.sellOrderDataType,
direct.buyOrderData
);
validateFull(sellOrder, direct.sellOrderSignature);
matchAndTransfer(sellOrder, buyOrder);
}
/**
* @dev function, generate sellOrder and buyOrder from parameters and call validateAndMatch() for accept bid transaction
* @param direct struct with parameters for accept bid operation
*/
function directAcceptBid(
LibDirectTransfer.AcceptBid calldata direct
) external payable {
LibAsset.AssetType memory paymentAssetType = getPaymentAssetType(direct.paymentToken);
LibOrder.Order memory buyOrder = LibOrder.Order(
direct.bidMaker,
LibAsset.Asset(
paymentAssetType,
direct.bidPaymentAmount
),
address(0),
LibAsset.Asset(
LibAsset.AssetType(
direct.nftAssetClass,
direct.nftData
),
direct.bidNftAmount
),
direct.bidSalt,
direct.bidStart,
direct.bidEnd,
direct.bidDataType,
direct.bidData
);
LibOrder.Order memory sellOrder = LibOrder.Order(
address(0),
LibAsset.Asset(
LibAsset.AssetType(
direct.nftAssetClass,
direct.nftData
),
direct.sellOrderNftAmount
),
address(0),
LibAsset.Asset(
paymentAssetType,
direct.sellOrderPaymentAmount
),
0,
0,
0,
direct.bidDataType,
direct.sellOrderData
);
validateFull(buyOrder, direct.bidSignature);
matchAndTransfer(sellOrder, buyOrder);
}
function matchOrders(
LibOrder.Order memory orderLeft,
bytes memory signatureLeft,
LibOrder.Order memory orderRight,
bytes memory signatureRight
) external payable {
validateOrders(orderLeft, signatureLeft, orderRight, signatureRight);
matchAndTransfer(orderLeft, orderRight);
}
/**
* @dev function, validate orders
* @param orderLeft left order
* @param signatureLeft order left signature
* @param orderRight right order
* @param signatureRight order right signature
*/
function validateOrders(LibOrder.Order memory orderLeft, bytes memory signatureLeft, LibOrder.Order memory orderRight, bytes memory signatureRight) internal view {
validateFull(orderLeft, signatureLeft);
validateFull(orderRight, signatureRight);
if (orderLeft.taker != address(0)) {
if (orderRight.maker != address(0))
require(orderRight.maker == orderLeft.taker, "leftOrder.taker verification failed");
}
if (orderRight.taker != address(0)) {
if (orderLeft.maker != address(0))
require(orderRight.taker == orderLeft.maker, "rightOrder.taker verification failed");
}
}
/**
@notice matches valid orders and transfers their assets
@param orderLeft the left order of the match
@param orderRight the right order of the match
*/
function matchAndTransfer(LibOrder.Order memory orderLeft, LibOrder.Order memory orderRight) internal {
(LibAsset.AssetType memory makeMatch, LibAsset.AssetType memory takeMatch) = matchAssets(orderLeft, orderRight);
(LibOrderData.GenericOrderData memory leftOrderData, LibOrderData.GenericOrderData memory rightOrderData, LibFill.FillResult memory newFill) =
parseOrdersSetFillEmitMatch(orderLeft, orderRight);
(uint totalMakeValue, uint totalTakeValue) = doTransfers(
LibDeal.DealSide({
asset: LibAsset.Asset({
assetType: makeMatch,
value: newFill.leftValue
}),
payouts: leftOrderData.payouts,
originFees: leftOrderData.originFees,
proxy: proxies[makeMatch.assetClass],
from: orderLeft.maker,
protocolFeeEnabled: leftOrderData.protocolFeeEnabled
}),
LibDeal.DealSide({
asset: LibAsset.Asset(
takeMatch,
newFill.rightValue
),
payouts: rightOrderData.payouts,
originFees: rightOrderData.originFees,
proxy: proxies[takeMatch.assetClass],
from: orderRight.maker,
protocolFeeEnabled: rightOrderData.protocolFeeEnabled
}),
LibFeeSide.getFeeSide(makeMatch.assetClass, takeMatch.assetClass)
);
if (makeMatch.assetClass == LibAsset.ETH_ASSET_CLASS) {
require(takeMatch.assetClass != LibAsset.ETH_ASSET_CLASS);
require(msg.value >= totalMakeValue, "not enough eth");
if (msg.value > totalMakeValue) {
address(msg.sender).transferEth(msg.value.sub(totalMakeValue));
}
} else if (takeMatch.assetClass == LibAsset.ETH_ASSET_CLASS) {
require(msg.value >= totalTakeValue, "not enough eth");
if (msg.value > totalTakeValue) {
address(msg.sender).transferEth(msg.value.sub(totalTakeValue));
}
}
}
function parseOrdersSetFillEmitMatch(
LibOrder.Order memory orderLeft,
LibOrder.Order memory orderRight
) internal returns (LibOrderData.GenericOrderData memory leftOrderData, LibOrderData.GenericOrderData memory rightOrderData, LibFill.FillResult memory newFill) {
bytes32 leftOrderKeyHash = LibOrder.hashKey(orderLeft);
bytes32 rightOrderKeyHash = LibOrder.hashKey(orderRight);
address msgSender = _msgSender();
if (orderLeft.maker == address(0)) {
orderLeft.maker = msgSender;
}
if (orderRight.maker == address(0)) {
orderRight.maker = msgSender;
}
leftOrderData = LibOrderData.parse(orderLeft);
rightOrderData = LibOrderData.parse(orderRight);
newFill = setFillEmitMatch(
orderLeft,
orderRight,
leftOrderKeyHash,
rightOrderKeyHash,
leftOrderData.isMakeFill,
rightOrderData.isMakeFill
);
}
/**
@notice calculates fills for the matched orders and set them in "fills" mapping
@param orderLeft left order of the match
@param orderRight right order of the match
@param leftMakeFill true if the left orders uses make-side fills, false otherwise
@param rightMakeFill true if the right orders uses make-side fills, false otherwise
@return returns change in orders' fills by the match
*/
function setFillEmitMatch(
LibOrder.Order memory orderLeft,
LibOrder.Order memory orderRight,
bytes32 leftOrderKeyHash,
bytes32 rightOrderKeyHash,
bool leftMakeFill,
bool rightMakeFill
) internal returns (LibFill.FillResult memory) {
uint leftOrderFill = getOrderFill(orderLeft.salt, leftOrderKeyHash);
uint rightOrderFill = getOrderFill(orderRight.salt, rightOrderKeyHash);
LibFill.FillResult memory newFill = LibFill.fillOrder(orderLeft, orderRight, leftOrderFill, rightOrderFill, leftMakeFill, rightMakeFill);
if (orderLeft.makeAsset.value != 0 || orderRight.takeAsset.value != 0) {
require(newFill.leftValue > 0, "nothing to fill");
}
if (orderLeft.takeAsset.value != 0 || orderRight.makeAsset.value != 0) {
require(newFill.rightValue > 0, "nothing to fill");
}
if (orderLeft.salt != 0) {
if (leftMakeFill) {
fills[leftOrderKeyHash] = leftOrderFill.add(newFill.leftValue);
} else {
fills[leftOrderKeyHash] = leftOrderFill.add(newFill.rightValue);
}
}
if (orderRight.salt != 0) {
if (rightMakeFill) {
fills[rightOrderKeyHash] = rightOrderFill.add(newFill.rightValue);
} else {
fills[rightOrderKeyHash] = rightOrderFill.add(newFill.leftValue);
}
}
emit Match(leftOrderKeyHash, rightOrderKeyHash, newFill.rightValue, newFill.leftValue);
return newFill;
}
function getOrderFill(uint salt, bytes32 hash) internal view returns (uint fill) {
if (salt == 0) {
fill = 0;
} else {
fill = fills[hash];
}
}
function matchAssets(LibOrder.Order memory orderLeft, LibOrder.Order memory orderRight) internal view returns (LibAsset.AssetType memory makeMatch, LibAsset.AssetType memory takeMatch) {
makeMatch = matchAssets(orderLeft.makeAsset.assetType, orderRight.takeAsset.assetType);
require(makeMatch.assetClass != 0, "assets don't match");
takeMatch = matchAssets(orderLeft.takeAsset.assetType, orderRight.makeAsset.assetType);
require(takeMatch.assetClass != 0, "assets don't match");
}
function validateFull(LibOrder.Order memory order, bytes memory signature) internal view {
LibOrder.validateOrderTime(order);
validate(order, signature);
}
function getPaymentAssetType(address token) internal pure returns(LibAsset.AssetType memory){
LibAsset.AssetType memory result;
if(token == address(0)) {
result.assetClass = LibAsset.ETH_ASSET_CLASS;
} else {
result.assetClass = LibAsset.ERC20_ASSET_CLASS;
result.data = abi.encode(token);
}
return result;
}
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "./libraries/LibOrder.sol";
import "@rarible/lib-signature/contracts/IERC1271.sol";
import "@rarible/lib-signature/contracts/LibSignature.sol";
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/drafts/EIP712Upgradeable.sol";
abstract contract OrderValidator is Initializable, ContextUpgradeable, EIP712Upgradeable {
using LibSignature for bytes32;
using AddressUpgradeable for address;
bytes4 constant internal MAGICVALUE = 0x1626ba7e;
function __OrderValidator_init_unchained() internal initializer {
__EIP712_init_unchained("Exchange", "2");
}
function validate(LibOrder.Order memory order, bytes memory signature) internal view {
if (order.salt == 0) {
if (order.maker != address(0)) {
require(_msgSender() == order.maker, "maker is not tx sender");
}
} else {
if (_msgSender() != order.maker) {
bytes32 hash = LibOrder.hash(order);
// if maker is contract checking ERC1271 signature
if (order.maker.isContract()) {
require(
IERC1271(order.maker).isValidSignature(_hashTypedDataV4(hash), signature) == MAGICVALUE,
"contract order signature verification error"
);
} else {
// if maker is not contract then checking ECDSA signature
if (_hashTypedDataV4(hash).recover(signature) != order.maker) {
revert("order signature verification error");
} else {
require (order.maker != address(0), "no maker");
}
}
}
}
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@rarible/lib-asset/contracts/LibAsset.sol";
library LibDirectTransfer { //LibDirectTransfers
/*All buy parameters need for create buyOrder and sellOrder*/
struct Purchase {
address sellOrderMaker; //
uint256 sellOrderNftAmount;
bytes4 nftAssetClass;
bytes nftData;
uint256 sellOrderPaymentAmount;
address paymentToken;
uint256 sellOrderSalt;
uint sellOrderStart;
uint sellOrderEnd;
bytes4 sellOrderDataType;
bytes sellOrderData;
bytes sellOrderSignature;
uint256 buyOrderPaymentAmount;
uint256 buyOrderNftAmount;
bytes buyOrderData;
}
/*All accept bid parameters need for create buyOrder and sellOrder*/
struct AcceptBid {
address bidMaker; //
uint256 bidNftAmount;
bytes4 nftAssetClass;
bytes nftData;
uint256 bidPaymentAmount;
address paymentToken;
uint256 bidSalt;
uint bidStart;
uint bidEnd;
bytes4 bidDataType;
bytes bidData;
bytes bidSignature;
uint256 sellOrderPaymentAmount;
uint256 sellOrderNftAmount;
bytes sellOrderData;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "./LibOrder.sol";
library LibFill {
struct FillResult {
uint leftValue;
uint rightValue;
}
struct IsMakeFill {
bool leftMake;
bool rightMake;
}
/**
* @dev Should return filled values
* @param leftOrder left order
* @param rightOrder right order
* @param leftOrderFill current fill of the left order (0 if order is unfilled)
* @param rightOrderFill current fill of the right order (0 if order is unfilled)
* @param leftIsMakeFill true if left orders fill is calculated from the make side, false if from the take side
* @param rightIsMakeFill true if right orders fill is calculated from the make side, false if from the take side
* @return tuple representing fill of both assets
*/
function fillOrder(LibOrder.Order memory leftOrder, LibOrder.Order memory rightOrder, uint leftOrderFill, uint rightOrderFill, bool leftIsMakeFill, bool rightIsMakeFill) internal pure returns (FillResult memory) {
(uint leftMakeValue, uint leftTakeValue) = LibOrder.calculateRemaining(leftOrder, leftOrderFill, leftIsMakeFill);
(uint rightMakeValue, uint rightTakeValue) = LibOrder.calculateRemaining(rightOrder, rightOrderFill, rightIsMakeFill);
//We have 3 cases here:
if (rightTakeValue > leftMakeValue || (rightTakeValue == leftMakeValue && leftMakeValue == 0)) { //1nd: left order should be fully filled
return fillLeft(leftMakeValue, leftTakeValue, rightOrder.makeAsset.value, rightOrder.takeAsset.value);
}//2st: right order should be fully filled or 3d: both should be fully filled if required values are the same
return fillRight(leftOrder.makeAsset.value, leftOrder.takeAsset.value, rightMakeValue, rightTakeValue);
}
function fillRight(uint leftMakeValue, uint leftTakeValue, uint rightMakeValue, uint rightTakeValue) internal pure returns (FillResult memory result) {
uint makerValue = LibMath.safeGetPartialAmountFloor(rightTakeValue, leftMakeValue, leftTakeValue);
require(makerValue <= rightMakeValue, "fillRight: unable to fill");
return FillResult(rightTakeValue, makerValue);
}
function fillLeft(uint leftMakeValue, uint leftTakeValue, uint rightMakeValue, uint rightTakeValue) internal pure returns (FillResult memory result) {
uint rightTake = LibMath.safeGetPartialAmountFloor(leftTakeValue, rightMakeValue, rightTakeValue);
require(rightTake <= leftMakeValue, "fillLeft: unable to fill");
return FillResult(leftMakeValue, leftTakeValue);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
library LibMath {
using SafeMathUpgradeable for uint;
/// @dev Calculates partial value given a numerator and denominator rounded down.
/// Reverts if rounding error is >= 0.1%
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to calculate partial of.
/// @return partialAmount value of target rounded down.
function safeGetPartialAmountFloor(
uint256 numerator,
uint256 denominator,
uint256 target
) internal pure returns (uint256 partialAmount) {
if (isRoundingErrorFloor(numerator, denominator, target)) {
revert("rounding error");
}
partialAmount = numerator.mul(target).div(denominator);
}
/// @dev Checks if rounding error >= 0.1% when rounding down.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to multiply with numerator/denominator.
/// @return isError Rounding error is present.
function isRoundingErrorFloor(
uint256 numerator,
uint256 denominator,
uint256 target
) internal pure returns (bool isError) {
if (denominator == 0) {
revert("division by zero");
}
// The absolute rounding error is the difference between the rounded
// value and the ideal value. The relative rounding error is the
// absolute rounding error divided by the absolute value of the
// ideal value. This is undefined when the ideal value is zero.
//
// The ideal value is `numerator * target / denominator`.
// Let's call `numerator * target % denominator` the remainder.
// The absolute error is `remainder / denominator`.
//
// When the ideal value is zero, we require the absolute error to
// be zero. Fortunately, this is always the case. The ideal value is
// zero iff `numerator == 0` and/or `target == 0`. In this case the
// remainder and absolute error are also zero.
if (target == 0 || numerator == 0) {
return false;
}
// Otherwise, we want the relative rounding error to be strictly
// less than 0.1%.
// The relative error is `remainder / (numerator * target)`.
// We want the relative error less than 1 / 1000:
// remainder / (numerator * target) < 1 / 1000
// or equivalently:
// 1000 * remainder < numerator * target
// so we have a rounding error iff:
// 1000 * remainder >= numerator * target
uint256 remainder = mulmod(
target,
numerator,
denominator
);
isError = remainder.mul(1000) >= numerator.mul(target);
}
function safeGetPartialAmountCeil(
uint256 numerator,
uint256 denominator,
uint256 target
) internal pure returns (uint256 partialAmount) {
if (isRoundingErrorCeil(numerator, denominator, target)) {
revert("rounding error");
}
partialAmount = numerator.mul(target).add(denominator.sub(1)).div(denominator);
}
/// @dev Checks if rounding error >= 0.1% when rounding up.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to multiply with numerator/denominator.
/// @return isError Rounding error is present.
function isRoundingErrorCeil(
uint256 numerator,
uint256 denominator,
uint256 target
) internal pure returns (bool isError) {
if (denominator == 0) {
revert("division by zero");
}
// See the comments in `isRoundingError`.
if (target == 0 || numerator == 0) {
// When either is zero, the ideal value and rounded value are zero
// and there is no rounding error. (Although the relative error
// is undefined.)
return false;
}
// Compute remainder as before
uint256 remainder = mulmod(
target,
numerator,
denominator
);
remainder = denominator.sub(remainder) % denominator;
isError = remainder.mul(1000) >= numerator.mul(target);
return isError;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@rarible/lib-asset/contracts/LibAsset.sol";
import "./LibMath.sol";
import "./LibOrderDataV3.sol";
import "./LibOrderDataV2.sol";
import "./LibOrderDataV1.sol";
library LibOrder {
using SafeMathUpgradeable for uint;
bytes32 constant ORDER_TYPEHASH = keccak256(
"Order(address maker,Asset makeAsset,address taker,Asset takeAsset,uint256 salt,uint256 start,uint256 end,bytes4 dataType,bytes data)Asset(AssetType assetType,uint256 value)AssetType(bytes4 assetClass,bytes data)"
);
bytes4 constant DEFAULT_ORDER_TYPE = 0xffffffff;
struct Order {
address maker;
LibAsset.Asset makeAsset;
address taker;
LibAsset.Asset takeAsset;
uint salt;
uint start;
uint end;
bytes4 dataType;
bytes data;
}
/**
* @dev Calculate remaining make and take values of the order (after partial filling real make and take decrease)
* @param order initial order to calculate remaining values for
* @param fill current fill of the left order (0 if order is unfilled)
* @param isMakeFill true if order fill is calculated from the make side, false if from the take side
* @return makeValue remaining make value of the order. if fill = 0 then it's order's make value
* @return takeValue remaining take value of the order. if fill = 0 then it's order's take value
*/
function calculateRemaining(Order memory order, uint fill, bool isMakeFill) internal pure returns (uint makeValue, uint takeValue) {
if (isMakeFill) {
makeValue = order.makeAsset.value.sub(fill);
takeValue = LibMath.safeGetPartialAmountFloor(order.takeAsset.value, order.makeAsset.value, makeValue);
} else {
takeValue = order.takeAsset.value.sub(fill);
makeValue = LibMath.safeGetPartialAmountFloor(order.makeAsset.value, order.takeAsset.value, takeValue);
}
}
function hashKey(Order memory order) internal pure returns (bytes32) {
if (order.dataType == LibOrderDataV1.V1 || order.dataType == DEFAULT_ORDER_TYPE) {
return keccak256(abi.encode(
order.maker,
LibAsset.hash(order.makeAsset.assetType),
LibAsset.hash(order.takeAsset.assetType),
order.salt
));
} else {
//order.data is in hash for V2, V3 and all new order
return keccak256(abi.encode(
order.maker,
LibAsset.hash(order.makeAsset.assetType),
LibAsset.hash(order.takeAsset.assetType),
order.salt,
order.data
));
}
}
function hash(Order memory order) internal pure returns (bytes32) {
return keccak256(abi.encode(
ORDER_TYPEHASH,
order.maker,
LibAsset.hash(order.makeAsset),
order.taker,
LibAsset.hash(order.takeAsset),
order.salt,
order.start,
order.end,
order.dataType,
keccak256(order.data)
));
}
function validateOrderTime(LibOrder.Order memory order) internal view {
require(order.start == 0 || order.start < block.timestamp, "Order start validation failed");
require(order.end == 0 || order.end > block.timestamp, "Order end validation failed");
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "./LibOrder.sol";
library LibOrderData {
struct GenericOrderData {
LibPart.Part[] payouts;
LibPart.Part[] originFees;
bool isMakeFill;
bool protocolFeeEnabled;
}
function parse(LibOrder.Order memory order) pure internal returns (GenericOrderData memory dataOrder) {
dataOrder.protocolFeeEnabled = false;
if (order.dataType == LibOrderDataV1.V1) {
LibOrderDataV1.DataV1 memory data = abi.decode(order.data, (LibOrderDataV1.DataV1));
dataOrder.payouts = data.payouts;
dataOrder.originFees = data.originFees;
} else if (order.dataType == LibOrderDataV2.V2) {
LibOrderDataV2.DataV2 memory data = abi.decode(order.data, (LibOrderDataV2.DataV2));
dataOrder.payouts = data.payouts;
dataOrder.originFees = data.originFees;
dataOrder.isMakeFill = data.isMakeFill;
} else if (order.dataType == LibOrderDataV3.V3) {
LibOrderDataV3.DataV3 memory data = abi.decode(order.data, (LibOrderDataV3.DataV3));
dataOrder.payouts = data.payouts;
dataOrder.originFees = data.originFees;
dataOrder.isMakeFill = data.isMakeFill;
dataOrder.protocolFeeEnabled = true;
} else if (order.dataType == 0xffffffff) {
} else {
revert("Unknown Order data type");
}
if (dataOrder.payouts.length == 0) {
dataOrder.payouts = payoutSet(order.maker);
}
}
function payoutSet(address orderAddress) pure internal returns (LibPart.Part[] memory) {
LibPart.Part[] memory payout = new LibPart.Part[](1);
payout[0].account = payable(orderAddress);
payout[0].value = 10000;
return payout;
}
function parseOriginFeeData(uint dataFirst, uint dataSecond) internal pure returns(LibPart.Part[] memory) {
LibPart.Part[] memory originFee;
if (dataFirst > 0 && dataSecond > 0){
originFee = new LibPart.Part[](2);
originFee[0] = uintToLibPart(dataFirst);
originFee[1] = uintToLibPart(dataSecond);
}
if (dataFirst > 0 && dataSecond == 0) {
originFee = new LibPart.Part[](1);
originFee[0] = uintToLibPart(dataFirst);
}
if (dataFirst == 0 && dataSecond > 0) {
originFee = new LibPart.Part[](1);
originFee[0] = uintToLibPart(dataSecond);
}
return originFee;
}
function parsePayouts(uint data) internal pure returns(LibPart.Part[] memory) {
LibPart.Part[] memory payouts;
if (data > 0) {
payouts = new LibPart.Part[](1);
payouts[0] = uintToLibPart(data);
}
return payouts;
}
/**
@notice converts uint to LibPart.Part
@param data address and value encoded in uint (first 12 bytes )
@return result LibPart.Part
*/
function uintToLibPart(uint data) internal pure returns(LibPart.Part memory result) {
if (data > 0){
result.account = payable(address(data));
result.value = uint96(data >> 160);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/lib-part/contracts/LibPart.sol";
library LibOrderDataV1 {
bytes4 constant public V1 = bytes4(keccak256("V1"));
struct DataV1 {
LibPart.Part[] payouts;
LibPart.Part[] originFees;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/lib-part/contracts/LibPart.sol";
library LibOrderDataV2 {
bytes4 constant public V2 = bytes4(keccak256("V2"));
struct DataV2 {
LibPart.Part[] payouts;
LibPart.Part[] originFees;
bool isMakeFill;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/lib-part/contracts/LibPart.sol";
library LibOrderDataV3 {
bytes4 constant public V3 = bytes4(keccak256("V3"));
struct DataV3 {
LibPart.Part[] payouts;
LibPart.Part[] originFees;
bool isMakeFill;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "../../contracts/ExchangeV2.sol";
contract RaribleTestHelper {
function encode(LibOrderDataV1.DataV1 memory data)
external
pure
returns (bytes memory)
{
return abi.encode(data);
}
function encodeV2(LibOrderDataV2.DataV2 memory data)
external
pure
returns (bytes memory)
{
return abi.encode(data);
}
function encodeV3(LibOrderDataV3.DataV3 memory data)
external
pure
returns (bytes memory)
{
return abi.encode(data);
}
function encodeOriginFeeIntoUint(address account, uint96 value)
external
pure
returns (uint256)
{
return (uint256(value) << 160) + uint256(account);
}
function hashKey(LibOrder.Order calldata order)
external
pure
returns (bytes32)
{
return LibOrder.hashKey(order);
}
function hashV2(
address maker,
LibAsset.Asset memory makeAsset,
LibAsset.Asset memory takeAsset,
uint256 salt,
bytes memory data
) public pure returns (bytes32) {
return
keccak256(
abi.encode(
maker,
LibAsset.hash(makeAsset.assetType),
LibAsset.hash(takeAsset.assetType),
salt,
data
)
);
}
function encodeLazy721(LibERC721LazyMint.Mint721Data memory data, address token)
external
pure
returns (bytes memory)
{
return abi.encode(token, data);
}
function encodeLazy1155(LibERC1155LazyMint.Mint1155Data memory data, address token)
external
pure
returns (bytes memory)
{
return abi.encode(token, data);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/transfer-manager/contracts/lib/LibTransfer.sol";
import "@rarible/lib-bp/contracts/BpLibrary.sol";
import "@rarible/lib-part/contracts/LibPart.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721Holder.sol";
import "@openzeppelin/contracts/token/ERC1155/ERC1155Holder.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "./interfaces/IWyvernExchange.sol";
import "./interfaces/IExchangeV2.sol";
import "./interfaces/ISeaPort.sol";
import "./interfaces/Ix2y2.sol";
import "./interfaces/ILooksRare.sol";
import "./interfaces/IBlur.sol";
import "./libraries/IsPausable.sol";
contract RaribleExchangeWrapper is Ownable, ERC721Holder, ERC1155Holder, IsPausable {
using LibTransfer for address;
using BpLibrary for uint;
using SafeMath for uint;
//marketplaces
address public immutable wyvernExchange;
address public immutable exchangeV2;
address public immutable seaPort_1_1;
address public immutable x2y2;
address public immutable looksRare;
address public immutable sudoswap;
address public immutable seaPort_1_4;
address public immutable looksRareV2;
address public immutable blur;
address public immutable seaPort_1_5;
address public immutable seaPort_1_6;
//currencties
address public immutable weth;
//constants
uint256 private constant UINT256_MAX = type(uint256).max;
event Execution(bool result);
enum Markets {
ExchangeV2,//0
WyvernExchange,//1
SeaPort_1_1,//2
X2Y2,//3
LooksRareOrders,//4
SudoSwap,//5
SeaPort_1_4,//6
LooksRareV2,//7
Blur,//8
SeaPort_1_5,//9
SeaPort_1_6//10
}
enum AdditionalDataTypes {
NoAdditionalData,
RoyaltiesAdditionalData
}
enum Currencies {
ETH,
WETH
}
/**
@notice struct for the purchase data
@param marketId - market key from Markets enum (what market to use)
@param amount - eth price (amount of eth that needs to be send to the marketplace)
@param fees - 2 fees (in base points) that are going to be taken on top of order amount encoded in 1 uint256
bytes (25,26) used for currency (0 - ETH, 1 - WETH erc-20)
bytes (27,28) used for dataType
bytes (29,30) used for the first value (goes to feeRecipientFirst)
bytes (31,32) are used for the second value (goes to feeRecipientSecond)
@param data - data for market call
*/
struct PurchaseDetails {
Markets marketId;
uint256 amount;
uint fees;
bytes data;
}
/**
@notice struct for the data with additional Ddta
@param data - data for market call
@param additionalRoyalties - array additional Royalties (in base points plus address Royalty recipient)
*/
struct AdditionalData {
bytes data;
uint[] additionalRoyalties;
}
constructor(
address[11] memory marketplaces,
//address _wyvernExchange, 0
//address _exchangeV2, 1
//address _seaPort_1_1, 2
//address _x2y2, 3
//address _looksRare, 4
//address _sudoswap, 5
//address _seaPort_1_4, 6
//address _looksRareV2, 7
//address _blur, 8
//address _seaPort_1_5, 9
//address _seaPort_1_6, 10
address _weth,
address[] memory transferProxies
) {
wyvernExchange = marketplaces[0];
exchangeV2 = marketplaces[1];
seaPort_1_1 = marketplaces[2];
x2y2 = marketplaces[3];
looksRare = marketplaces[4];
sudoswap = marketplaces[5];
seaPort_1_4 = marketplaces[6];
looksRareV2 = marketplaces[7];
blur = marketplaces[8];
seaPort_1_5 = marketplaces[9];
seaPort_1_6 = marketplaces[10];
weth = _weth;
for (uint i = 0; i < transferProxies.length; ++i) {
if (_weth != address(0)){
IERC20Upgradeable(_weth).approve(transferProxies[i], UINT256_MAX);
}
}
}
/**
@notice executes a single purchase
@param purchaseDetails - deatails about the purchase (more info in PurchaseDetails struct)
@param feeRecipientFirst - address of the first fee recipient
@param feeRecipientSecond - address of the second fee recipient
*/
function singlePurchase(PurchaseDetails memory purchaseDetails, address feeRecipientFirst, address feeRecipientSecond) external payable {
requireNotPaused();
//amount of WETH needed for purchases:
uint wethAmountNeeded = getAmountOfWethForPurchase(purchaseDetails);
//transfer WETH to this contract (if needed)
if (wethAmountNeeded > 0) {
IERC20Upgradeable(weth).transferFrom(_msgSender(), address(this), wethAmountNeeded);
}
Currencies currency = getCurrency(purchaseDetails.fees);
bool success;
uint firstFeeAmount;
uint secondFeeAmount;
if (currency == Currencies.ETH) {
(success, firstFeeAmount, secondFeeAmount) = purchase(purchaseDetails, false);
transferFeeETH(firstFeeAmount, feeRecipientFirst);
transferFeeETH(secondFeeAmount, feeRecipientSecond);
} else if (currency == Currencies.WETH) {
(success, firstFeeAmount, secondFeeAmount) = purchaseWETH(purchaseDetails, false);
transferFeeWETH(firstFeeAmount, feeRecipientFirst);
transferFeeWETH(secondFeeAmount, feeRecipientSecond);
} else {
revert("Unknown purchase currency");
}
emit Execution(success);
//transfer ETH change
transferChange();
//transfer WETH change
if (wethAmountNeeded > 0) {
transferChangeWETH();
}
}
/**
@notice executes an array of purchases
@param purchaseDetails - array of deatails about the purchases (more info in PurchaseDetails struct)
@param feeRecipientFirst - address of the first fee recipient
@param feeRecipientSecond - address of the second fee recipient
@param allowFail - true if fails while executing orders are allowed, false if fail of a single order means fail of the whole batch
*/
function bulkPurchase(PurchaseDetails[] memory purchaseDetails, address feeRecipientFirst, address feeRecipientSecond, bool allowFail) external payable {
requireNotPaused();
uint sumFirstFeesETH = 0;
uint sumSecondFeesETH = 0;
uint sumFirstFeesWETH = 0;
uint sumSecondFeesWETH = 0;
bool result = false;
//amount of WETH needed for purchases:
uint wethAmountNeeded = 0;
for (uint i = 0; i < purchaseDetails.length; ++i) {
wethAmountNeeded = wethAmountNeeded + getAmountOfWethForPurchase(purchaseDetails[i]);
}
//transfer WETH to this contract (if needed)
if (wethAmountNeeded > 0) {
IERC20Upgradeable(weth).transferFrom(_msgSender(), address(this), wethAmountNeeded);
}
for (uint i = 0; i < purchaseDetails.length; ++i) {
Currencies currency = getCurrency(purchaseDetails[i].fees);
bool success;
uint firstFeeAmount;
uint secondFeeAmount;
if (currency == Currencies.ETH) {
(success, firstFeeAmount, secondFeeAmount) = purchase(purchaseDetails[i], allowFail);
sumFirstFeesETH = sumFirstFeesETH.add(firstFeeAmount);
sumSecondFeesETH = sumSecondFeesETH.add(secondFeeAmount);
} else if (currency == Currencies.WETH) {
(success, firstFeeAmount, secondFeeAmount) = purchaseWETH(purchaseDetails[i], allowFail);
sumFirstFeesWETH = sumFirstFeesWETH.add(firstFeeAmount);
sumSecondFeesWETH = sumSecondFeesWETH.add(secondFeeAmount);
} else {
revert("Unknown purchase currency");
}
result = result || success;
emit Execution(success);
}
require(result, "no successful executions");
//pay fees in ETH
transferFeeETH(sumFirstFeesETH, feeRecipientFirst);
transferFeeETH(sumSecondFeesETH, feeRecipientSecond);
//pay fees in WETH
transferFeeWETH(sumFirstFeesWETH, feeRecipientFirst);
transferFeeWETH(sumSecondFeesWETH, feeRecipientSecond);
//transfer ETH change
transferChange();
//transfer WETH change
if (wethAmountNeeded > 0) {
transferChangeWETH();
}
}
/**
@notice executes one purchase in ETH
@param purchaseDetails - details about the purchase
@param allowFail - true if errors are handled, false if revert on errors
@return result false if execution failed, true if succeded
@return firstFeeAmount amount of the first fee of the purchase, 0 if failed
@return secondFeeAmount amount of the second fee of the purchase, 0 if failed
*/
function purchase(PurchaseDetails memory purchaseDetails, bool allowFail) internal returns(bool, uint, uint) {
(bytes memory marketData, uint[] memory additionalRoyalties) = getDataAndAdditionalData (purchaseDetails.data, purchaseDetails.fees, purchaseDetails.marketId);
uint paymentAmount = purchaseDetails.amount;
if (purchaseDetails.marketId == Markets.SeaPort_1_1){
(bool success,) = address(seaPort_1_1).call{value : paymentAmount}(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase SeaPort_1_1 failed");
}
} else if (purchaseDetails.marketId == Markets.WyvernExchange) {
(bool success,) = address(wyvernExchange).call{value : paymentAmount}(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase wyvernExchange failed");
}
} else if (purchaseDetails.marketId == Markets.ExchangeV2) {
(bool success,) = address(exchangeV2).call{value : paymentAmount}(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase rarible failed");
}
} else if (purchaseDetails.marketId == Markets.X2Y2) {
Ix2y2.RunInput memory input = abi.decode(marketData, (Ix2y2.RunInput));
if (allowFail) {
try Ix2y2(x2y2).run{value : paymentAmount}(input) {
} catch {
return (false, 0, 0);
}
} else {
Ix2y2(x2y2).run{value : paymentAmount}(input);
}
//for every element in input.details[] getting
// order = input.details[i].orderIdx
// and from that order getting item = input.details[i].itemId
for (uint i = 0; i < input.details.length; ++i) {
uint orderId = input.details[i].orderIdx;
uint itemId = input.details[i].itemIdx;
bytes memory data = input.orders[orderId].items[itemId].data;
{
if (input.orders[orderId].dataMask.length > 0 && input.details[i].dataReplacement.length > 0) {
_arrayReplace(data, input.details[i].dataReplacement, input.orders[orderId].dataMask);
}
}
// 1 = erc-721
if (input.orders[orderId].delegateType == 1) {
Ix2y2.Pair721[] memory pairs = abi.decode(data, (Ix2y2.Pair721[]));
for (uint256 j = 0; j < pairs.length; j++) {
Ix2y2.Pair721 memory p = pairs[j];
IERC721Upgradeable(address(p.token)).safeTransferFrom(address(this), _msgSender(), p.tokenId);
}
} else if (input.orders[orderId].delegateType == 2) {
// 2 = erc-1155
Ix2y2.Pair1155[] memory pairs = abi.decode(data, (Ix2y2.Pair1155[]));
for (uint256 j = 0; j < pairs.length; j++) {
Ix2y2.Pair1155 memory p = pairs[j];
IERC1155Upgradeable(address(p.token)).safeTransferFrom(address(this), _msgSender(), p.tokenId, p.amount, "");
}
} else {
revert("unknown delegateType x2y2");
}
}
} else if (purchaseDetails.marketId == Markets.LooksRareOrders) {
(LibLooksRare.TakerOrder memory takerOrder, LibLooksRare.MakerOrder memory makerOrder, bytes4 typeNft) = abi.decode(marketData, (LibLooksRare.TakerOrder, LibLooksRare.MakerOrder, bytes4));
if (allowFail) {
try ILooksRare(looksRare).matchAskWithTakerBidUsingETHAndWETH{value : paymentAmount}(takerOrder, makerOrder) {
} catch {
return (false, 0, 0);
}
} else {
ILooksRare(looksRare).matchAskWithTakerBidUsingETHAndWETH{value : paymentAmount}(takerOrder, makerOrder);
}
if (typeNft == LibAsset.ERC721_ASSET_CLASS) {
IERC721Upgradeable(makerOrder.collection).safeTransferFrom(address(this), _msgSender(), makerOrder.tokenId);
} else if (typeNft == LibAsset.ERC1155_ASSET_CLASS) {
IERC1155Upgradeable(makerOrder.collection).safeTransferFrom(address(this), _msgSender(), makerOrder.tokenId, makerOrder.amount, "");
} else {
revert("Unknown token type");
}
} else if (purchaseDetails.marketId == Markets.SudoSwap) {
(bool success,) = address(sudoswap).call{value : paymentAmount}(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase sudoswap failed");
}
} else if (purchaseDetails.marketId == Markets.SeaPort_1_4){
(bool success,) = address(seaPort_1_4).call{value : paymentAmount}(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase SeaPort_1_4 failed");
}
} else if (purchaseDetails.marketId == Markets.LooksRareV2){
(bool success,) = address(looksRareV2).call{value : paymentAmount}(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase LooksRareV2 failed");
}
} else if (purchaseDetails.marketId == Markets.Blur){
(IBlur.Input memory sell, IBlur.Input memory buy, bytes4 typeNft) = abi.decode(marketData, (IBlur.Input, IBlur.Input, bytes4));
if (allowFail) {
try IBlur(blur).execute{value : paymentAmount}(sell, buy) {
} catch {
return (false, 0, 0);
}
} else {
IBlur(blur).execute{value : paymentAmount}(sell, buy);
}
if (typeNft == LibAsset.ERC721_ASSET_CLASS) {
IERC721Upgradeable(sell.order.collection).safeTransferFrom(address(this), _msgSender(), sell.order.tokenId);
} else if (typeNft == LibAsset.ERC1155_ASSET_CLASS) {
IERC1155Upgradeable(sell.order.collection).safeTransferFrom(address(this), _msgSender(), sell.order.tokenId, sell.order.amount, "");
} else {
revert("Unknown token type");
}
} else if (purchaseDetails.marketId == Markets.SeaPort_1_5){
(bool success,) = address(seaPort_1_5).call{value : paymentAmount}(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase SeaPort_1_5 failed");
}
} else if (purchaseDetails.marketId == Markets.SeaPort_1_6){
(bool success,) = address(seaPort_1_6).call{value : paymentAmount}(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase SeaPort_1_6 failed");
}
} else {
revert("Unknown marketId ETH");
}
//transferring royalties
transferAdditionalRoyaltiesETH(additionalRoyalties, purchaseDetails.amount);
(uint firstFeeAmount, uint secondFeeAmount) = getFees(purchaseDetails.fees, purchaseDetails.amount);
return (true, firstFeeAmount, secondFeeAmount);
}
/**
@notice executes one purchase in WETH
@param purchaseDetails - details about the purchase
@param allowFail - true if errors are handled, false if revert on errors
@return result false if execution failed, true if succeded
@return firstFeeAmount amount of the first fee of the purchase, 0 if failed
@return secondFeeAmount amount of the second fee of the purchase, 0 if failed
*/
function purchaseWETH(PurchaseDetails memory purchaseDetails, bool allowFail) internal returns(bool, uint, uint) {
(bytes memory marketData, uint[] memory additionalRoyalties) = getDataAndAdditionalData (purchaseDetails.data, purchaseDetails.fees, purchaseDetails.marketId);
//buying
if (purchaseDetails.marketId == Markets.SeaPort_1_1){
(bool success,) = address(seaPort_1_1).call(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase SeaPort_1_1 failed WETH");
}
} else if (purchaseDetails.marketId == Markets.ExchangeV2) {
(bool success,) = address(exchangeV2).call(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase rarible failed WETH");
}
} else if (purchaseDetails.marketId == Markets.SeaPort_1_4){
(bool success,) = address(seaPort_1_4).call(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase SeaPort_1_4 failed WETH");
}
} else if (purchaseDetails.marketId == Markets.SeaPort_1_5){
(bool success,) = address(seaPort_1_5).call(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase SeaPort_1_5 failed WETH");
}
} else if (purchaseDetails.marketId == Markets.SeaPort_1_6){
(bool success,) = address(seaPort_1_6).call(marketData);
if (allowFail) {
if (!success) {
return (false, 0, 0);
}
} else {
require(success, "Purchase SeaPort_1_6 failed WETH");
}
} else {
revert("Unknown marketId WETH");
}
//transfer royalties
transferAdditionalRoyaltiesWETH(additionalRoyalties, purchaseDetails.amount);
//get fees
(uint firstFeeAmount, uint secondFeeAmount) = getFees(purchaseDetails.fees, purchaseDetails.amount);
return (true, firstFeeAmount, secondFeeAmount);
}
/**
@notice transfers ETH fee to feeRecipient
@param feeAmount - amount to be transfered
@param feeRecipient - address of the recipient
*/
function transferFeeETH(uint feeAmount, address feeRecipient) internal {
if (feeAmount > 0 && feeRecipient != address(0)) {
LibTransfer.transferEth(feeRecipient, feeAmount);
}
}
/**
@notice transfers WETH fee to feeRecipient
@param feeAmount - amount to be transfered
@param feeRecipient - address of the recipient
*/
function transferFeeWETH(uint feeAmount, address feeRecipient) internal {
if (feeAmount > 0 && feeRecipient != address(0)) {
IERC20Upgradeable(weth).transfer(feeRecipient, feeAmount);
}
}
/**
@notice transfers change back to sender
*/
function transferChange() internal {
uint ethAmount = address(this).balance;
if (ethAmount > 0) {
address(msg.sender).transferEth(ethAmount);
}
}
/**
@notice transfers weth change back to sender
*/
function transferChangeWETH() internal {
uint wethAmount = IERC20Upgradeable(weth).balanceOf(address(this));
if (wethAmount > 0) {
IERC20Upgradeable(weth).transfer(_msgSender(), wethAmount);
}
}
/**
@notice parses fees in base points from one uint and calculates real amount of fees
@param fees two fees encoded in one uint, 29 and 30 bytes are used for the first fee, 31 and 32 bytes for second fee
@param amount price of the order
@return firstFeeAmount real amount for the first fee
@return secondFeeAmount real amount for the second fee
*/
function getFees(uint fees, uint amount) internal pure returns(uint, uint) {
uint firstFee = uint(uint16(fees >> 16));
uint secondFee = uint(uint16(fees));
return (amount.bp(firstFee), amount.bp(secondFee));
}
/**
@notice parses "fees" field to find the currency for the purchase
@param fees field with encoded data
@return 0 if ETH, 1 if WETH ERC-20
*/
function getCurrency(uint fees) internal pure returns(Currencies) {
return Currencies(uint16(fees >> 48));
}
/**
@notice parses _data to data for market call and additionalData
@param feesAndDataType 27 and 28 bytes for dataType
@return marketData data for market call
@return additionalRoyalties array uint256, (base point + address)
*/
function getDataAndAdditionalData (bytes memory _data, uint feesAndDataType, Markets marketId) internal pure returns (bytes memory, uint[] memory) {
AdditionalDataTypes dataType = AdditionalDataTypes(uint16(feesAndDataType >> 32));
uint[] memory additionalRoyalties;
//return no royalties if wrong data type
if (dataType == AdditionalDataTypes.NoAdditionalData) {
return (_data, additionalRoyalties);
}
if (dataType == AdditionalDataTypes.RoyaltiesAdditionalData) {
AdditionalData memory additionalData = abi.decode(_data, (AdditionalData));
//return no royalties if market doesn't support royalties
if (supportsRoyalties(marketId)) {
return (additionalData.data, additionalData.additionalRoyalties);
} else {
return (additionalData.data, additionalRoyalties);
}
}
revert("unknown additionalDataType");
}
/**
@notice transfer additional royalties in ETH
@param _additionalRoyalties array uint256 (base point + royalty recipient address)
*/
function transferAdditionalRoyaltiesETH (uint[] memory _additionalRoyalties, uint amount) internal {
for (uint i = 0; i < _additionalRoyalties.length; ++i) {
if (_additionalRoyalties[i] > 0) {
address payable account = payable(address(_additionalRoyalties[i]));
uint basePoint = uint(_additionalRoyalties[i] >> 160);
uint value = amount.bp(basePoint);
transferFeeETH(value, account);
}
}
}
/**
@notice transfer additional royalties in WETH
@param _additionalRoyalties array uint256 (base point + royalty recipient address)
*/
function transferAdditionalRoyaltiesWETH (uint[] memory _additionalRoyalties, uint amount) internal {
for (uint i = 0; i < _additionalRoyalties.length; ++i) {
if (_additionalRoyalties[i] > 0) {
address payable account = payable(address(_additionalRoyalties[i]));
uint basePoint = uint(_additionalRoyalties[i] >> 160);
uint value = amount.bp(basePoint);
transferFeeWETH(value, account);
}
}
}
// modifies `src`
function _arrayReplace(
bytes memory src,
bytes memory replacement,
bytes memory mask
) internal view virtual {
require(src.length == replacement.length);
require(src.length == mask.length);
for (uint256 i = 0; i < src.length; ++i) {
if (mask[i] != 0) {
src[i] = replacement[i];
}
}
}
/**
@notice returns true if this contract supports additional royalties for the marketplace;
now royalties are supported for:
1. SudoSwap
2. LooksRare old
3. LooksRare V2
*/
function supportsRoyalties(Markets marketId) internal pure returns (bool){
if (
marketId == Markets.SudoSwap ||
marketId == Markets.LooksRareOrders ||
marketId == Markets.LooksRareV2
) {
return true;
}
return false;
}
function getAmountOfWethForPurchase(PurchaseDetails memory detail) internal pure returns (uint) {
uint result = 0;
Currencies currency = getCurrency(detail.fees);
//for every purchase with WETH we sum amount, fees and royalties needed
if (currency == Currencies.WETH) {
//add amount
result = result + detail.amount;
//add fees
(uint firstFeeAmount, uint secondFeeAmount) = getFees(detail.fees, detail.amount);
result = result + firstFeeAmount + secondFeeAmount;
//add royalties
(, uint[] memory royalties) = getDataAndAdditionalData (detail.data, detail.fees, detail.marketId);
for (uint j = 0; j < royalties.length; ++j) {
uint royaltyBasePoint = uint(royalties[j] >> 160);
uint royaltyValue = detail.amount.bp(royaltyBasePoint);
result = result + royaltyValue;
}
}
return result;
}
/**
@notice approves weth for a list of the addresses
@param transferProxies - array of addresses to approve WETH for
*/
function approveWETH(address[] calldata transferProxies) external onlyOwner {
for (uint i = 0; i < transferProxies.length; ++i) {
IERC20Upgradeable(weth).approve(transferProxies[i], UINT256_MAX);
}
}
receive() external payable {}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
interface IBlur {
enum Side { Buy, Sell }
enum SignatureVersion { Single, Bulk }
enum AssetType { ERC721, ERC1155 }
struct Fee {
uint16 rate;
address payable recipient;
}
struct Order {
address trader;
Side side;
address matchingPolicy;
address collection;
uint256 tokenId;
uint256 amount;
address paymentToken;
uint256 price;
uint256 listingTime;
/* Order expiration timestamp - 0 for oracle cancellations. */
uint256 expirationTime;
Fee[] fees;
uint256 salt;
bytes extraParams;
}
struct Input {
Order order;
uint8 v;
bytes32 r;
bytes32 s;
bytes extraSignature;
SignatureVersion signatureVersion;
uint256 blockNumber;
}
function execute(Input calldata sell, Input calldata buy)
external
payable;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
import "@rarible/exchange-v2/contracts/ExchangeV2.sol";
import {RoyaltiesRegistry} from "@rarible/royalties-registry/contracts/RoyaltiesRegistry.sol";
import {TransferProxy} from "@rarible/transfer-proxy/contracts/proxy/TransferProxy.sol";
import {ERC20TransferProxy} from "@rarible/transfer-proxy/contracts/proxy/ERC20TransferProxy.sol";
interface IExchangeV2 {
function matchOrders(
LibOrder.Order memory orderLeft,
bytes memory signatureLeft,
LibOrder.Order memory orderRight,
bytes memory signatureRight
) external payable;
function directPurchase(
LibDirectTransfer.Purchase calldata direct
) external payable;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
interface ILSSVMRouter {
struct PairSwapSpecific {
address pair;
uint256[] nftIds;
}
/**
@notice Swaps ETH into specific NFTs using multiple pairs.
@param swapList The list of pairs to trade with and the IDs of the NFTs to buy from each.
@param ethRecipient The address that will receive the unspent ETH input
@param nftRecipient The address that will receive the NFT output
@param deadline The Unix timestamp (in seconds) at/after which the swap will revert
@return remainingValue The unspent ETH amount
*/
function swapETHForSpecificNFTs(
PairSwapSpecific[] calldata swapList,
address payable ethRecipient,
address nftRecipient,
uint256 deadline
)
external
payable
returns (uint256 remainingValue);
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "../libraries/LibLooksRare.sol";
interface ILooksRare {
function matchAskWithTakerBidUsingETHAndWETH(LibLooksRare.TakerOrder calldata takerBid, LibLooksRare.MakerOrder calldata makerAsk) external payable;
/**
* @notice This function allows a user to execute a taker bid (against a maker ask).
* @param takerBid Taker bid struct
* @param makerAsk Maker ask struct
* @param makerSignature Maker signature
* @param merkleTree Merkle tree struct (if the signature contains multiple maker orders)
* @param affiliate Affiliate address
*/
function executeTakerBid(LibLooksRare.Taker calldata takerBid, LibLooksRare.Maker calldata makerAsk, bytes calldata makerSignature, LibLooksRare.MerkleTree calldata merkleTree, address affiliate) external payable;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
import "../libraries/LibSeaPort.sol";
interface ISeaPort {
function fulfillAdvancedOrder(
LibSeaPort.AdvancedOrder calldata advancedOrder,
LibSeaPort.CriteriaResolver[] calldata criteriaResolvers,
bytes32 fulfillerConduitKey,
address recipient
) external payable returns (bool fulfilled);
function fulfillAvailableAdvancedOrders(
LibSeaPort.AdvancedOrder[] memory advancedOrders,
LibSeaPort.CriteriaResolver[] calldata criteriaResolvers,
LibSeaPort.FulfillmentComponent[][] calldata offerFulfillments,
LibSeaPort.FulfillmentComponent[][] calldata considerationFulfillments,
bytes32 fulfillerConduitKey,
address recipient,
uint256 maximumFulfilled
) external payable returns (bool[] memory availableOrders, LibSeaPort.Execution[] memory executions);
function fulfillBasicOrder(LibSeaPort.BasicOrderParameters calldata parameters)
external
payable
returns (bool fulfilled);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
interface IWyvernExchange {
function atomicMatch_(
address[14] memory addrs,
uint[18] memory uints,
uint8[8] memory feeMethodsSidesKindsHowToCalls,
bytes memory calldataBuy,
bytes memory calldataSell,
bytes memory replacementPatternBuy,
bytes memory replacementPatternSell,
bytes memory staticExtradataBuy,
bytes memory staticExtradataSell,
uint8[2] memory vs,
bytes32[5] memory rssMetadata)
external
payable;
enum Side {
Buy,
Sell
}
enum SaleKind {
FixedPrice,
DutchAuction
}
function calculateFinalPrice(
Side side,
SaleKind saleKind,
uint256 basePrice,
uint256 extra,
uint256 listingTime,
uint256 expirationTime
) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
interface Ix2y2 {
struct OrderItem {
uint256 price;
bytes data;
}
struct Pair721 {
address token;
uint256 tokenId;
}
struct Pair1155 {
address token;
uint256 tokenId;
uint256 amount;
}
struct Order {
uint256 salt;
address user;
uint256 network;
uint256 intent;
uint256 delegateType;
uint256 deadline;
address currency;
bytes dataMask;
OrderItem[] items;
// signature
bytes32 r;
bytes32 s;
uint8 v;
uint8 signVersion;
}
struct Fee {
uint256 percentage;
address to;
}
struct SettleDetail {
Op op;
uint256 orderIdx;
uint256 itemIdx;
uint256 price;
bytes32 itemHash;
address executionDelegate;
bytes dataReplacement;
uint256 bidIncentivePct;
uint256 aucMinIncrementPct;
uint256 aucIncDurationSecs;
Fee[] fees;
}
struct SettleShared {
uint256 salt;
uint256 deadline;
uint256 amountToEth;
uint256 amountToWeth;
address user;
bool canFail;
}
struct RunInput {
Order[] orders;
SettleDetail[] details;
SettleShared shared;
// signature
bytes32 r;
bytes32 s;
uint8 v;
}
enum Op {
INVALID,
// off-chain
COMPLETE_SELL_OFFER,
COMPLETE_BUY_OFFER,
CANCEL_OFFER,
// auction
BID,
COMPLETE_AUCTION,
REFUND_AUCTION,
REFUND_AUCTION_STUCK_ITEM
}
function run(RunInput memory input) external payable;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@openzeppelin/contracts/access/Ownable.sol";
abstract contract IsPausable is Ownable {
bool public paused;
event Paused(bool paused);
function pause(bool _paused) external onlyOwner {
paused = _paused;
emit Paused(_paused);
}
function requireNotPaused() internal view {
require (!paused, "the contract is paused");
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
library LibLooksRare {
struct MakerOrder {
bool isOrderAsk; // true --> ask / false --> bid
address signer; // signer of the maker order
address collection; // collection address
uint256 price; // price (used as )
uint256 tokenId; // id of the token
uint256 amount; // amount of tokens to sell/purchase (must be 1 for ERC721, 1+ for ERC1155)
address strategy; // strategy for trade execution (e.g., DutchAuction, StandardSaleForFixedPrice)
address currency; // currency (e.g., WETH)
uint256 nonce; // order nonce (must be unique unless new maker order is meant to override existing one e.g., lower ask price)
uint256 startTime; // startTime in timestamp
uint256 endTime; // endTime in timestamp
uint256 minPercentageToAsk; // slippage protection (9000 --> 90% of the final price must return to ask)
bytes params; // additional parameters
uint8 v; // v: parameter (27 or 28)
bytes32 r; // r: parameter
bytes32 s; // s: parameter
}
struct TakerOrder {
bool isOrderAsk; // true --> ask / false --> bid
address taker; // msg.sender
uint256 price; // final price for the purchase
uint256 tokenId;
uint256 minPercentageToAsk; // // slippage protection (9000 --> 90% of the final price must return to ask)
bytes params; // other params (e.g., tokenId)
}
/**
* @notice CollectionType is used in OrderStructs.Maker's collectionType to determine the collection type being traded.
*/
enum CollectionType {
ERC721,
ERC1155
}
/**
* @notice QuoteType is used in OrderStructs.Maker's quoteType to determine whether the maker order is a bid or an ask.
*/
enum QuoteType {
Bid,
Ask
}
/**
* 1. Maker struct
*/
/**
* @notice Maker is the struct for a maker order.
* @param quoteType Quote type (i.e. 0 = BID, 1 = ASK)
* @param globalNonce Global user order nonce for maker orders
* @param subsetNonce Subset nonce (shared across bid/ask maker orders)
* @param orderNonce Order nonce (it can be shared across bid/ask maker orders)
* @param strategyId Strategy id
* @param collectionType Collection type (i.e. 0 = ERC721, 1 = ERC1155)
* @param collection Collection address
* @param currency Currency address (@dev address(0) = ETH)
* @param signer Signer address
* @param startTime Start timestamp
* @param endTime End timestamp
* @param price Minimum price for maker ask, maximum price for maker bid
* @param itemIds Array of itemIds
* @param amounts Array of amounts
* @param additionalParameters Extra data specific for the order
*/
struct Maker {
QuoteType quoteType;
uint256 globalNonce;
uint256 subsetNonce;
uint256 orderNonce;
uint256 strategyId;
CollectionType collectionType;
address collection;
address currency;
address signer;
uint256 startTime;
uint256 endTime;
uint256 price;
uint256[] itemIds;
uint256[] amounts;
bytes additionalParameters;
}
/**
* 2. Taker struct
*/
/**
* @notice Taker is the struct for a taker ask/bid order. It contains the parameters required for a direct purchase.
* @dev Taker struct is matched against MakerAsk/MakerBid structs at the protocol level.
* @param recipient Recipient address (to receive NFTs or non-fungible tokens)
* @param additionalParameters Extra data specific for the order
*/
struct Taker {
address recipient;
bytes additionalParameters;
}
/**
* 3. Merkle tree struct
*/
enum MerkleTreeNodePosition {
Left,
Right
}
/**
* @notice MerkleTreeNode is a MerkleTree's node.
* @param value It can be an order hash or a proof
* @param position The node's position in its branch.
* It can be left or right or none
* (before the tree is sorted).
*/
struct MerkleTreeNode {
bytes32 value;
MerkleTreeNodePosition position;
}
/**
* @notice MerkleTree is the struct for a merkle tree of order hashes.
* @dev A Merkle tree can be computed with order hashes.
* It can contain order hashes from both maker bid and maker ask structs.
* @param root Merkle root
* @param proof Array containing the merkle proof
*/
struct MerkleTree {
bytes32 root;
MerkleTreeNode[] proof;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
library LibSeaPort {
/**
* @dev For basic orders involving ETH / native / ERC20 <=> ERC721 / ERC1155
* matching, a group of six functions may be called that only requires a
* subset of the usual order arguments. Note the use of a "basicOrderType"
* enum; this represents both the usual order type as well as the "route"
* of the basic order (a simple derivation function for the basic order
* type is `basicOrderType = orderType + (4 * basicOrderRoute)`.)
*/
struct BasicOrderParameters {
address considerationToken; // 0x24
uint256 considerationIdentifier; // 0x44
uint256 considerationAmount; // 0x64
address payable offerer; // 0x84
address zone; // 0xa4
address offerToken; // 0xc4
uint256 offerIdentifier; // 0xe4
uint256 offerAmount; // 0x104
BasicOrderType basicOrderType; // 0x124
uint256 startTime; // 0x144
uint256 endTime; // 0x164
bytes32 zoneHash; // 0x184
uint256 salt; // 0x1a4
bytes32 offererConduitKey; // 0x1c4
bytes32 fulfillerConduitKey; // 0x1e4
uint256 totalOriginalAdditionalRecipients; // 0x204
AdditionalRecipient[] additionalRecipients; // 0x224
bytes signature; // 0x244
}
/**
* @dev Basic orders can supply any number of additional recipients, with the
* implied assumption that they are supplied from the offered ETH (or other
* native token) or ERC20 token for the order.
*/
struct AdditionalRecipient {
uint256 amount;
address payable recipient;
}
// prettier-ignore
enum BasicOrderType {
// 0: no partial fills, anyone can execute
ETH_TO_ERC721_FULL_OPEN,
// 1: partial fills supported, anyone can execute
ETH_TO_ERC721_PARTIAL_OPEN,
// 2: no partial fills, only offerer or zone can execute
ETH_TO_ERC721_FULL_RESTRICTED,
// 3: partial fills supported, only offerer or zone can execute
ETH_TO_ERC721_PARTIAL_RESTRICTED,
// 4: no partial fills, anyone can execute
ETH_TO_ERC1155_FULL_OPEN,
// 5: partial fills supported, anyone can execute
ETH_TO_ERC1155_PARTIAL_OPEN,
// 6: no partial fills, only offerer or zone can execute
ETH_TO_ERC1155_FULL_RESTRICTED,
// 7: partial fills supported, only offerer or zone can execute
ETH_TO_ERC1155_PARTIAL_RESTRICTED,
// 8: no partial fills, anyone can execute
ERC20_TO_ERC721_FULL_OPEN,
// 9: partial fills supported, anyone can execute
ERC20_TO_ERC721_PARTIAL_OPEN,
// 10: no partial fills, only offerer or zone can execute
ERC20_TO_ERC721_FULL_RESTRICTED,
// 11: partial fills supported, only offerer or zone can execute
ERC20_TO_ERC721_PARTIAL_RESTRICTED,
// 12: no partial fills, anyone can execute
ERC20_TO_ERC1155_FULL_OPEN,
// 13: partial fills supported, anyone can execute
ERC20_TO_ERC1155_PARTIAL_OPEN,
// 14: no partial fills, only offerer or zone can execute
ERC20_TO_ERC1155_FULL_RESTRICTED,
// 15: partial fills supported, only offerer or zone can execute
ERC20_TO_ERC1155_PARTIAL_RESTRICTED,
// 16: no partial fills, anyone can execute
ERC721_TO_ERC20_FULL_OPEN,
// 17: partial fills supported, anyone can execute
ERC721_TO_ERC20_PARTIAL_OPEN,
// 18: no partial fills, only offerer or zone can execute
ERC721_TO_ERC20_FULL_RESTRICTED,
// 19: partial fills supported, only offerer or zone can execute
ERC721_TO_ERC20_PARTIAL_RESTRICTED,
// 20: no partial fills, anyone can execute
ERC1155_TO_ERC20_FULL_OPEN,
// 21: partial fills supported, anyone can execute
ERC1155_TO_ERC20_PARTIAL_OPEN,
// 22: no partial fills, only offerer or zone can execute
ERC1155_TO_ERC20_FULL_RESTRICTED,
// 23: partial fills supported, only offerer or zone can execute
ERC1155_TO_ERC20_PARTIAL_RESTRICTED
}
/**
* @dev The full set of order components, with the exception of the counter,
* must be supplied when fulfilling more sophisticated orders or groups of
* orders. The total number of original consideration items must also be
* supplied, as the caller may specify additional consideration items.
*/
struct OrderParameters {
address offerer; // 0x00
address zone; // 0x20
OfferItem[] offer; // 0x40
ConsiderationItem[] consideration; // 0x60
OrderType orderType; // 0x80
uint256 startTime; // 0xa0
uint256 endTime; // 0xc0
bytes32 zoneHash; // 0xe0
uint256 salt; // 0x100
bytes32 conduitKey; // 0x120
uint256 totalOriginalConsiderationItems; // 0x140
// offer.length // 0x160
}
/**
* @dev Orders require a signature in addition to the other order parameters.
*/
struct Order {
OrderParameters parameters;
bytes signature;
}
struct AdvancedOrder {
OrderParameters parameters;
uint120 numerator;
uint120 denominator;
bytes signature;
bytes extraData;
}
struct OfferItem {
ItemType itemType;
address token;
uint256 identifierOrCriteria;
uint256 startAmount;
uint256 endAmount;
}
/**
* @dev A consideration item has the same five components as an offer item and
* an additional sixth component designating the required recipient of the
* item.
*/
struct ConsiderationItem {
ItemType itemType;
address token;
uint256 identifierOrCriteria;
uint256 startAmount;
uint256 endAmount;
address payable recipient;
}
// prettier-ignore
enum OrderType {
// 0: no partial fills, anyone can execute
FULL_OPEN,
// 1: partial fills supported, anyone can execute
PARTIAL_OPEN,
// 2: no partial fills, only offerer or zone can execute
FULL_RESTRICTED,
// 3: partial fills supported, only offerer or zone can execute
PARTIAL_RESTRICTED
}
// prettier-ignore
enum ItemType {
// 0: ETH on mainnet, MATIC on polygon, etc.
NATIVE,
// 1: ERC20 items (ERC777 and ERC20 analogues could also technically work)
ERC20,
// 2: ERC721 items
ERC721,
// 3: ERC1155 items
ERC1155,
// 4: ERC721 items where a number of tokenIds are supported
ERC721_WITH_CRITERIA,
// 5: ERC1155 items where a number of ids are supported
ERC1155_WITH_CRITERIA
}
/**
* @dev A fulfillment is applied to a group of orders. It decrements a series of
* offer and consideration items, then generates a single execution
* element. A given fulfillment can be applied to as many offer and
* consideration items as desired, but must contain at least one offer and
* at least one consideration that match. The fulfillment must also remain
* consistent on all key parameters across all offer items (same offerer,
* token, type, tokenId, and conduit preference) as well as across all
* consideration items (token, type, tokenId, and recipient).
*/
struct Fulfillment {
FulfillmentComponent[] offerComponents;
FulfillmentComponent[] considerationComponents;
}
/**
* @dev Each fulfillment component contains one index referencing a specific
* order and another referencing a specific offer or consideration item.
*/
struct FulfillmentComponent {
uint256 orderIndex;
uint256 itemIndex;
}
/**
* @dev An execution is triggered once all consideration items have been zeroed
* out. It sends the item in question from the offerer to the item's
* recipient, optionally sourcing approvals from either this contract
* directly or from the offerer's chosen conduit if one is specified. An
* execution is not provided as an argument, but rather is derived via
* orders, criteria resolvers, and fulfillments (where the total number of
* executions will be less than or equal to the total number of indicated
* fulfillments) and returned as part of `matchOrders`.
*/
struct Execution {
ReceivedItem item;
address offerer;
bytes32 conduitKey;
}
/**
* @dev A received item is translated from a utilized consideration item and has
* the same four components as a spent item, as well as an additional fifth
* component designating the required recipient of the item.
*/
struct ReceivedItem {
ItemType itemType;
address token;
uint256 identifier;
uint256 amount;
address payable recipient;
}
struct CriteriaResolver {
uint256 orderIndex;
Side side;
uint256 index;
uint256 identifier;
bytes32[] criteriaProof;
}
// prettier-ignore
enum Side {
// 0: Items that can be spent
OFFER,
// 1: Items that must be received
CONSIDERATION
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
import {IERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol";
import {IWyvernExchange} from "../../contracts/interfaces/IWyvernExchange.sol";
import {IExchangeV2} from "../../contracts/interfaces/IExchangeV2.sol";
import {LibOrder} from "../../contracts/RaribleExchangeWrapper.sol";
import {LibDirectTransfer} from "../../contracts/RaribleExchangeWrapper.sol";
import {LibSeaPort} from "../../contracts/libraries/LibSeaPort.sol";
import {ISeaPort} from "../../contracts/interfaces/ISeaPort.sol";
import {Ix2y2} from "../../contracts/interfaces/Ix2y2.sol";
import {LibLooksRare} from "../../contracts/libraries/LibLooksRare.sol";
import {ILooksRare} from "../../contracts/interfaces/ILooksRare.sol";
import {ILSSVMRouter} from "../../contracts/interfaces/ILSSVMRouter.sol";
import {IBlur} from "../../contracts/interfaces/IBlur.sol";
interface IERC1155 {
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
}
interface IERC721 {
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}
interface IMatchERC721{
function matchERC721UsingCriteria(
address from,
address to,
IERC721 token,
uint256 tokenId,
bytes32 root,
bytes32[] calldata proof
) external returns (bool);
}
interface IMatchERC1155{
/*This method Merkle validator https://etherscan.io/address/0xbaf2127b49fc93cbca6269fade0f7f31df4c88a7#code
*/
function matchERC1155UsingCriteria(
address from,
address to,
IERC1155 token,
uint256 tokenId,
uint256 amount,
bytes32 root,
bytes32[] calldata proof
) external returns (bool);
}
/*Interface with error*/
interface IWyvernExchangeError {
/*method is not exist in WyvernBulkExchange contract*/
function atomicMatchError_(
address[14] memory addrs,
uint[18] memory uints,
uint8[8] memory feeMethodsSidesKindsHowToCalls,
bytes memory calldataBuy,
bytes memory calldataSell,
bytes memory replacementPatternBuy,
bytes memory replacementPatternSell,
bytes memory staticExtradataBuy,
bytes memory staticExtradataSell,
uint8[2] memory vs,
bytes32[5] memory rssMetadata)
external
payable;
}
contract WrapperHelper {
struct WyvernOrders {
address[14] addrs;
uint[18] uints;
uint8[8] feeMethodsSidesKindsHowToCalls;
bytes calldataBuy;
bytes calldataSell;
bytes replacementPatternBuy;
bytes replacementPatternSell;
bytes staticExtradataBuy;
bytes staticExtradataSell;
uint8[2] vs;
bytes32[5] rssMetadata;
}
struct RaribleBuy {
LibOrder.Order orderLeft;
bytes signatureLeft;
LibOrder.Order orderRight;
bytes signatureRight;
}
struct AdditionalData {
bytes data;
uint[] additionalRoyalties;
}
function getDataWyvernAtomicMatch(WyvernOrders memory _openSeaBuy) external pure returns(bytes memory _data) {
_data = abi.encodeWithSelector(IWyvernExchange.atomicMatch_.selector, _openSeaBuy.addrs, _openSeaBuy.uints, _openSeaBuy.feeMethodsSidesKindsHowToCalls, _openSeaBuy.calldataBuy, _openSeaBuy.calldataSell, _openSeaBuy.replacementPatternBuy, _openSeaBuy.replacementPatternSell, _openSeaBuy.staticExtradataBuy, _openSeaBuy.staticExtradataSell, _openSeaBuy.vs, _openSeaBuy.rssMetadata);
}
function getDataWyvernAtomicMatchWithError(WyvernOrders memory _openSeaBuy) external pure returns(bytes memory _data) {
_data = abi.encodeWithSelector(IWyvernExchangeError.atomicMatchError_.selector, _openSeaBuy.addrs, _openSeaBuy.uints, _openSeaBuy.feeMethodsSidesKindsHowToCalls, _openSeaBuy.calldataBuy, _openSeaBuy.calldataSell, _openSeaBuy.replacementPatternBuy, _openSeaBuy.replacementPatternSell, _openSeaBuy.staticExtradataBuy, _openSeaBuy.staticExtradataSell, _openSeaBuy.vs, _openSeaBuy.rssMetadata);
}
function getDataERC721UsingCriteria(
address from,
address to,
IERC721Upgradeable token,
uint256 tokenId
) external pure returns(bytes memory _data) {
_data = abi.encodeWithSelector(IMatchERC721.matchERC721UsingCriteria.selector, from, to, token, tokenId);
}
function getDataERC1155UsingCriteria(
address from,
address to,
IERC1155Upgradeable token,
uint256 tokenId,
uint256 amount
) external pure returns(bytes memory _data) {
_data = abi.encodeWithSelector(IMatchERC1155.matchERC1155UsingCriteria.selector, from, to, token, tokenId, amount);
}
function encodeOriginFeeIntoUint(address account, uint96 value) external pure returns(uint){
return (uint(value) << 160) + uint(account);
}
function getDataDirectPurchase(LibDirectTransfer.Purchase memory data) external pure returns(bytes memory result) {
result = abi.encodeWithSelector(IExchangeV2.directPurchase.selector, data);
}
function getDataSeaPortFulfillAdvancedOrder(
LibSeaPort.AdvancedOrder memory _advancedOrder,
LibSeaPort.CriteriaResolver[] memory _criteriaResolvers,
bytes32 _fulfillerConduitKey,
address _recipient
) external pure returns(bytes memory _data) {
_data = abi.encodeWithSelector(ISeaPort.fulfillAdvancedOrder.selector, _advancedOrder, _criteriaResolvers, _fulfillerConduitKey, _recipient);
}
function getDataSeaPortFulfillAvailableAdvancedOrders(
LibSeaPort.AdvancedOrder[] memory _orders,
LibSeaPort.CriteriaResolver[] memory _criteriaResolvers,
LibSeaPort.FulfillmentComponent[][] memory _offerFulfillments,
LibSeaPort.FulfillmentComponent[][] memory _considerationFulfillments,
bytes32 _fulfillerConduitKey,
address _recipient,
uint256 _maximumFulfilled
) external pure returns(bytes memory _data) {
_data = abi.encodeWithSelector(
ISeaPort.fulfillAvailableAdvancedOrders.selector,
_orders,
_criteriaResolvers,
_offerFulfillments,
_considerationFulfillments,
_fulfillerConduitKey,
_recipient,
_maximumFulfilled
);
}
function getDataSeaPortBasic(LibSeaPort.BasicOrderParameters calldata seaPortBasic, bytes4 typeNft) external pure returns(bytes memory _data) {
_data = abi.encode(seaPortBasic, typeNft);
}
function encodeData(Ix2y2.Pair721[] calldata data) external pure returns(bytes memory){
return abi.encode(data);
}
function encodeData1155(Ix2y2.Pair1155[] calldata data) external pure returns(bytes memory){
return abi.encode(data);
}
function hashItem(Ix2y2.Order memory order, Ix2y2.OrderItem memory item)
external
pure
returns (bytes32)
{
return
keccak256(
abi.encode(
order.salt,
order.user,
order.network,
order.intent,
order.delegateType,
order.deadline,
order.currency,
order.dataMask,
item
)
);
}
function encodeX2Y2Call(Ix2y2.RunInput calldata data) external pure returns(bytes memory) {
return abi.encode(data);
}
function getDataWrapperMatchAskWithTakerBidUsingETHAndWETH(LibLooksRare.TakerOrder calldata _takerBid, LibLooksRare.MakerOrder calldata _makerAsk, bytes4 typeNft) external pure returns(bytes memory _data) {
_data = abi.encode(_takerBid, _makerAsk, typeNft);
}
function encodeFees(uint first, uint second) external pure returns(uint){
return (uint(uint16(first)) << 16) + uint(uint16(second));
}
function encodeFeesPlusDataType(uint dataType, uint first, uint second) external pure returns(uint){
return (uint(uint16(dataType)) << 32) + (uint(uint16(first)) << 16) + uint(uint16(second));
}
function encodeCurrencyAndDataTypeAndFees(uint currency, uint dataType, uint first, uint second) external pure returns(uint){
return (uint(uint16(currency)) << 48) + (uint(uint16(dataType)) << 32) + (uint(uint16(first)) << 16) + uint(uint16(second));
}
function encodeDataPlusRoyalties(AdditionalData calldata data) external pure returns(bytes memory) {
return abi.encode(data);
}
function encodeBpPlusAccount(uint bp, address account) external pure returns (uint) {
return (uint(bp) << 160) + uint(account);
}
function decodeFees(uint data) external pure returns(uint, uint) {
uint first = uint(uint16(data >> 16));
uint second = uint(uint16(data));
return (first, second);
}
function encodeSudoSwapCall(
ILSSVMRouter.PairSwapSpecific[] calldata swapList,
address payable ethRecipient,
address nftRecipient,
uint256 deadline
) external pure returns (bytes memory _data) {
_data = abi.encodeWithSelector(ILSSVMRouter.swapETHForSpecificNFTs.selector, swapList, ethRecipient, nftRecipient, deadline);
}
function encodeLooksRareV2Call(LibLooksRare.Taker calldata takerBid, LibLooksRare.Maker calldata makerAsk, bytes calldata makerSignature, LibLooksRare.MerkleTree calldata merkleTree, address affiliate) external pure returns (bytes memory _data) {
_data = abi.encodeWithSelector(ILooksRare.executeTakerBid.selector, takerBid, makerAsk, makerSignature, merkleTree, affiliate);
}
function encodeBlurData(IBlur.Input memory sell, IBlur.Input memory buy, bytes4 typeNft) external pure returns(bytes memory _data) {
_data = abi.encode(sell, buy, typeNft);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol";
import "./LibERC1155LazyMint.sol";
import "@rarible/lib-part/contracts/LibPart.sol";
interface IERC1155LazyMint is IERC1155Upgradeable {
event Supply(
uint256 tokenId,
uint256 value
);
event Creators(
uint256 tokenId,
LibPart.Part[] creators
);
function mintAndTransfer(
LibERC1155LazyMint.Mint1155Data memory data,
address to,
uint256 _amount
) external;
function transferFromOrMint(
LibERC1155LazyMint.Mint1155Data memory data,
address from,
address to,
uint256 amount
) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "@rarible/lib-part/contracts/LibPart.sol";
library LibERC1155LazyMint {
bytes4 constant public ERC1155_LAZY_ASSET_CLASS = bytes4(keccak256("ERC1155_LAZY"));
bytes4 constant _INTERFACE_ID_MINT_AND_TRANSFER = 0x6db15a0f;
struct Mint1155Data {
uint tokenId;
string tokenURI;
uint supply;
LibPart.Part[] creators;
LibPart.Part[] royalties;
bytes[] signatures;
}
bytes32 public constant MINT_AND_TRANSFER_TYPEHASH = keccak256("Mint1155(uint256 tokenId,uint256 supply,string tokenURI,Part[] creators,Part[] royalties)Part(address account,uint96 value)");
function hash(Mint1155Data memory data) internal pure returns (bytes32) {
bytes32[] memory royaltiesBytes = new bytes32[](data.royalties.length);
for (uint i = 0; i < data.royalties.length; ++i) {
royaltiesBytes[i] = LibPart.hash(data.royalties[i]);
}
bytes32[] memory creatorsBytes = new bytes32[](data.creators.length);
for (uint i = 0; i < data.creators.length; ++i) {
creatorsBytes[i] = LibPart.hash(data.creators[i]);
}
return keccak256(abi.encode(
MINT_AND_TRANSFER_TYPEHASH,
data.tokenId,
data.supply,
keccak256(bytes(data.tokenURI)),
keccak256(abi.encodePacked(creatorsBytes)),
keccak256(abi.encodePacked(royaltiesBytes))
));
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
import "./LibERC721LazyMint.sol";
import "@rarible/lib-part/contracts/LibPart.sol";
interface IERC721LazyMint is IERC721Upgradeable {
event Creators(
uint256 tokenId,
LibPart.Part[] creators
);
function mintAndTransfer(
LibERC721LazyMint.Mint721Data memory data,
address to
) external;
function transferFromOrMint(
LibERC721LazyMint.Mint721Data memory data,
address from,
address to
) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "@rarible/lib-part/contracts/LibPart.sol";
library LibERC721LazyMint {
bytes4 constant public ERC721_LAZY_ASSET_CLASS = bytes4(keccak256("ERC721_LAZY"));
bytes4 constant _INTERFACE_ID_MINT_AND_TRANSFER = 0x8486f69f;
struct Mint721Data {
uint tokenId;
string tokenURI;
LibPart.Part[] creators;
LibPart.Part[] royalties;
bytes[] signatures;
}
bytes32 public constant MINT_AND_TRANSFER_TYPEHASH = keccak256("Mint721(uint256 tokenId,string tokenURI,Part[] creators,Part[] royalties)Part(address account,uint96 value)");
function hash(Mint721Data memory data) internal pure returns (bytes32) {
bytes32[] memory royaltiesBytes = new bytes32[](data.royalties.length);
for (uint i = 0; i < data.royalties.length; ++i) {
royaltiesBytes[i] = LibPart.hash(data.royalties[i]);
}
bytes32[] memory creatorsBytes = new bytes32[](data.creators.length);
for (uint i = 0; i < data.creators.length; ++i) {
creatorsBytes[i] = LibPart.hash(data.creators[i]);
}
return keccak256(abi.encode(
MINT_AND_TRANSFER_TYPEHASH,
data.tokenId,
keccak256(bytes(data.tokenURI)),
keccak256(abi.encodePacked(creatorsBytes)),
keccak256(abi.encodePacked(royaltiesBytes))
));
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import "../../contracts/erc-721/IERC721LazyMint.sol";
contract ERC721LazyMintTest is IERC721LazyMint, ERC721Upgradeable {
function mintAndTransfer(
LibERC721LazyMint.Mint721Data memory data,
address to
) external override {
_mint(to, data.tokenId);
}
function transferFromOrMint(
LibERC721LazyMint.Mint721Data memory data,
address from,
address to
) external override {
if (_exists(data.tokenId)) {
safeTransferFrom(from, to, data.tokenId);
} else {
this.mintAndTransfer(data, to);
}
}
function encode(LibERC721LazyMint.Mint721Data memory data)
external
view
returns (bytes memory)
{
return abi.encode(address(this), data);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
library LibAsset {
bytes4 constant public ETH_ASSET_CLASS = bytes4(keccak256("ETH"));
bytes4 constant public ERC20_ASSET_CLASS = bytes4(keccak256("ERC20"));
bytes4 constant public ERC721_ASSET_CLASS = bytes4(keccak256("ERC721"));
bytes4 constant public ERC1155_ASSET_CLASS = bytes4(keccak256("ERC1155"));
bytes4 constant public COLLECTION = bytes4(keccak256("COLLECTION"));
bytes4 constant public CRYPTO_PUNKS = bytes4(keccak256("CRYPTO_PUNKS"));
bytes32 constant ASSET_TYPE_TYPEHASH = keccak256(
"AssetType(bytes4 assetClass,bytes data)"
);
bytes32 constant ASSET_TYPEHASH = keccak256(
"Asset(AssetType assetType,uint256 value)AssetType(bytes4 assetClass,bytes data)"
);
struct AssetType {
bytes4 assetClass;
bytes data;
}
struct Asset {
AssetType assetType;
uint value;
}
function hash(AssetType memory assetType) internal pure returns (bytes32) {
return keccak256(abi.encode(
ASSET_TYPE_TYPEHASH,
assetType.assetClass,
keccak256(assetType.data)
));
}
function hash(Asset memory asset) internal pure returns (bytes32) {
return keccak256(abi.encode(
ASSET_TYPEHASH,
hash(asset.assetType),
asset.value
));
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
library BpLibrary {
using SafeMathUpgradeable for uint;
function bp(uint value, uint bpValue) internal pure returns (uint) {
return value.mul(bpValue).div(10000);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
library LibPart {
bytes32 public constant TYPE_HASH = keccak256("Part(address account,uint96 value)");
struct Part {
address payable account;
uint96 value;
}
function hash(Part memory part) internal pure returns (bytes32) {
return keccak256(abi.encode(TYPE_HASH, part.account, part.value));
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
abstract contract ERC1271 {
bytes4 constant public ERC1271_INTERFACE_ID = 0xfb855dc9; // this.isValidSignature.selector
bytes4 constant public ERC1271_RETURN_VALID_SIGNATURE = 0x1626ba7e;
bytes4 constant public ERC1271_RETURN_INVALID_SIGNATURE = 0x00000000;
/**
* @dev Function must be implemented by deriving contract
* @param _hash Arbitrary length data signed on the behalf of address(this)
* @param _signature Signature byte array associated with _data
* @return A bytes4 magic value 0x1626ba7e if the signature check passes, 0x00000000 if not
*
* MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)
* MUST allow external calls
*/
function isValidSignature(bytes32 _hash, bytes memory _signature) public virtual view returns (bytes4);
function returnIsValidSignatureMagicNumber(bool isValid) internal pure returns (bytes4) {
return isValid ? ERC1271_RETURN_VALID_SIGNATURE : ERC1271_RETURN_INVALID_SIGNATURE;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
interface IERC1271 {
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param _hash Hash of the data signed on the behalf of address(this)
* @param _signature Signature byte array associated with _data
*
* MUST return the bytes4 magic value 0x1626ba7e when function passes.
* MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)
* MUST allow external calls
*/
function isValidSignature(bytes32 _hash, bytes calldata _signature) virtual external view returns (bytes4 magicValue);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
library LibSignature {
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature)
internal
pure
returns (address)
{
// Check the signature length
if (signature.length != 65) {
revert("ECDSA: invalid signature length");
}
// Divide the signature in r, s and v variables
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
// solhint-disable-next-line no-inline-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return recover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover-bytes32-bytes-} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
require(
uint256(s) <=
0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
"ECDSA: invalid signature 's' value"
);
// If the signature is valid (and not malleable), return the signer address
// v > 30 is a special case, we need to adjust hash with "\x19Ethereum Signed Message:\n32"
// and v = v - 4
address signer;
if (v > 30) {
require(
v - 4 == 27 || v - 4 == 28,
"ECDSA: invalid signature 'v' value"
);
signer = ecrecover(toEthSignedMessageHash(hash), v - 4, r, s);
} else {
require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value");
signer = ecrecover(hash, v, r, s);
}
require(signer != address(0), "ECDSA: invalid signature");
return signer;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* replicates the behavior of the
* https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]
* JSON-RPC method.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash)
internal
pure
returns (bytes32)
{
// 32 is the length in bytes of hash,
// enforced by the type signature above
return
keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)
);
}
}//SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
abstract contract EIP712MetaTransaction is ContextUpgradeable {
using SafeMath for uint256;
bytes32 private constant META_TRANSACTION_TYPEHASH = keccak256(bytes("MetaTransaction(uint256 nonce,address from,bytes functionSignature)"));
bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)");
mapping(address => uint256) private nonces;
bytes32 internal domainSeparator;
/*
* Meta transaction structure.
* No point of including value field here as if user is doing value transfer then he has the funds to pay for gas
* He should call the desired function directly in that case.
*/
struct MetaTransaction {
uint256 nonce;
address from;
bytes functionSignature;
}
/*
* Domain structure.
* Data(information to for making metaTransaction method uniq.) about method and contract
*/
struct EIP712Domain {
string name;
string version;
address verifyingContract;
bytes32 salt;
}
event MetaTransactionExecuted(address userAddress, address payable relayerAddress, bytes functionSignature);
function __MetaTransaction_init_unchained(string memory name, string memory version) internal {
domainSeparator = keccak256(abi.encode(
EIP712_DOMAIN_TYPEHASH,
keccak256(bytes(name)),
keccak256(bytes(version)),
address(this),
getSalt()
));
}
function convertBytesToBytes4(bytes memory inBytes) internal pure returns (bytes4 outBytes4) {
if (inBytes.length == 0) {
return 0x0;
}
assembly {
outBytes4 := mload(add(inBytes, 32))
}
}
function executeMetaTransaction(address userAddress,
bytes memory functionSignature, bytes32 sigR, bytes32 sigS, uint8 sigV) external payable returns (bytes memory) {
bytes4 destinationFunctionSig = convertBytesToBytes4(functionSignature);
require(destinationFunctionSig != msg.sig, "Wrong functionSignature");
MetaTransaction memory metaTx = MetaTransaction({
nonce : nonces[userAddress],
from : userAddress,
functionSignature : functionSignature
});
require(verify(userAddress, metaTx, sigR, sigS, sigV), "Signer and signature do not match");
nonces[userAddress] = nonces[userAddress].add(1);
// Append userAddress at the end to extract it from calling context
(bool success, bytes memory returnData) = address(this).call(abi.encodePacked(functionSignature, userAddress));
require(success, "Function call not successful");
emit MetaTransactionExecuted(userAddress, msg.sender, functionSignature);
return returnData;
}
function hashMetaTransaction(MetaTransaction memory metaTx) internal pure returns (bytes32) {
return keccak256(abi.encode(
META_TRANSACTION_TYPEHASH,
metaTx.nonce,
metaTx.from,
keccak256(metaTx.functionSignature)
));
}
function getNonce(address user) external view returns (uint256 nonce) {
nonce = nonces[user];
}
function verify(address user, MetaTransaction memory metaTx, bytes32 sigR, bytes32 sigS, uint8 sigV) internal view returns (bool) {
address signer = ecrecover(toTypedMessageHash(hashMetaTransaction(metaTx)), sigV, sigR, sigS);
require(signer != address(0), "Invalid signature");
return signer == user;
}
function _msgSender() internal view virtual override returns (address payable sender) {
if (msg.sender == address(this)) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
} else {
sender = msg.sender;
}
return sender;
}
function getSalt() internal pure returns (bytes32) {
return bytes32(getChainID());
}
function getChainID() internal pure returns (uint256 id) {
assembly {
id := chainid()
}
}
function getDomainSeparator() private view returns (bytes32) {
return domainSeparator;
}
/**
* Accept message hash and returns hash message in EIP712 compatible form
* So that it can be used to recover signer from signature signed using EIP712 formatted data
* https://eips.ethereum.org/EIPS/eip-712
* "\\x19" makes the encoding deterministic
* "\\x01" is the version byte to make it compatible to EIP-191
*/
function toTypedMessageHash(bytes32 messageHash) internal view returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", getDomainSeparator(), messageHash));
}
/**
* @dev verifies the call result and bubbles up revert reason for failed calls
*
* @param success : outcome of forwarded call
* @param returndata : returned data from the frowarded call
* @param errorMessage : fallback error message to show
*/
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure {
if (!success) {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
contract OperatorRole is OwnableUpgradeable {
mapping (address => bool) operators;
function __OperatorRole_init() external initializer {
__Context_init_unchained();
__Ownable_init_unchained();
}
function addOperator(address operator) external onlyOwner {
operators[operator] = true;
}
function removeOperator(address operator) external onlyOwner {
operators[operator] = false;
}
modifier onlyOperator() {
require(operators[_msgSender()], "OperatorRole: caller is not the operator");
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "@rarible/exchange-interfaces/contracts/IRoyaltiesProvider.sol";
import "@rarible/royalties/contracts/LibRoyaltiesV2.sol";
import "@rarible/royalties/contracts/LibRoyaltiesV1.sol";
import "@rarible/royalties/contracts/LibRoyalties2981.sol";
import "@rarible/royalties/contracts/RoyaltiesV1.sol";
import "@rarible/royalties/contracts/RoyaltiesV2.sol";
import "@rarible/royalties/contracts/IERC2981.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
contract RoyaltiesRegistry is IRoyaltiesProvider, OwnableUpgradeable {
/// @dev deprecated
event RoyaltiesSetForToken(address indexed token, uint indexed tokenId, LibPart.Part[] royalties);
/// @dev emitted when royalties set for token in
event RoyaltiesSetForContract(address indexed token, LibPart.Part[] royalties);
/// @dev struct to store royalties in royaltiesByToken
struct RoyaltiesSet {
bool initialized;
LibPart.Part[] royalties;
}
/// @dev deprecated
mapping(bytes32 => RoyaltiesSet) public royaltiesByTokenAndTokenId;
/// @dev stores royalties for token contract, set in setRoyaltiesByToken() method
mapping(address => RoyaltiesSet) public royaltiesByToken;
/// @dev stores external provider and royalties type for token contract
mapping(address => uint) public royaltiesProviders;
/// @dev total amount or supported royalties types
// 0 - royalties type is unset
// 1 - royaltiesByToken, 2 - v2, 3 - v1,
// 4 - external provider, 5 - EIP-2981
// 6 - unsupported/nonexistent royalties type
uint constant royaltiesTypesAmount = 6;
function __RoyaltiesRegistry_init() external initializer {
__Ownable_init_unchained();
}
/// @dev sets external provider for token contract, and royalties type = 4
function setProviderByToken(address token, address provider) external {
checkOwner(token);
setRoyaltiesType(token, 4, provider);
}
/// @dev returns provider address for token contract from royaltiesProviders mapping
function getProvider(address token) public view returns(address) {
return address(royaltiesProviders[token]);
}
/// @dev returns royalties type for token contract
function getRoyaltiesType(address token) external view returns(uint) {
return _getRoyaltiesType(royaltiesProviders[token]);
}
/// @dev returns royalties type from uint
function _getRoyaltiesType(uint data) internal pure returns(uint) {
for (uint i = 1; i <= royaltiesTypesAmount; ++i) {
if (data / 2**(256-i) == 1) {
return i;
}
}
return 0;
}
/// @dev sets royalties type for token contract
function setRoyaltiesType(address token, uint royaltiesType, address royaltiesProvider) internal {
require(royaltiesType > 0 && royaltiesType <= royaltiesTypesAmount, "wrong royaltiesType");
royaltiesProviders[token] = uint(royaltiesProvider) + 2**(256 - royaltiesType);
}
/// @dev clears and sets new royalties type for token contract
function forceSetRoyaltiesType(address token, uint royaltiesType) external {
checkOwner(token);
setRoyaltiesType(token, royaltiesType, getProvider(token));
}
/// @dev clears royalties type for token contract
function clearRoyaltiesType(address token) external {
checkOwner(token);
royaltiesProviders[token] = uint(getProvider(token));
}
/// @dev sets royalties for token contract in royaltiesByToken mapping and royalties type = 1
function setRoyaltiesByToken(address token, LibPart.Part[] memory royalties) external {
checkOwner(token);
//clearing royaltiesProviders value for the token
delete royaltiesProviders[token];
// setting royaltiesType = 1 for the token
setRoyaltiesType(token, 1, address(0));
uint sumRoyalties = 0;
delete royaltiesByToken[token];
for (uint i = 0; i < royalties.length; ++i) {
require(royalties[i].account != address(0x0), "RoyaltiesByToken recipient should be present");
require(royalties[i].value != 0, "Royalty value for RoyaltiesByToken should be > 0");
royaltiesByToken[token].royalties.push(royalties[i]);
sumRoyalties += royalties[i].value;
}
require(sumRoyalties < 10000, "Set by token royalties sum more, than 100%");
royaltiesByToken[token].initialized = true;
emit RoyaltiesSetForContract(token, royalties);
}
/// @dev checks if msg.sender is owner of this contract or owner of the token contract
function checkOwner(address token) internal view {
if ((owner() != _msgSender()) && (OwnableUpgradeable(token).owner() != _msgSender())) {
revert("Token owner not detected");
}
}
/// @dev calculates royalties type for token contract
function calculateRoyaltiesType(address token, address royaltiesProvider ) internal view returns(uint) {
try IERC165Upgradeable(token).supportsInterface(LibRoyaltiesV2._INTERFACE_ID_ROYALTIES) returns(bool result) {
if (result) {
return 2;
}
} catch { }
try IERC165Upgradeable(token).supportsInterface(LibRoyaltiesV1._INTERFACE_ID_FEES) returns(bool result) {
if (result) {
return 3;
}
} catch { }
try IERC165Upgradeable(token).supportsInterface(LibRoyalties2981._INTERFACE_ID_ROYALTIES) returns(bool result) {
if (result) {
return 5;
}
} catch { }
if (royaltiesProvider != address(0)) {
return 4;
}
if (royaltiesByToken[token].initialized) {
return 1;
}
return 6;
}
/// @dev returns royalties for token contract and token id
function getRoyalties(address token, uint tokenId) override external returns (LibPart.Part[] memory) {
uint royaltiesProviderData = royaltiesProviders[token];
address royaltiesProvider = address(royaltiesProviderData);
uint royaltiesType = _getRoyaltiesType(royaltiesProviderData);
// case when royaltiesType is not set
if (royaltiesType == 0) {
// calculating royalties type for token
royaltiesType = calculateRoyaltiesType(token, royaltiesProvider);
//saving royalties type
setRoyaltiesType(token, royaltiesType, royaltiesProvider);
}
//case royaltiesType = 1, royalties are set in royaltiesByToken
if (royaltiesType == 1) {
return royaltiesByToken[token].royalties;
}
//case royaltiesType = 2, royalties rarible v2
if (royaltiesType == 2) {
return getRoyaltiesRaribleV2(token,tokenId);
}
//case royaltiesType = 3, royalties rarible v1
if (royaltiesType == 3) {
return getRoyaltiesRaribleV1(token, tokenId);
}
//case royaltiesType = 4, royalties from external provider
if (royaltiesType == 4) {
return providerExtractor(token, tokenId, royaltiesProvider);
}
//case royaltiesType = 5, royalties EIP-2981
if (royaltiesType == 5) {
return getRoyaltiesEIP2981(token, tokenId);
}
// case royaltiesType = 6, unknown/empty royalties
if (royaltiesType == 6) {
return new LibPart.Part[](0);
}
revert("something wrong in getRoyalties");
}
/// @dev tries to get royalties rarible-v2 for token and tokenId
function getRoyaltiesRaribleV2(address token, uint tokenId) internal view returns (LibPart.Part[] memory) {
try RoyaltiesV2(token).getRaribleV2Royalties(tokenId) returns (LibPart.Part[] memory result) {
return result;
} catch {
return new LibPart.Part[](0);
}
}
/// @dev tries to get royalties rarible-v1 for token and tokenId
function getRoyaltiesRaribleV1(address token, uint tokenId) internal view returns (LibPart.Part[] memory) {
RoyaltiesV1 v1 = RoyaltiesV1(token);
address payable[] memory recipients;
try v1.getFeeRecipients(tokenId) returns (address payable[] memory resultRecipients) {
recipients = resultRecipients;
} catch {
return new LibPart.Part[](0);
}
uint[] memory values;
try v1.getFeeBps(tokenId) returns (uint[] memory resultValues) {
values = resultValues;
} catch {
return new LibPart.Part[](0);
}
if (values.length != recipients.length) {
return new LibPart.Part[](0);
}
LibPart.Part[] memory result = new LibPart.Part[](values.length);
for (uint256 i = 0; i < values.length; ++i) {
result[i].value = uint96(values[i]);
result[i].account = recipients[i];
}
return result;
}
/// @dev tries to get royalties EIP-2981 for token and tokenId
function getRoyaltiesEIP2981(address token, uint tokenId) internal view returns (LibPart.Part[] memory) {
try IERC2981(token).royaltyInfo(tokenId, LibRoyalties2981._WEIGHT_VALUE) returns (address receiver, uint256 royaltyAmount) {
return LibRoyalties2981.calculateRoyalties(receiver, royaltyAmount);
} catch {
return new LibPart.Part[](0);
}
}
/// @dev tries to get royalties for token and tokenId from external provider set in royaltiesProviders
function providerExtractor(address token, uint tokenId, address providerAddress) internal returns (LibPart.Part[] memory) {
try IRoyaltiesProvider(providerAddress).getRoyalties(token, tokenId) returns (LibPart.Part[] memory result) {
return result;
} catch {
return new LibPart.Part[](0);
}
}
uint256[46] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
import "@rarible/exchange-interfaces/contracts/IRoyaltiesProvider.sol";
import "./RoyaltyArtBlocks.sol";
import "@rarible/lib-bp/contracts/BpLibrary.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract RoyaltiesProviderArtBlocks is IRoyaltiesProvider, Ownable {
using SafeMathUpgradeable for uint;
using BpLibrary for uint;
uint96 public artblocksPercentage = 250;
event ArtblocksPercentageChanged(address _who, uint96 _old, uint96 _new);
function getRoyalties(address token, uint tokenId) override external view returns(LibPart.Part[] memory) {
RoyaltyArtBlocks artBlocks = RoyaltyArtBlocks(token);
//gettign artist and additionalPayee royalty part
(address artistAddress, address additionalPayee, uint256 additionalPayeePercentage, uint256 royaltyFeeByID) = artBlocks.getRoyaltyData(tokenId);
require(additionalPayeePercentage <= 100 && royaltyFeeByID <= 100, "wrong royalties percentages from artBlocks");
//resulting royalties
LibPart.Part[] memory result;
//if no artist royalty
if (royaltyFeeByID == 0) {
//if artblocksPercentage > 0
if (artblocksPercentage > 0) {
result = new LibPart.Part[](1);
//calculating artBLocks part
result[0].account = payable(owner());
result[0].value = artblocksPercentage;
}
//if artblocksPercentage = 0 then result is empty
return result;
//if royaltyFeeByID > 0 and 0 < additionalPayeePercentage < 100
} else if (additionalPayeePercentage > 0 && additionalPayeePercentage < 100) {
result = new LibPart.Part[](3);
//calculating artBLocks part
result[0].account = payable(owner());
result[0].value = artblocksPercentage;
// additional payee percentage * 100
uint96 additionalPart = uint96(royaltyFeeByID.mul(100).bp(additionalPayeePercentage.mul(100)));
//artist part
result[1].account = payable(artistAddress);
result[1].value = uint96(royaltyFeeByID.mul(100).sub(additionalPart));
result[2].account = payable(additionalPayee);
result[2].value = additionalPart;
//if royaltyFeeByID > 0 and additionalPayeePercentage == 0 or 100
} else {
result = new LibPart.Part[](2);
//calculating artBLocks part
result[0].account = payable(owner());
result[0].value = artblocksPercentage;
// additional payee percentage * 100
uint96 additionalPart = uint96(royaltyFeeByID.mul(100).bp(additionalPayeePercentage.mul(100)));
//artist part
if (additionalPayeePercentage == 0) {
result[1].account = payable(artistAddress);
result[1].value = uint96(royaltyFeeByID.mul(100).sub(additionalPart));
}
//additional payee part
if (additionalPayeePercentage == 100) {
result[1].account = payable(additionalPayee);
result[1].value = additionalPart;
}
}
return result;
}
//sets new value for artblocksPercentage
function setArtblocksPercentage(uint96 _artblocksPercentage) onlyOwner public {
require(_artblocksPercentage <= 10000,"_artblocksPercentage can't be > 100%");
emit ArtblocksPercentageChanged(_msgSender(), artblocksPercentage, _artblocksPercentage);
artblocksPercentage = _artblocksPercentage;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
import "@rarible/exchange-interfaces/contracts/IRoyaltiesProvider.sol";
import "./RoyaltyArtBlocksV2.sol";
contract RoyaltiesProviderArtBlocksV2 is IRoyaltiesProvider {
function getRoyalties(address token, uint tokenId) override external view returns(LibPart.Part[] memory) {
RoyaltyArtBlocksV2 artBlocksV2 = RoyaltyArtBlocksV2(token);
(address payable[] memory recipients, uint256[] memory bps) = artBlocksV2.getRoyalties(tokenId);
uint256 len = recipients.length;
LibPart.Part[] memory result = new LibPart.Part[](len);
for (uint i = 0; i < len; i++) {
result[i].account = recipients[i];
result[i].value = uint96(bps[i]);
}
return result;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
import "@rarible/exchange-interfaces/contracts/IRoyaltiesProvider.sol";
import "./RoyaltyV2Legacy.sol";
contract RoyaltiesProviderV2Legacy is IRoyaltiesProvider {
function getRoyalties(address token, uint tokenId) override external view returns(LibPart.Part[] memory) {
return RoyaltyV2Legacy(token).getRoyalties(tokenId);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "@rarible/lib-part/contracts/LibPart.sol";
abstract contract RoyaltyArtBlocks {
function getRoyaltyData(uint256 _tokenId) external virtual view returns (address artistAddress, address additionalPayee, uint256 additionalPayeePercentage, uint256 royaltyFeeByID);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "@rarible/lib-part/contracts/LibPart.sol";
abstract contract RoyaltyArtBlocksV2 {
/**
* @notice Gets royalty Basis Points (BPS) for token ID `_tokenId`.
* This conforms to the IManifold interface designated in the Royalty
* Registry's RoyaltyEngineV1.sol contract.
* ref: https://github.com/manifoldxyz/royalty-registry-solidity
* @param _tokenId Token ID to be queried.
* @return recipients Array of royalty payment recipients
* @return bps Array of Basis Points (BPS) allocated to each recipient,
* aligned by index.
* @dev reverts if invalid _tokenId
* @dev only returns recipients that have a non-zero BPS allocation
*/
function getRoyalties(uint256 _tokenId)
external
view
virtual
returns (
address payable[] memory recipients,
uint256[] memory bps
);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "@rarible/lib-part/contracts/LibPart.sol";
interface RoyaltyV2Legacy {
event RoyaltiesSet(uint256 tokenId, LibPart.Part[] royalties);
function getRoyalties(uint256 id) external view returns (LibPart.Part[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol";
import "@rarible/royalties/contracts/LibRoyaltiesV2.sol";
import "@rarible/royalties/contracts/RoyaltiesV2.sol";
abstract contract RoyaltiesV2Upgradeable is ERC165Upgradeable, RoyaltiesV2 {
function __RoyaltiesV2Upgradeable_init_unchained() internal initializer {
_registerInterface(LibRoyaltiesV2._INTERFACE_ID_ROYALTIES);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "@rarible/lib-part/contracts/LibPart.sol";
///
/// @dev Interface for the NFT Royalty Standard
///
//interface IERC2981 is IERC165 {
interface IERC2981 {
/// ERC165 bytes to add to interface array - set in parent contract
/// implementing this standard
///
/// bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a
/// bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;
/// _registerInterface(_INTERFACE_ID_ERC2981);
/// @notice Called with the sale price to determine how much royalty
// is owed and to whom.
/// @param _tokenId - the NFT asset queried for royalty information
/// @param _salePrice - the sale price of the NFT asset specified by _tokenId
/// @return receiver - address of who should be sent the royalty payment
/// @return royaltyAmount - the royalty payment amount for _salePrice
function royaltyInfo(
uint256 _tokenId,
uint256 _salePrice
) external view returns (
address receiver,
uint256 royaltyAmount
);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "@rarible/lib-part/contracts/LibPart.sol";
library LibRoyalties2981 {
/*
* https://eips.ethereum.org/EIPS/eip-2981: bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;
*/
bytes4 constant _INTERFACE_ID_ROYALTIES = 0x2a55205a;
uint96 constant _WEIGHT_VALUE = 1000000;
/*Method for converting amount to percent and forming LibPart*/
function calculateRoyalties(address to, uint256 amount) internal view returns (LibPart.Part[] memory) {
LibPart.Part[] memory result;
if (amount == 0) {
return result;
}
uint256 percent = amount * 10000 / _WEIGHT_VALUE;
require(percent < 10000, "Royalties 2981 exceeds 100%");
result = new LibPart.Part[](1);
result[0].account = payable(to);
result[0].value = uint96(percent);
return result;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
library LibRoyaltiesV1 {
/*
* bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f
* bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb
*
* => 0x0ebd4c7f ^ 0xb9c4d9fb == 0xb7799584
*/
bytes4 constant _INTERFACE_ID_FEES = 0xb7799584;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
library LibRoyaltiesV2 {
/*
* bytes4(keccak256('getRaribleV2Royalties(uint256)')) == 0xcad96cca
*/
bytes4 constant _INTERFACE_ID_ROYALTIES = 0xcad96cca;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
interface RoyaltiesV1 {
event SecondarySaleFees(uint256 tokenId, address[] recipients, uint[] bps);
function getFeeRecipients(uint256 id) external view returns (address payable[] memory);
function getFeeBps(uint256 id) external view returns (uint[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "@rarible/lib-part/contracts/LibPart.sol";
interface RoyaltiesV2 {
event RoyaltiesSet(uint256 tokenId, LibPart.Part[] royalties);
function getRaribleV2Royalties(uint256 id) external view returns (LibPart.Part[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "@rarible/lib-part/contracts/LibPart.sol";
abstract contract AbstractRoyalties {
mapping (uint256 => LibPart.Part[]) internal royalties;
function _saveRoyalties(uint256 id, LibPart.Part[] memory _royalties) internal {
uint256 totalValue;
for (uint i = 0; i < _royalties.length; ++i) {
require(_royalties[i].account != address(0x0), "Recipient should be present");
require(_royalties[i].value != 0, "Royalty value should be positive");
totalValue += _royalties[i].value;
royalties[id].push(_royalties[i]);
}
require(totalValue < 10000, "Royalty total value should be < 10000");
_onRoyaltiesSet(id, _royalties);
}
function _updateAccount(uint256 _id, address _from, address _to) internal {
uint length = royalties[_id].length;
for(uint i = 0; i < length; ++i) {
if (royalties[_id][i].account == _from) {
royalties[_id][i].account = payable(address(uint160(_to)));
}
}
}
function _onRoyaltiesSet(uint256 id, LibPart.Part[] memory _royalties) virtual internal;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "./AbstractRoyalties.sol";
import "../RoyaltiesV1.sol";
contract RoyaltiesV1Impl is AbstractRoyalties, RoyaltiesV1 {
function getFeeRecipients(uint256 id) public override view returns (address payable[] memory) {
LibPart.Part[] memory _royalties = royalties[id];
address payable[] memory result = new address payable[](_royalties.length);
for (uint i = 0; i < _royalties.length; ++i) {
result[i] = address(uint160(_royalties[i].account));
}
return result;
}
function getFeeBps(uint256 id) public override view returns (uint[] memory) {
LibPart.Part[] memory _royalties = royalties[id];
uint[] memory result = new uint[](_royalties.length);
for (uint i = 0; i < _royalties.length; ++i) {
result[i] = _royalties[i].value;
}
return result;
}
function _onRoyaltiesSet(uint256 id, LibPart.Part[] memory _royalties) override internal {
address[] memory recipients = new address[](_royalties.length);
uint[] memory bps = new uint[](_royalties.length);
for (uint i = 0; i < _royalties.length; ++i) {
recipients[i] = _royalties[i].account;
bps[i] = _royalties[i].value;
}
emit SecondarySaleFees(id, recipients, bps);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "./AbstractRoyalties.sol";
import "../RoyaltiesV2.sol";
import "../IERC2981.sol";
import "../LibRoyalties2981.sol";
contract RoyaltiesV2Impl is AbstractRoyalties, RoyaltiesV2, IERC2981 {
function getRaribleV2Royalties(uint256 id) override external view returns (LibPart.Part[] memory) {
return royalties[id];
}
function _onRoyaltiesSet(uint256 id, LibPart.Part[] memory _royalties) override internal {
emit RoyaltiesSet(id, _royalties);
}
/*
*Token (ERC721, ERC721Minimal, ERC721MinimalMeta, ERC1155 ) can have a number of different royalties beneficiaries
*calculate sum all royalties, but royalties beneficiary will be only one royalties[0].account, according to rules of IERC2981
*/
function royaltyInfo(uint256 id, uint256 _salePrice) override external view returns (address receiver, uint256 royaltyAmount) {
if (royalties[id].length == 0) {
receiver = address(0);
royaltyAmount = 0;
return(receiver, royaltyAmount);
}
LibPart.Part[] memory _royalties = royalties[id];
receiver = _royalties[0].account;
uint percent;
for (uint i = 0; i < _royalties.length; ++i) {
percent += _royalties[i].value;
}
//don`t need require(percent < 10000, "Token royalty > 100%"); here, because check later in calculateRoyalties
royaltyAmount = percent * _salePrice / 10000;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol";
import "../../contracts/impl/RoyaltiesV2Impl.sol";
import "../../contracts/LibRoyaltiesV2.sol";
contract TestERC1155RoyaltiesV2 is RoyaltiesV2Impl, ERC1155Upgradeable {
function initialize() public initializer {
_registerInterface(LibRoyaltiesV2._INTERFACE_ID_ROYALTIES);
}
function mint(address to, uint tokenId, uint amount, LibPart.Part[] memory _fees) external {
_mint(to, tokenId, amount, "");
_saveRoyalties(tokenId, _fees);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import "../../contracts/impl/RoyaltiesV1Impl.sol";
import "../../contracts/LibRoyaltiesV1.sol";
contract TestERC721RoyaltiesV1 is RoyaltiesV1Impl, ERC721Upgradeable {
function initialize() public initializer {
_registerInterface(LibRoyaltiesV1._INTERFACE_ID_FEES);
}
function mint(address to, uint tokenId, LibPart.Part[] memory _fees) external {
_mint(to, tokenId);
_saveRoyalties(tokenId, _fees);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import "../../contracts/impl/RoyaltiesV2Impl.sol";
import "../../contracts/LibRoyaltiesV2.sol";
contract TestERC721RoyaltiesV2 is RoyaltiesV2Impl, ERC721Upgradeable {
function initialize() public initializer {
_registerInterface(LibRoyaltiesV2._INTERFACE_ID_ROYALTIES);
}
function mint(address to, uint tokenId, LibPart.Part[] memory _fees) external {
_mint(to, tokenId);
_saveRoyalties(tokenId, _fees);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol";
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
contract TestERC1155 is ERC1155, Pausable {
constructor() ERC1155("uri"){
}
function mint(address to, uint tokenId, uint amount) external {
_mint(to, tokenId, amount, "");
}
function batchSafeTransferFrom(
address[] memory froms,
address[] memory tos,
uint256[] memory ids,
uint256[] memory amounts
) external {
require(froms.length == tos.length, "wrong length 1");
require(tos.length == ids.length, "wrong length 2");
require(ids.length == amounts.length, "wrong length 3");
for (uint i = 0; i < froms.length; i ++) {
safeTransferFrom(froms[i], tos[i], ids[i], amounts[i], "");
}
}
function emitPauseEvent(bool paused) external {
if (paused) {
emit Paused(address(0));
} else {
emit Unpaused(address(0));
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
contract TestERC20 is ERC20Upgradeable {
function mint(address to, uint amount) external {
_mint(to, amount);
}
function init() external {
__ERC20_init("TestERC20", "TE20");
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "./dependencies/Ownable.sol";
import "./dependencies/RenderingContract.sol";
import "./dependencies/IERC4906.sol";
contract TestERC721 is ERC721Upgradeable, Ownable, RenderingContract, IERC4906 {
constructor(string memory _name, string memory _symbol) public {
__ERC721_init(_name, _symbol);
_setupOwner(msg.sender);
}
function mint(address to, uint tokenId) external {
_mint(to, tokenId);
}
function setBaseURI(string calldata uri) external {
}
function reveal(uint256 _index) external {
emit TokenURIRevealed(_index, "test");
}
function getBatchIdAtIndex(uint256 _index) external view returns (uint256) {
return 10;
}
function _canSetOwner() internal virtual view override returns (bool) {
return msg.sender == owner();
}
function mintWithPrice(address to, uint[] memory tokenIds, address currency, uint256 pricePerToken) external {
for (uint i = 0; i < tokenIds.length; i++) {
_mint(to, tokenIds[i]);
}
IERC20Upgradeable(currency).transferFrom(msg.sender, owner(), pricePerToken * tokenIds.length);
}
function updateMetaData(uint256 _tokenId) external {
emit MetadataUpdate(_tokenId);
}
function updateBatchMetaData(uint256 _fromTokenId, uint256 _toTokenId) external {
emit BatchMetadataUpdate(_fromTokenId, _toTokenId);
}
event TokenURIRevealed(uint256 indexed index, string revealedURI);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.7.6;
/// @title ERC-721 Metadata Update Extension
interface IERC4906 {
/// @dev This event emits when the metadata of a token is changed.
/// So that the third-party platforms such as NFT market could
/// timely update the images and related attributes of the NFT.
event MetadataUpdate(uint256 _tokenId);
/// @dev This event emits when the metadata of a range of tokens is changed.
/// So that the third-party platforms such as NFT market could
/// timely update the images and related attributes of the NFTs.
event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.7.6;
/// @author thirdweb
/**
* Thirdweb's `Ownable` is a contract extension to be used with any base contract. It exposes functions for setting and reading
* who the 'owner' of the inheriting smart contract is, and lets the inheriting contract perform conditional logic that uses
* information about who the contract's owner is.
*/
interface IOwnable {
/// @dev Returns the owner of the contract.
function owner() external view returns (address);
/// @dev Lets a module admin set a new owner for the contract. The new owner must be a module admin.
function setOwner(address _newOwner) external;
/// @dev Emitted when a new Owner is set.
event OwnerUpdated(address indexed prevOwner, address indexed newOwner);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.6;
/// @author thirdweb
import "./IOwnable.sol";
/**
* @title Ownable
* @notice Thirdweb's `Ownable` is a contract extension to be used with any base contract. It exposes functions for setting and reading
* who the 'owner' of the inheriting smart contract is, and lets the inheriting contract perform conditional logic that uses
* information about who the contract's owner is.
*/
abstract contract Ownable is IOwnable {
/// @dev Owner of the contract (purpose: OpenSea compatibility)
address private _owner;
/// @dev Reverts if caller is not the owner.
modifier onlyOwner() {
if (msg.sender != _owner) {
revert("unauthorized");
}
_;
}
/**
* @notice Returns the owner of the contract.
*/
function owner() public view override returns (address) {
return _owner;
}
/**
* @notice Lets an authorized wallet set a new owner for the contract.
* @param _newOwner The address to set as the new owner of the contract.
*/
function setOwner(address _newOwner) external override {
if (!_canSetOwner()) {
revert("unauthorized");
}
_setupOwner(_newOwner);
}
/// @dev Lets a contract admin set a new owner for the contract. The new owner must be a contract admin.
function _setupOwner(address _newOwner) internal {
address _prevOwner = _owner;
_owner = _newOwner;
emit OwnerUpdated(_prevOwner, _newOwner);
}
/// @dev Returns whether owner can be set in the given execution context.
function _canSetOwner() internal view virtual returns (bool);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.7.6;
interface ITokenURIGenerator {
function tokenURI(uint tokenId) external view returns (string memory);
}
abstract contract RenderingContract {
ITokenURIGenerator public renderingContract;
function setRenderingContract(ITokenURIGenerator _contract) external {
renderingContract = _contract;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol";
abstract contract HasContractURI is ERC165Upgradeable {
string public contractURI;
/*
* bytes4(keccak256('contractURI()')) == 0xe8a3d485
*/
bytes4 private constant _INTERFACE_ID_CONTRACT_URI = 0xe8a3d485;
function __HasContractURI_init_unchained(string memory _contractURI) internal initializer {
contractURI = _contractURI;
_registerInterface(_INTERFACE_ID_CONTRACT_URI);
}
/**
* @dev Internal function to set the contract URI
* @param _contractURI string URI prefix to assign
*/
function _setContractURI(string memory _contractURI) internal {
contractURI = _contractURI;
}
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
contract IsPrivateCollection {
/// @dev true if collection is private, false if public
bool isPrivate;
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
library LibURI {
/// @dev checks if _tokenURI starts with base. if true returns _tokenURI, else base + _tokenURI
function checkPrefix(string memory base, string memory _tokenURI)
internal
pure
returns (string memory)
{
bytes memory whatBytes = bytes(base);
bytes memory whereBytes = bytes(_tokenURI);
if (whatBytes.length > whereBytes.length) {
return string(abi.encodePacked(base, _tokenURI));
}
for (uint256 j = 0; j < whatBytes.length; j++) {
if (whereBytes[j] != whatBytes[j]) {
return string(abi.encodePacked(base, _tokenURI));
}
}
return _tokenURI;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "./erc-1271/ERC1271Validator.sol";
import "@rarible/lazy-mint/contracts/erc-721/LibERC721LazyMint.sol";
contract Mint721Validator is ERC1271Validator {
function __Mint721Validator_init_unchained() internal initializer {
__EIP712_init_unchained("Mint721", "1");
}
function validate(address account, bytes32 hash, bytes memory signature) internal view {
validate1271(account, hash, signature);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
abstract contract MinterAccessControl is OwnableUpgradeable {
mapping(address => bool) private _minters;
event MinterStatusChanged(address indexed minter, bool indexed status);
function __MinterAccessControl_init() internal initializer {
__Ownable_init_unchained();
__MinterAccessControl_init_unchained();
}
function __MinterAccessControl_init_unchained() internal initializer {
}
/**
* @dev Add `minter` to the list of allowed minters.
*/
function addMinter(address minter) external onlyOwner {
_minters[minter] = true;
emit MinterStatusChanged(minter, true);
}
/**
* @dev Add `minters` to the list of allowed minters.
*/
function addMinters(address[] memory minters) external onlyOwner {
for (uint i = 0; i < minters.length; ++i) {
address minter = minters[i];
_minters[minter] = true;
emit MinterStatusChanged(minter, true);
}
}
/**
* @dev Revoke `_minter` from the list of allowed minters.
*/
function removeMinter(address _minter) external onlyOwner {
_minters[_minter] = false;
emit MinterStatusChanged(_minter, false);
}
/**
* @dev Returns `true` if `account` has been granted to minters.
*/
function isMinter(address account) public view returns (bool) {
return _minters[account];
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "@openzeppelin/contracts/proxy/UpgradeableBeacon.sol";
contract ERC1155RaribleBeacon is UpgradeableBeacon {
constructor(address impl) UpgradeableBeacon(impl) {
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "@openzeppelin/contracts/proxy/UpgradeableBeacon.sol";
contract ERC1155RaribleBeaconMeta is UpgradeableBeacon {
constructor(address impl) UpgradeableBeacon(impl) {
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "@openzeppelin/contracts/proxy/UpgradeableBeacon.sol";
contract ERC721RaribleBeacon is UpgradeableBeacon {
constructor(address impl) UpgradeableBeacon(impl) {
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "@openzeppelin/contracts/proxy/UpgradeableBeacon.sol";
contract ERC721RaribleMinimalBeacon is UpgradeableBeacon {
constructor(address impl) UpgradeableBeacon(impl) {
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "@openzeppelin/contracts/proxy/UpgradeableBeacon.sol";
contract ERC721RaribleMinimalBeaconMeta is UpgradeableBeacon {
constructor(address impl) UpgradeableBeacon(impl) {
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "../erc-1155/ERC1155Rarible.sol";
import "@openzeppelin/contracts/proxy/BeaconProxy.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @dev This contract is for creating proxy to access ERC1155Rarible token.
*
* The beacon should be initialized before call ERC1155RaribleFactoryC2 constructor.
*
*/
contract ERC1155RaribleFactoryC2 is Ownable{
address public beacon;
address transferProxy;
address lazyTransferProxy;
event Create1155RaribleProxy(address proxy);
event Create1155RaribleUserProxy(address proxy);
constructor(address _beacon, address _transferProxy, address _lazyTransferProxy) {
beacon = _beacon;
transferProxy = _transferProxy;
lazyTransferProxy = _lazyTransferProxy;
}
function createToken(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, uint salt) external {
address beaconProxy = deployProxy(getData(_name, _symbol, baseURI, contractURI), salt);
ERC1155Rarible token = ERC1155Rarible(beaconProxy);
token.transferOwnership(_msgSender());
emit Create1155RaribleProxy(beaconProxy);
}
function createToken(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address[] memory operators, uint salt) external {
address beaconProxy = deployProxy(getData(_name, _symbol, baseURI, contractURI, operators), salt);
ERC1155Rarible token = ERC1155Rarible(address(beaconProxy));
token.transferOwnership(_msgSender());
emit Create1155RaribleUserProxy(beaconProxy);
}
//deploying BeaconProxy contract with create2
function deployProxy(bytes memory data, uint salt) internal returns(address proxy){
bytes memory bytecode = getCreationBytecode(data);
assembly {
proxy := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
if iszero(extcodesize(proxy)) {
revert(0, 0)
}
}
}
//adding constructor arguments to BeaconProxy bytecode
function getCreationBytecode(bytes memory _data) internal view returns (bytes memory) {
return abi.encodePacked(type(BeaconProxy).creationCode, abi.encode(beacon, _data));
}
//returns address that contract with such arguments will be deployed on
function getAddress(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, uint _salt)
public
view
returns (address)
{
bytes memory bytecode = getCreationBytecode(getData(_name, _symbol, baseURI, contractURI));
bytes32 hash = keccak256(
abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode))
);
return address(uint160(uint(hash)));
}
function getData(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI) view internal returns(bytes memory){
return abi.encodeWithSelector(ERC1155Rarible(0).__ERC1155Rarible_init.selector, _name, _symbol, baseURI, contractURI, transferProxy, lazyTransferProxy);
}
//returns address that contract with such arguments will be deployed on
function getAddress(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address[] memory operators, uint _salt)
public
view
returns (address)
{
bytes memory bytecode = getCreationBytecode(getData(_name, _symbol, baseURI, contractURI, operators));
bytes32 hash = keccak256(
abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode))
);
return address(uint160(uint(hash)));
}
function getData(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address[] memory operators) view internal returns(bytes memory){
return abi.encodeWithSelector(ERC1155Rarible(0).__ERC1155RaribleUser_init.selector, _name, _symbol, baseURI, contractURI, operators, transferProxy, lazyTransferProxy);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
pragma abicoder v2;
import "../erc-721-minimal/ERC721RaribleMinimal.sol";
import "@openzeppelin/contracts/proxy/BeaconProxy.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @dev This contract is for creating proxy to access ERC721Rarible token.
*
* The beacon should be initialized before call ERC721RaribleFactoryC2 constructor.
*
*/
contract ERC721RaribleFactoryC2 is Ownable {
address public beacon;
address transferProxy;
address lazyTransferProxy;
event Create721RaribleProxy(address proxy);
event Create721RaribleUserProxy(address proxy);
constructor(address _beacon, address _transferProxy, address _lazyTransferProxy) {
beacon = _beacon;
transferProxy = _transferProxy;
lazyTransferProxy = _lazyTransferProxy;
}
function createToken(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, uint salt) external {
address beaconProxy = deployProxy(getData(_name, _symbol, baseURI, contractURI), salt);
ERC721RaribleMinimal token = ERC721RaribleMinimal(address(beaconProxy));
token.transferOwnership(_msgSender());
emit Create721RaribleProxy(beaconProxy);
}
function createToken(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address[] memory operators, uint salt) external {
address beaconProxy = deployProxy(getData(_name, _symbol, baseURI, contractURI, operators), salt);
ERC721RaribleMinimal token = ERC721RaribleMinimal(address(beaconProxy));
token.transferOwnership(_msgSender());
emit Create721RaribleUserProxy(beaconProxy);
}
//deploying BeaconProxy contract with create2
function deployProxy(bytes memory data, uint salt) internal returns(address proxy){
bytes memory bytecode = getCreationBytecode(data);
assembly {
proxy := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
if iszero(extcodesize(proxy)) {
revert(0, 0)
}
}
}
//adding constructor arguments to BeaconProxy bytecode
function getCreationBytecode(bytes memory _data) internal view returns (bytes memory) {
return abi.encodePacked(type(BeaconProxy).creationCode, abi.encode(beacon, _data));
}
//returns address that contract with such arguments will be deployed on
function getAddress(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, uint _salt)
public
view
returns (address)
{
bytes memory bytecode = getCreationBytecode(getData(_name, _symbol, baseURI, contractURI));
bytes32 hash = keccak256(
abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode))
);
return address(uint160(uint(hash)));
}
function getData(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI) view internal returns(bytes memory){
return abi.encodeWithSelector(ERC721RaribleMinimal(0).__ERC721Rarible_init.selector, _name, _symbol, baseURI, contractURI, transferProxy, lazyTransferProxy);
}
//returns address that private contract with such arguments will be deployed on
function getAddress(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address[] memory operators, uint _salt)
public
view
returns (address)
{
bytes memory bytecode = getCreationBytecode(getData(_name, _symbol, baseURI, contractURI, operators));
bytes32 hash = keccak256(
abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode))
);
return address(uint160(uint(hash)));
}
function getData(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address[] memory operators) view internal returns(bytes memory){
return abi.encodeWithSelector(ERC721RaribleMinimal(0).__ERC721RaribleUser_init.selector, _name, _symbol, baseURI, contractURI, operators, transferProxy, lazyTransferProxy);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "./ERC1155BurnableUpgradeable.sol";
import "./ERC1155DefaultApproval.sol";
import "./ERC1155Lazy.sol";
import "../HasContractURI.sol";
abstract contract ERC1155Base is OwnableUpgradeable, ERC1155DefaultApproval, ERC1155BurnableUpgradeable, ERC1155Lazy, HasContractURI {
string public name;
string public symbol;
event BurnLazy(address indexed operator, address indexed account, uint256 id, uint256 amount);
event BurnLazyBatch(address indexed operator, address indexed account, uint256[] ids, uint256[] amounts);
event BaseUriChanged(string newBaseURI);
function isApprovedForAll(address _owner, address _operator) public override(ERC1155Upgradeable, ERC1155DefaultApproval, IERC1155Upgradeable) view returns (bool) {
return ERC1155DefaultApproval.isApprovedForAll(_owner, _operator);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155Lazy, ERC165Upgradeable) returns (bool) {
return super.supportsInterface(interfaceId);
}
function burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) public virtual override {
require(ids.length == amounts.length, "ids != amounts");
uint256[] memory leftToBurns = new uint256[](ids.length);
uint256[] memory lazyToBurns = new uint256[](ids.length);
for (uint i = 0; i < ids.length; ++i) {
(leftToBurns[i], lazyToBurns[i]) = _burnLazy(ids[i], amounts[i]);
}
ERC1155BurnableUpgradeable.burnBatch(account, ids, leftToBurns);
emit BurnLazyBatch(_msgSender(), account, ids, lazyToBurns);
}
function burn(address account, uint256 id, uint256 amount) public virtual override {
(uint256 leftToBurn, uint256 lazyToBurn) = _burnLazy(id, amount);
if (leftToBurn > 0) {
//token exists, burn Minted
ERC1155BurnableUpgradeable.burn(account, id, leftToBurn);
}
if (lazyToBurn > 0) {
emit BurnLazy(_msgSender(), account, id, lazyToBurn);
}
}
function _burnLazy(uint256 id, uint256 amount) internal returns (uint256 leftToBurn, uint256 lazyToBurn) {
leftToBurn = amount;
lazyToBurn = 0;
address creator = address(id >> 96);
if (creator == _msgSender()) {
lazyToBurn = amount;
uint supply = ERC1155Lazy._getSupply(id);
if (supply != 0) {
//calculate Lazy amount available for burn
uint256 lazyBalance = supply - ERC1155Lazy._getMinted(id);
if (amount > lazyBalance) {//need to burn more than available
lazyToBurn = lazyBalance;
}
}
ERC1155Lazy._addMinted(id, lazyToBurn);
leftToBurn = amount - lazyToBurn;
}
}
function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual override(ERC1155Upgradeable, ERC1155Lazy) {
ERC1155Lazy._mint(account, id, amount, data);
}
function __ERC1155Base_init_unchained(string memory _name, string memory _symbol) internal {
name = _name;
symbol = _symbol;
}
function uri(uint id) external view override(ERC1155BaseURI, ERC1155Upgradeable) virtual returns (string memory) {
return _tokenURI(id);
}
function setBaseURI(string memory newBaseURI) external onlyOwner {
super._setBaseURI(newBaseURI);
emit BaseUriChanged(newBaseURI);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol";
import "../LibURI.sol";
import "./ERC1155Upgradeable.sol";
contract ERC1155BaseURI is ERC1155Upgradeable {
using StringsUpgradeable for uint;
// Optional mapping for token URIs
mapping (uint256 => string) private _tokenURIs;
// Base URI
string private _baseURI;
/**
* @dev Returns the base URI set via {_setBaseURI}. This will be
* automatically added as a prefix in {tokenURI} to each token's URI, or
* to the token ID if no specific URI is set for that token ID.
*/
function baseURI() public view virtual returns (string memory) {
return _baseURI;
}
function uri(uint id) external view override virtual returns (string memory) {
return _tokenURI(id);
}
function _tokenURI(uint256 tokenId) internal view virtual returns (string memory) {
string memory __tokenURI = _tokenURIs[tokenId];
string memory base = baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return __tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(__tokenURI).length > 0) {
return LibURI.checkPrefix(base, __tokenURI);
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(base, tokenId.toString()));
}
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _setTokenURI(uint256 tokenId, string memory _uri) internal virtual {
_tokenURIs[tokenId] = _uri;
emit URI(_tokenURI(tokenId), tokenId);
}
/**
* @dev Internal function to set the base URI for all token IDs. It is
* automatically added as a prefix to the value returned in {tokenURI},
* or to the token ID if {tokenURI} is empty.
*/
function _setBaseURI(string memory baseURI_) internal virtual {
_baseURI = baseURI_;
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./ERC1155Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
/**
* @dev Extension of {ERC1155} that allows token holders to destroy both their
* own tokens and those that they have been approved to use.
*
* _Available since v3.1._
*/
abstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {
function __ERC1155Burnable_init() internal {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155Burnable_init_unchained();
}
function __ERC1155Burnable_init_unchained() internal {
}
function burn(address account, uint256 id, uint256 value) public virtual {
require(
account == _msgSender() || isApprovedForAll(account, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_burn(account, id, value);
}
function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {
require(
account == _msgSender() || isApprovedForAll(account, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_burnBatch(account, ids, values);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "./ERC1155Upgradeable.sol";
abstract contract ERC1155DefaultApproval is ERC1155Upgradeable {
mapping(address => bool) private defaultApprovals;
event DefaultApproval(address indexed operator, bool hasApproval);
function _setDefaultApproval(address operator, bool hasApproval) internal {
defaultApprovals[operator] = hasApproval;
emit DefaultApproval(operator, hasApproval);
}
function isApprovedForAll(address _owner, address _operator) public virtual override view returns (bool) {
return defaultApprovals[_operator] || super.isApprovedForAll(_owner, _operator);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "./ERC1155Upgradeable.sol";
import "@rarible/royalties/contracts/impl/RoyaltiesV2Impl.sol";
import "@rarible/royalties-upgradeable/contracts/RoyaltiesV2Upgradeable.sol";
import "@rarible/lazy-mint/contracts/erc-1155/IERC1155LazyMint.sol";
import "./Mint1155Validator.sol";
import "./ERC1155BaseURI.sol";
abstract contract ERC1155Lazy is IERC1155LazyMint, ERC1155BaseURI, Mint1155Validator, RoyaltiesV2Upgradeable, RoyaltiesV2Impl {
using SafeMathUpgradeable for uint;
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;
bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;
mapping(uint256 => LibPart.Part[]) private creators;
mapping(uint => uint) private supply;
mapping(uint => uint) private minted;
function __ERC1155Lazy_init_unchained() internal {
}
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {
return interfaceId == LibERC1155LazyMint._INTERFACE_ID_MINT_AND_TRANSFER
|| interfaceId == LibRoyaltiesV2._INTERFACE_ID_ROYALTIES
|| interfaceId == LibRoyalties2981._INTERFACE_ID_ROYALTIES
|| interfaceId == _INTERFACE_ID_ERC165
|| interfaceId == _INTERFACE_ID_ERC1155
|| interfaceId == _INTERFACE_ID_ERC1155_METADATA_URI;
}
function transferFromOrMint(
LibERC1155LazyMint.Mint1155Data memory data,
address from,
address to,
uint256 amount
) override external {
uint balance = balanceOf(from, data.tokenId);
uint left = amount;
if (balance != 0) {
uint transfer = amount;
if (balance < amount) {
transfer = balance;
}
safeTransferFrom(from, to, data.tokenId, transfer, "");
left = amount - transfer;
}
if (left > 0) {
require(from == data.creators[0].account, "wrong order maker");
mintAndTransfer(data, to, left);
}
}
function mintAndTransfer(LibERC1155LazyMint.Mint1155Data memory data, address to, uint256 _amount) public override virtual {
address minter = address(data.tokenId >> 96);
address sender = _msgSender();
require(minter == sender || isApprovedForAll(minter, sender), "ERC1155: transfer caller is not approved");
require(_amount > 0, "amount incorrect");
if (supply[data.tokenId] == 0) {
require(minter == data.creators[0].account, "tokenId incorrect");
require(data.supply > 0, "supply incorrect");
require(data.creators.length == data.signatures.length);
bytes32 hash = LibERC1155LazyMint.hash(data);
for (uint i = 0; i < data.creators.length; ++i) {
address creator = data.creators[i].account;
if (creator != sender) {
validate(creator, hash, data.signatures[i]);
}
}
_saveSupply(data.tokenId, data.supply);
_saveRoyalties(data.tokenId, data.royalties);
_saveCreators(data.tokenId, data.creators);
_setTokenURI(data.tokenId, data.tokenURI);
}
_mint(to, data.tokenId, _amount, "");
if (minter != to) {
emit TransferSingle(sender, address(0), minter, data.tokenId, _amount);
emit TransferSingle(sender, minter, to, data.tokenId, _amount);
} else {
emit TransferSingle(sender, address(0), to, data.tokenId, _amount);
}
}
function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual override {
uint newMinted = amount.add(minted[id]);
require(newMinted <= supply[id], "more than supply");
minted[id] = newMinted;
require(account != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][account] = _balances[id][account].add(amount);
_doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
}
function _saveSupply(uint tokenId, uint _supply) internal {
require(supply[tokenId] == 0);
supply[tokenId] = _supply;
emit Supply(tokenId, _supply);
}
function _saveCreators(uint tokenId, LibPart.Part[] memory _creators) internal {
LibPart.Part[] storage creatorsOfToken = creators[tokenId];
uint total = 0;
for (uint i = 0; i < _creators.length; ++i) {
require(_creators[i].account != address(0x0), "Account should be present");
require(_creators[i].value != 0, "Creator share should be positive");
creatorsOfToken.push(_creators[i]);
total = total.add(_creators[i].value);
}
require(total == 10000, "total amount of creators share should be 10000");
emit Creators(tokenId, _creators);
}
function updateAccount(uint256 _id, address _from, address _to) external {
require(_msgSender() == _from, "not allowed");
super._updateAccount(_id, _from, _to);
}
function getCreators(uint256 _id) external view returns (LibPart.Part[] memory) {
return creators[_id];
}
function _addMinted(uint256 tokenId, uint amount) internal {
minted[tokenId] += amount;
}
function _getMinted(uint256 tokenId) internal view returns (uint) {
return minted[tokenId];
}
function _getSupply(uint256 tokenId) internal view returns (uint) {
return supply[tokenId];
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "./ERC1155Base.sol";
import "../IsPrivateCollection.sol";
import "../access/MinterAccessControl.sol";
contract ERC1155Rarible is ERC1155Base, IsPrivateCollection, MinterAccessControl {
event CreateERC1155Rarible(address owner, string name, string symbol);
event CreateERC1155RaribleUser(address owner, string name, string symbol);
function __ERC1155RaribleUser_init(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address[] memory operators, address transferProxy, address lazyTransferProxy) external virtual {
__ERC1155Rarible_init_unchained(_name, _symbol, baseURI, contractURI, transferProxy, lazyTransferProxy);
isPrivate = true;
emit CreateERC1155RaribleUser(_msgSender(), _name, _symbol);
}
function __ERC1155Rarible_init(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address transferProxy, address lazyTransferProxy) external virtual {
__ERC1155Rarible_init_unchained(_name, _symbol, baseURI, contractURI, transferProxy, lazyTransferProxy);
isPrivate = false;
emit CreateERC1155Rarible(_msgSender(), _name, _symbol);
}
function __ERC1155Rarible_init_unchained(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address transferProxy, address lazyTransferProxy) internal initializer {
__Ownable_init_unchained();
__ERC1155Lazy_init_unchained();
__ERC165_init_unchained();
__Context_init_unchained();
__Mint1155Validator_init_unchained();
__ERC1155_init_unchained("");
__HasContractURI_init_unchained(contractURI);
__ERC1155Burnable_init_unchained();
__RoyaltiesV2Upgradeable_init_unchained();
__ERC1155Base_init_unchained(_name, _symbol);
__MinterAccessControl_init_unchained();
_setBaseURI(baseURI);
//setting default approver for transferProxies
_setDefaultApproval(transferProxy, true);
_setDefaultApproval(lazyTransferProxy, true);
}
function mintAndTransfer(LibERC1155LazyMint.Mint1155Data memory data, address to, uint256 _amount) public override {
if (isPrivate){
require(owner() == data.creators[0].account || isMinter(data.creators[0].account), "not owner or minter");
}
super.mintAndTransfer(data, to, _amount);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155MetadataURIUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155ReceiverUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
/**
*
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/
contract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {
using SafeMathUpgradeable for uint256;
using AddressUpgradeable for address;
// Mapping from token ID to account balances
mapping (uint256 => mapping(address => uint256)) internal _balances;
// Mapping from account to operator approvals
mapping (address => mapping(address => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/*
* bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
* bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a
* bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6
*
* => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^
* 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26
*/
bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;
/*
* bytes4(keccak256('uri(uint256)')) == 0x0e89341c
*/
bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;
/**
* @dev See {_setURI}.
*/
function __ERC1155_init(string memory uri_) internal initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC1155_init_unchained(uri_);
}
function __ERC1155_init_unchained(string memory uri_) internal initializer {
_setURI(uri_);
// register the supported interfaces to conform to ERC1155 via ERC165
_registerInterface(_INTERFACE_ID_ERC1155);
// register the supported interfaces to conform to ERC1155MetadataURI via ERC165
_registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256) external view virtual override returns (string memory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: balance query for the zero address");
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(
address[] memory accounts,
uint256[] memory ids
)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
require(_msgSender() != operator, "ERC1155: setting approval status for self");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
)
public
virtual
override
{
require(to != address(0), "ERC1155: transfer to the zero address");
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][from] = _balances[id][from].sub(amount, "ERC1155: insufficient balance for transfer");
_balances[id][to] = _balances[id][to].add(amount);
emit TransferSingle(operator, from, to, id, amount);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
)
public
virtual
override
{
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: transfer caller is not owner nor approved"
);
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
_balances[id][from] = _balances[id][from].sub(
amount,
"ERC1155: insufficient balance for transfer"
);
_balances[id][to] = _balances[id][to].add(amount);
}
emit TransferBatch(operator, from, to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {
require(account != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][account] = _balances[id][account].add(amount);
emit TransferSingle(operator, address(0), account, id, amount);
_doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint i = 0; i < ids.length; ++i) {
_balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `account`
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens of token type `id`.
*/
function _burn(address account, uint256 id, uint256 amount) internal virtual {
require(account != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
_balances[id][account] = _balances[id][account].sub(
amount,
"ERC1155: burn amount exceeds balance"
);
emit TransferSingle(operator, account, address(0), id, amount);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/
function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {
require(account != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
for (uint i = 0; i < ids.length; ++i) {
_balances[ids[i]][account] = _balances[ids[i]][account].sub(
amounts[i],
"ERC1155: burn amount exceeds balance"
);
}
emit TransferBatch(operator, account, address(0), ids, amounts);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
)
internal
virtual
{ }
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
)
internal
{
if (to.isContract()) {
try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155ReceiverUpgradeable(to).onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
)
private
{
if (to.isContract()) {
try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {
if (response != IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) internal pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
uint256[47] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "../erc-1271/ERC1271Validator.sol";
import "@rarible/lazy-mint/contracts/erc-1155/LibERC1155LazyMint.sol";
contract Mint1155Validator is ERC1271Validator {
function __Mint1155Validator_init_unchained() internal initializer {
__EIP712_init_unchained("Mint1155", "1");
}
function validate(address account, bytes32 hash, bytes memory signature) internal view {
validate1271(account, hash, signature);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/meta-tx/contracts/EIP712MetaTransaction.sol";
import "../ERC1155Base.sol";
import "../../IsPrivateCollection.sol";
import "../../access/MinterAccessControl.sol";
contract ERC1155RaribleMeta is ERC1155Base, IsPrivateCollection, MinterAccessControl, EIP712MetaTransaction {
event CreateERC1155Rarible(address owner, string name, string symbol);
event CreateERC1155RaribleUser(address owner, string name, string symbol);
function __ERC1155RaribleUser_init(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address[] memory operators, address transferProxy, address lazyTransferProxy) external {
__ERC1155Rarible_init_unchained(_name, _symbol, baseURI, contractURI, transferProxy, lazyTransferProxy);
__MetaTransaction_init_unchained("ERC1155RaribleUserMeta", "1");
isPrivate = true;
emit CreateERC1155RaribleUser(_msgSender(), _name, _symbol);
}
function __ERC1155Rarible_init(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address transferProxy, address lazyTransferProxy) external {
__ERC1155Rarible_init_unchained(_name, _symbol, baseURI, contractURI, transferProxy, lazyTransferProxy);
__MetaTransaction_init_unchained("ERC1155RaribleMeta", "1");
isPrivate = false;
emit CreateERC1155Rarible(_msgSender(), _name, _symbol);
}
function _msgSender() internal view virtual override(ContextUpgradeable, EIP712MetaTransaction) returns (address payable) {
return super._msgSender();
}
function __ERC1155Rarible_init_unchained(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address transferProxy, address lazyTransferProxy) internal initializer {
__Ownable_init_unchained();
__ERC1155Lazy_init_unchained();
__ERC165_init_unchained();
__Context_init_unchained();
__Mint1155Validator_init_unchained();
__ERC1155_init_unchained("");
__HasContractURI_init_unchained(contractURI);
__ERC1155Burnable_init_unchained();
__RoyaltiesV2Upgradeable_init_unchained();
__ERC1155Base_init_unchained(_name, _symbol);
__MinterAccessControl_init_unchained();
_setBaseURI(baseURI);
//setting default approver for transferProxies
_setDefaultApproval(transferProxy, true);
_setDefaultApproval(lazyTransferProxy, true);
}
function mintAndTransfer(LibERC1155LazyMint.Mint1155Data memory data, address to, uint256 _amount) public override {
if (isPrivate){
require(owner() == data.creators[0].account || isMinter(data.creators[0].account), "not owner or minter");
}
super.mintAndTransfer(data, to, _amount);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@rarible/lib-signature/contracts/ERC1271.sol";
import "@openzeppelin/contracts-upgradeable/drafts/EIP712Upgradeable.sol";
import "@rarible/lib-signature/contracts/LibSignature.sol";
abstract contract ERC1271Validator is EIP712Upgradeable {
using AddressUpgradeable for address;
using LibSignature for bytes32;
string constant SIGNATURE_ERROR = "signature verification error";
bytes4 constant internal MAGICVALUE = 0x1626ba7e;
function validate1271(address signer, bytes32 structHash, bytes memory signature) internal view {
bytes32 hash = _hashTypedDataV4(structHash);
address signerFromSig;
if (signature.length == 65) {
signerFromSig = hash.recover(signature);
}
if (signerFromSig != signer) {
if (signer.isContract()) {
require(
ERC1271(signer).isValidSignature(hash, signature) == MAGICVALUE,
SIGNATURE_ERROR
);
} else {
revert(SIGNATURE_ERROR);
}
}
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "./ERC721BurnableUpgradeableMinimal.sol";
import "./ERC721DefaultApprovalMinimal.sol";
import "./ERC721LazyMinimal.sol";
import "../HasContractURI.sol";
abstract contract ERC721BaseMinimal is OwnableUpgradeable, ERC721DefaultApprovalMinimal, ERC721BurnableUpgradeableMinimal, ERC721LazyMinimal, HasContractURI {
event BaseUriChanged(string newBaseURI);
function _isApprovedOrOwner(address spender, uint256 tokenId) internal virtual override(ERC721UpgradeableMinimal, ERC721DefaultApprovalMinimal) view returns (bool) {
return ERC721DefaultApprovalMinimal._isApprovedOrOwner(spender, tokenId);
}
function isApprovedForAll(address owner, address operator) public view virtual override(ERC721DefaultApprovalMinimal, ERC721UpgradeableMinimal, IERC721Upgradeable) returns (bool) {
return ERC721DefaultApprovalMinimal.isApprovedForAll(owner, operator);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, ERC721LazyMinimal) returns (bool) {
return super.supportsInterface(interfaceId);
}
function tokenURI(uint256 tokenId) public view virtual override(ERC721UpgradeableMinimal, ERC721LazyMinimal) returns (string memory) {
return ERC721LazyMinimal.tokenURI(tokenId);
}
function _clearMetadata(uint256 tokenId) internal override(ERC721UpgradeableMinimal, ERC721LazyMinimal) virtual {
return ERC721LazyMinimal._clearMetadata(tokenId);
}
function _emitMintEvent(address to, uint tokenId) internal override(ERC721UpgradeableMinimal, ERC721LazyMinimal) virtual {
return ERC721LazyMinimal._emitMintEvent(to, tokenId);
}
function setBaseURI(string memory newBaseURI) external onlyOwner {
super._setBaseURI(newBaseURI);
emit BaseUriChanged(newBaseURI);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import "./ERC721UpgradeableMinimal.sol";
/**
* @title ERC721 Burnable Token
* @dev ERC721 Token that can be irreversibly burned (destroyed).
*/
abstract contract ERC721BurnableUpgradeableMinimal is Initializable, ContextUpgradeable, ERC721UpgradeableMinimal {
function __ERC721Burnable_init() internal initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721Burnable_init_unchained();
}
function __ERC721Burnable_init_unchained() internal initializer {
}
/**
* @dev Burns `tokenId`. See {ERC721-_burn}.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function burn(uint256 tokenId) public virtual {
if(!_exists(tokenId)) {
address owner = address(tokenId >> 96);
require(owner == _msgSender(), "ERC721Burnable: caller is not owner, not burn");
_setBurned(tokenId);
} else {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
_burn(tokenId);
}
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "./ERC721UpgradeableMinimal.sol";
abstract contract ERC721DefaultApprovalMinimal is ERC721UpgradeableMinimal {
mapping(address => bool) private defaultApprovals;
event DefaultApproval(address indexed operator, bool hasApproval);
function _setDefaultApproval(address operator, bool hasApproval) internal {
defaultApprovals[operator] = hasApproval;
emit DefaultApproval(operator, hasApproval);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal virtual override view returns (bool) {
return defaultApprovals[spender] || super._isApprovedOrOwner(spender, tokenId);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return defaultApprovals[operator] || super.isApprovedForAll(owner, operator);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "./ERC721UpgradeableMinimal.sol";
import "@rarible/royalties/contracts/impl/RoyaltiesV2Impl.sol";
import "@rarible/royalties-upgradeable/contracts/RoyaltiesV2Upgradeable.sol";
import "@rarible/lazy-mint/contracts/erc-721/IERC721LazyMint.sol";
import "../Mint721Validator.sol";
import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
import "./ERC721URI.sol";
abstract contract ERC721LazyMinimal is IERC721LazyMint, ERC721UpgradeableMinimal, Mint721Validator, RoyaltiesV2Upgradeable, RoyaltiesV2Impl, ERC721URI {
using SafeMathUpgradeable for uint;
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
// tokenId => creators
mapping(uint256 => LibPart.Part[]) private creators;
function __ERC721Lazy_init_unchained() internal initializer {
}
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {
return interfaceId == LibERC721LazyMint._INTERFACE_ID_MINT_AND_TRANSFER
|| interfaceId == LibRoyaltiesV2._INTERFACE_ID_ROYALTIES
|| interfaceId == LibRoyalties2981._INTERFACE_ID_ROYALTIES
|| interfaceId == _INTERFACE_ID_ERC165
|| interfaceId == _INTERFACE_ID_ERC721
|| interfaceId == _INTERFACE_ID_ERC721_METADATA
|| interfaceId == _INTERFACE_ID_ERC721_ENUMERABLE;
}
function transferFromOrMint(
LibERC721LazyMint.Mint721Data memory data,
address from,
address to
) override external {
if (_exists(data.tokenId)) {
safeTransferFrom(from, to, data.tokenId);
} else {
require(from == data.creators[0].account, "wrong order maker");
mintAndTransfer(data, to);
}
}
function mintAndTransfer(LibERC721LazyMint.Mint721Data memory data, address to) public override virtual {
address minter = address(data.tokenId >> 96);
address sender = _msgSender();
require(minter == data.creators[0].account, "tokenId incorrect");
require(data.creators.length == data.signatures.length);
require(minter == sender || isApprovedForAll(minter, sender), "ERC721: transfer caller is not owner nor approved");
bytes32 hash = LibERC721LazyMint.hash(data);
for (uint i = 0; i < data.creators.length; ++i) {
address creator = data.creators[i].account;
if (creator != sender) {
validate(creator, hash, data.signatures[i]);
}
}
_safeMint(to, data.tokenId);
_saveRoyalties(data.tokenId, data.royalties);
_saveCreators(data.tokenId, data.creators);
_setTokenURI(data.tokenId, data.tokenURI);
}
function _emitMintEvent(address to, uint tokenId) internal override virtual {
address minter = address(tokenId >> 96);
if (minter != to) {
emit Transfer(address(0), minter, tokenId);
emit Transfer(minter, to, tokenId);
} else {
emit Transfer(address(0), to, tokenId);
}
}
function _saveCreators(uint tokenId, LibPart.Part[] memory _creators) internal {
LibPart.Part[] storage creatorsOfToken = creators[tokenId];
uint total = 0;
for (uint i = 0; i < _creators.length; ++i) {
require(_creators[i].account != address(0x0), "Account should be present");
require(_creators[i].value != 0, "Creator share should be positive");
creatorsOfToken.push(_creators[i]);
total = total.add(_creators[i].value);
}
require(total == 10000, "total amount of creators share should be 10000");
emit Creators(tokenId, _creators);
}
function updateAccount(uint256 _id, address _from, address _to) external {
require(_msgSender() == _from, "not allowed");
super._updateAccount(_id, _from, _to);
}
function getCreators(uint256 _id) external view returns (LibPart.Part[] memory) {
return creators[_id];
}
function tokenURI(uint256 tokenId) public view virtual override(ERC721UpgradeableMinimal, ERC721URI) returns (string memory) {
return ERC721URI.tokenURI(tokenId);
}
function _clearMetadata(uint256 tokenId) internal override(ERC721UpgradeableMinimal, ERC721URI) virtual {
return ERC721URI._clearMetadata(tokenId);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "./ERC721BaseMinimal.sol";
import "../IsPrivateCollection.sol";
import "../access/MinterAccessControl.sol";
contract ERC721RaribleMinimal is ERC721BaseMinimal, IsPrivateCollection, MinterAccessControl {
event CreateERC721Rarible(address owner, string name, string symbol);
event CreateERC721RaribleUser(address owner, string name, string symbol);
function __ERC721RaribleUser_init(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address[] memory operators, address transferProxy, address lazyTransferProxy) external virtual {
__ERC721Rarible_init_unchained(_name, _symbol, baseURI, contractURI, transferProxy, lazyTransferProxy);
isPrivate = true;
emit CreateERC721RaribleUser(_msgSender(), _name, _symbol);
}
function __ERC721Rarible_init(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address transferProxy, address lazyTransferProxy) external virtual {
__ERC721Rarible_init_unchained(_name, _symbol, baseURI, contractURI, transferProxy, lazyTransferProxy);
isPrivate = false;
emit CreateERC721Rarible(_msgSender(), _name, _symbol);
}
function __ERC721Rarible_init_unchained(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address transferProxy, address lazyTransferProxy) internal initializer {
_setBaseURI(baseURI);
__ERC721Lazy_init_unchained();
__RoyaltiesV2Upgradeable_init_unchained();
__Context_init_unchained();
__ERC165_init_unchained();
__Ownable_init_unchained();
__ERC721Burnable_init_unchained();
__Mint721Validator_init_unchained();
__MinterAccessControl_init_unchained();
__HasContractURI_init_unchained(contractURI);
__ERC721_init_unchained(_name, _symbol);
//setting default approver for transferProxies
_setDefaultApproval(transferProxy, true);
_setDefaultApproval(lazyTransferProxy, true);
}
function mintAndTransfer(LibERC721LazyMint.Mint721Data memory data, address to) public override virtual {
if (isPrivate){
require(owner() == data.creators[0].account || isMinter(data.creators[0].account), "not owner or minter");
}
super.mintAndTransfer(data, to);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import "./ERC721UpgradeableMinimal.sol";
import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol";
import "../LibURI.sol";
/**
* @title ERC721 Burnable Token
* @dev ERC721 Token that can be irreversibly burned (destroyed).
*/
abstract contract ERC721URI is ContextUpgradeable, ERC721UpgradeableMinimal {
using StringsUpgradeable for uint256;
// Optional mapping for token URIs
mapping (uint256 => string) private _tokenURIs;
// Base URI
string private _baseURI;
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
/**
* @dev Internal function to set the base URI for all token IDs. It is
* automatically added as a prefix to the value returned in {tokenURI},
* or to the token ID if {tokenURI} is empty.
*/
function _setBaseURI(string memory baseURI_) internal virtual {
_baseURI = baseURI_;
}
/**
* @dev Returns the base URI set via {_setBaseURI}. This will be
* automatically added as a prefix in {tokenURI} to each token's URI, or
* to the token ID if no specific URI is set for that token ID.
*/
function baseURI() public view virtual returns (string memory) {
return _baseURI;
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _clearMetadata(uint256 tokenId) internal override virtual {
// Clear metadata (if any)
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return LibURI.checkPrefix(base, _tokenURI);
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(base, tokenId.toString()));
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721MetadataUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol";
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721UpgradeableMinimal is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {
using AddressUpgradeable for address;
using StringsUpgradeable for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/*
* bytes4(keccak256('balanceOf(address)')) == 0x70a08231
* bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
* bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
* bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
*
* => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
* 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
*/
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
/*
* bytes4(keccak256('name()')) == 0x06fdde03
* bytes4(keccak256('symbol()')) == 0x95d89b41
* bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
*
* => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
*/
bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
// Mapping from token ID to flag == true, means token already burned
mapping(uint256 => bool) private _burnedTokens;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
function __ERC721_init(string memory name_, string memory symbol_) internal initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name_, symbol_);
}
function __ERC721_init_unchained(string memory name_, string memory symbol_) internal initializer {
_name = name_;
_symbol = symbol_;
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_INTERFACE_ID_ERC721);
_registerInterface(_INTERFACE_ID_ERC721_METADATA);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721UpgradeableMinimal.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
require(operator != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `_data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721UpgradeableMinimal.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_burnedTokens[tokenId], "token already burned");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
_emitMintEvent(to, tokenId);
}
function _emitMintEvent(address to, uint tokenId) internal virtual {
emit Transfer(address(0), to, tokenId);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721UpgradeableMinimal.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
_clearMetadata(tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
//set token is burned
_setBurned(tokenId);
emit Transfer(owner, address(0), tokenId);
}
/*Set token with tokenId burned*/
function _setBurned(uint256 tokenId) internal {
_burnedTokens[tokenId] = true;
}
function _clearMetadata(uint256 tokenId) internal virtual {
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721UpgradeableMinimal.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits a {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721UpgradeableMinimal.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
uint256[43] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/meta-tx/contracts/EIP712MetaTransaction.sol";
import "../ERC721BaseMinimal.sol";
import "../../IsPrivateCollection.sol";
import "../../access/MinterAccessControl.sol";
contract ERC721RaribleMeta is ERC721BaseMinimal, IsPrivateCollection, MinterAccessControl, EIP712MetaTransaction {
event CreateERC721Rarible(address owner, string name, string symbol);
event CreateERC721RaribleUser(address owner, string name, string symbol);
function __ERC721RaribleUser_init(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address[] memory operators, address transferProxy, address lazyTransferProxy) external {
__ERC721Rarible_init_unchained(_name, _symbol, baseURI, contractURI, transferProxy, lazyTransferProxy);
__MetaTransaction_init_unchained("ERC721RaribleUserMeta", "1");
isPrivate = true;
emit CreateERC721RaribleUser(_msgSender(), _name, _symbol);
}
function __ERC721Rarible_init(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address transferProxy, address lazyTransferProxy) external {
__ERC721Rarible_init_unchained(_name, _symbol, baseURI, contractURI, transferProxy, lazyTransferProxy);
__MetaTransaction_init_unchained("ERC721RaribleMeta", "1");
isPrivate = false;
emit CreateERC721Rarible(_msgSender(), _name, _symbol);
}
function _msgSender() internal view virtual override(ContextUpgradeable, EIP712MetaTransaction) returns (address payable) {
return super._msgSender();
}
function __ERC721Rarible_init_unchained(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address transferProxy, address lazyTransferProxy) internal initializer {
_setBaseURI(baseURI);
__ERC721Lazy_init_unchained();
__RoyaltiesV2Upgradeable_init_unchained();
__Context_init_unchained();
__ERC165_init_unchained();
__Ownable_init_unchained();
__ERC721Burnable_init_unchained();
__Mint721Validator_init_unchained();
__MinterAccessControl_init_unchained();
__HasContractURI_init_unchained(contractURI);
__ERC721_init_unchained(_name, _symbol);
//setting default approver for transferProxies
_setDefaultApproval(transferProxy, true);
_setDefaultApproval(lazyTransferProxy, true);
}
function mintAndTransfer(LibERC721LazyMint.Mint721Data memory data, address to) public override virtual {
if (isPrivate){
require(owner() == data.creators[0].account || isMinter(data.creators[0].account), "not owner or minter");
}
super.mintAndTransfer(data, to);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "./ERC721BurnableUpgradeable.sol";
import "./ERC721DefaultApproval.sol";
import "./ERC721Lazy.sol";
import "../HasContractURI.sol";
abstract contract ERC721Base is OwnableUpgradeable, ERC721DefaultApproval, ERC721BurnableUpgradeable, ERC721Lazy, HasContractURI {
event BaseUriChanged(string newBaseURI);
function _isApprovedOrOwner(address spender, uint256 tokenId) internal virtual override(ERC721Upgradeable, ERC721DefaultApproval) view returns (bool) {
return ERC721DefaultApproval._isApprovedOrOwner(spender, tokenId);
}
function isApprovedForAll(address owner, address operator) public view virtual override(ERC721DefaultApproval, ERC721Upgradeable, IERC721Upgradeable) returns (bool) {
return ERC721DefaultApproval.isApprovedForAll(owner, operator);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, ERC721Lazy) returns (bool) {
return super.supportsInterface(interfaceId);
}
function _mint(address to, uint256 tokenId) internal override(ERC721Lazy, ERC721Upgradeable) {
super._mint(to, tokenId);
}
function setBaseURI(string memory newBaseURI) external onlyOwner {
super._setBaseURI(newBaseURI);
emit BaseUriChanged(newBaseURI);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import "./ERC721Upgradeable.sol";
/**
* @title ERC721 Burnable Token
* @dev ERC721 Token that can be irreversibly burned (destroyed).
*/
abstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {
function __ERC721Burnable_init() internal initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721Burnable_init_unchained();
}
function __ERC721Burnable_init_unchained() internal initializer {
}
/**
* @dev Burns `tokenId`. See {ERC721-_burn}.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function burn(uint256 tokenId) public virtual {
if(!_exists(tokenId)) {
address owner = address(tokenId >> 96);
require(owner == _msgSender(), "ERC721Burnable: caller is not owner, not burn");
_setBurned(tokenId);
} else {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
_burn(tokenId);
}
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "./ERC721Upgradeable.sol";
abstract contract ERC721DefaultApproval is ERC721Upgradeable {
mapping(address => bool) private defaultApprovals;
event DefaultApproval(address indexed operator, bool hasApproval);
function _setDefaultApproval(address operator, bool hasApproval) internal {
defaultApprovals[operator] = hasApproval;
emit DefaultApproval(operator, hasApproval);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal virtual override view returns (bool) {
return defaultApprovals[spender] || super._isApprovedOrOwner(spender, tokenId);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return defaultApprovals[operator] || super.isApprovedForAll(owner, operator);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "./ERC721Upgradeable.sol";
import "@rarible/royalties/contracts/impl/RoyaltiesV2Impl.sol";
import "@rarible/royalties-upgradeable/contracts/RoyaltiesV2Upgradeable.sol";
import "@rarible/lazy-mint/contracts/erc-721/IERC721LazyMint.sol";
import "../Mint721Validator.sol";
abstract contract ERC721Lazy is IERC721LazyMint, ERC721Upgradeable, Mint721Validator, RoyaltiesV2Upgradeable, RoyaltiesV2Impl {
using SafeMathUpgradeable for uint;
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;
using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
// tokenId => creators
mapping(uint256 => LibPart.Part[]) private creators;
function __ERC721Lazy_init_unchained() internal initializer {
}
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {
return interfaceId == LibERC721LazyMint._INTERFACE_ID_MINT_AND_TRANSFER
|| interfaceId == LibRoyaltiesV2._INTERFACE_ID_ROYALTIES
|| interfaceId == LibRoyalties2981._INTERFACE_ID_ROYALTIES
|| interfaceId == _INTERFACE_ID_ERC165
|| interfaceId == _INTERFACE_ID_ERC721
|| interfaceId == _INTERFACE_ID_ERC721_METADATA
|| interfaceId == _INTERFACE_ID_ERC721_ENUMERABLE;
}
function transferFromOrMint(
LibERC721LazyMint.Mint721Data memory data,
address from,
address to
) override external {
if (_exists(data.tokenId)) {
safeTransferFrom(from, to, data.tokenId);
} else {
require(from == data.creators[0].account, "wrong order maker");
mintAndTransfer(data, to);
}
}
function mintAndTransfer(LibERC721LazyMint.Mint721Data memory data, address to) public override virtual {
address minter = address(data.tokenId >> 96);
address sender = _msgSender();
require(minter == data.creators[0].account, "tokenId incorrect");
require(data.creators.length == data.signatures.length);
require(minter == sender || isApprovedForAll(minter, sender), "ERC721: transfer caller is not owner nor approved");
bytes32 hash = LibERC721LazyMint.hash(data);
for (uint i = 0; i < data.creators.length; ++i) {
address creator = data.creators[i].account;
if (creator != sender) {
validate(creator, hash, data.signatures[i]);
}
}
_safeMint(to, data.tokenId);
_saveRoyalties(data.tokenId, data.royalties);
_saveCreators(data.tokenId, data.creators);
_setTokenURI(data.tokenId, data.tokenURI);
}
function _mint(address to, uint256 tokenId) internal virtual override {
require(to != address(0), "ERC721: mint to the zero address");
require(!_burned(tokenId), "token already burned");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
address minter = address(tokenId >> 96);
if (minter != to) {
emit Transfer(address(0), minter, tokenId);
emit Transfer(minter, to, tokenId);
} else {
emit Transfer(address(0), to, tokenId);
}
}
function _saveCreators(uint tokenId, LibPart.Part[] memory _creators) internal {
LibPart.Part[] storage creatorsOfToken = creators[tokenId];
uint total = 0;
for (uint i = 0; i < _creators.length; ++i) {
require(_creators[i].account != address(0x0), "Account should be present");
require(_creators[i].value != 0, "Creator share should be positive");
creatorsOfToken.push(_creators[i]);
total = total.add(_creators[i].value);
}
require(total == 10000, "total amount of creators share should be 10000");
emit Creators(tokenId, _creators);
}
function updateAccount(uint256 _id, address _from, address _to) external {
require(_msgSender() == _from, "not allowed");
super._updateAccount(_id, _from, _to);
}
function getCreators(uint256 _id) external view returns (LibPart.Part[] memory) {
return creators[_id];
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "./ERC721Base.sol";
contract ERC721Rarible is ERC721Base {
event CreateERC721Rarible(address owner, string name, string symbol);
function __ERC721Rarible_init(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address transferProxy, address lazyTransferProxy) external initializer {
__ERC721Rarible_init_unchained(_name, _symbol, baseURI, contractURI, transferProxy, lazyTransferProxy);
emit CreateERC721Rarible(_msgSender(), _name, _symbol);
}
function __ERC721Rarible_init_unchained(string memory _name, string memory _symbol, string memory baseURI, string memory contractURI, address transferProxy, address lazyTransferProxy) internal {
_setBaseURI(baseURI);
__ERC721Lazy_init_unchained();
__RoyaltiesV2Upgradeable_init_unchained();
__Context_init_unchained();
__ERC165_init_unchained();
__Ownable_init_unchained();
__ERC721Burnable_init_unchained();
__Mint721Validator_init_unchained();
__HasContractURI_init_unchained(contractURI);
__ERC721_init_unchained(_name, _symbol);
//setting default approver for transferProxies
_setDefaultApproval(transferProxy, true);
_setDefaultApproval(lazyTransferProxy, true);
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721MetadataUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import "../LibURI.sol";
/**
* @title ERC721 Non-Fungible Token Standard basic implementation
* @dev see https://eips.ethereum.org/EIPS/eip-721
*/
contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {
using SafeMathUpgradeable for uint256;
using AddressUpgradeable for address;
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;
using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;
using StringsUpgradeable for uint256;
// Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
// which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
// Mapping from holder address to their (enumerable) set of owned tokens
mapping (address => EnumerableSetUpgradeable.UintSet) _holderTokens;
// Enumerable mapping from token ids to their owners
EnumerableMapUpgradeable.UintToAddressMap _tokenOwners;
// Mapping from token ID to approved address
mapping (uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping (address => mapping (address => bool)) private _operatorApprovals;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Optional mapping for token URIs
mapping (uint256 => string) private _tokenURIs;
// Base URI
string private _baseURI;
/*
* bytes4(keccak256('balanceOf(address)')) == 0x70a08231
* bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
* bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
* bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
*
* => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
* 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
*/
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
/*
* bytes4(keccak256('name()')) == 0x06fdde03
* bytes4(keccak256('symbol()')) == 0x95d89b41
* bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
*
* => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
*/
bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
/*
* bytes4(keccak256('totalSupply()')) == 0x18160ddd
* bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
* bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
*
* => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
*/
bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
// Mapping from token ID to flag == true, means token already burned
mapping(uint256 => bool) private _burnedTokens;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
function __ERC721_init(string memory name_, string memory symbol_) internal initializer {
__Context_init_unchained();
__ERC165_init_unchained();
__ERC721_init_unchained(name_, symbol_);
}
function __ERC721_init_unchained(string memory name_, string memory symbol_) internal initializer {
_name = name_;
_symbol = symbol_;
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_INTERFACE_ID_ERC721);
_registerInterface(_INTERFACE_ID_ERC721_METADATA);
_registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _holderTokens[owner].length();
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return LibURI.checkPrefix(base, _tokenURI);
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(base, tokenId.toString()));
}
/**
* @dev Returns the base URI set via {_setBaseURI}. This will be
* automatically added as a prefix in {tokenURI} to each token's URI, or
* to the token ID if no specific URI is set for that token ID.
*/
function baseURI() public view virtual returns (string memory) {
return _baseURI;
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
return _holderTokens[owner].at(index);
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
// _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
return _tokenOwners.length();
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
(uint256 tokenId, ) = _tokenOwners.at(index);
return tokenId;
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721Upgradeable.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(_msgSender() == owner || ERC721Upgradeable.isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
require(operator != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(address from, address to, uint256 tokenId) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `_data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _tokenOwners.contains(tokenId);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721Upgradeable.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || ERC721Upgradeable.isApprovedForAll(owner, spender));
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
d*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
_mint(to, tokenId);
require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_burnedTokens[tokenId], "token already burned");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(address(0), to, tokenId);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721Upgradeable.ownerOf(tokenId); // internal owner
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
// Clear metadata (if any)
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
_holderTokens[owner].remove(tokenId);
_tokenOwners.remove(tokenId);
_setBurned(tokenId);
emit Transfer(owner, address(0), tokenId);
}
/*Returns true if token with tokenId already burned*/
function _burned(uint256 tokenId) internal returns (bool) {
return _burnedTokens[tokenId];
}
/*Set token with tokenId burned*/
function _setBurned(uint256 tokenId) internal {
_burnedTokens[tokenId] = true;
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(address from, address to, uint256 tokenId) internal virtual {
require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_holderTokens[from].remove(tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(from, to, tokenId);
}
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
/**
* @dev Internal function to set the base URI for all token IDs. It is
* automatically added as a prefix to the value returned in {tokenURI},
* or to the token ID if {tokenURI} is empty.
*/
function _setBaseURI(string memory baseURI_) internal virtual {
_baseURI = baseURI_;
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
private returns (bool)
{
if (!to.isContract()) {
return true;
}
bytes memory returndata = to.functionCall(abi.encodeWithSelector(
IERC721ReceiverUpgradeable(to).onERC721Received.selector,
_msgSender(),
from,
tokenId,
_data
), "ERC721: transfer to non ERC721Receiver implementer");
bytes4 retval = abi.decode(returndata, (bytes4));
return (retval == _ERC721_RECEIVED);
}
function _approve(address to, uint256 tokenId) private {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
uint256[40] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@rarible/lazy-mint/contracts/erc-721/LibERC721LazyMint.sol";
import "@rarible/lazy-mint/contracts/erc-1155/LibERC1155LazyMint.sol";
import "@rarible/exchange-interfaces/contracts/IRoyaltiesProvider.sol";
import "@rarible/lib-bp/contracts/BpLibrary.sol";
import "./interfaces/ITransferManager.sol";
abstract contract RaribleTransferManager is OwnableUpgradeable, ITransferManager {
using BpLibrary for uint;
using SafeMathUpgradeable for uint;
ProtocolFeeData public protocolFee;
IRoyaltiesProvider public royaltiesRegistry;
//deprecated
address private defaultFeeReceiver;
// deprecated
mapping(address => address) private feeReceivers;
/// @dev event that's emitted when ProtocolFeeData buyerAmount changes
event BuyerFeeAmountChanged(uint oldValue, uint newValue);
/// @dev event that's emitted when ProtocolFeeData sellerAmount changes
event SellerFeeAmountChanged(uint oldValue, uint newValue);
/// @dev event that's emitted when ProtocolFeeData receiver changes
event FeeReceiverChanged(address oldValue, address newValue);
/// @dev struct to store protocol fee - receiver address, buyer fee amount (in bp), seller fee amount (in bp)
struct ProtocolFeeData {
address receiver;
uint48 buyerAmount;
uint48 sellerAmount;
}
/**
@notice initialises RaribleTransferManager state
@param newProtocolFee deprecated
@param newDefaultFeeReceiver deprecated
@param newRoyaltiesProvider royaltiesRegistry contract address
*/
function __RaribleTransferManager_init_unchained(
uint newProtocolFee,
address newDefaultFeeReceiver,
IRoyaltiesProvider newRoyaltiesProvider
) internal initializer {
royaltiesRegistry = newRoyaltiesProvider;
}
function setRoyaltiesRegistry(IRoyaltiesProvider newRoyaltiesRegistry) external onlyOwner {
royaltiesRegistry = newRoyaltiesRegistry;
}
function setPrtocolFeeReceiver(address _receiver) public onlyOwner {
emit FeeReceiverChanged(protocolFee.receiver, _receiver);
protocolFee.receiver = _receiver;
}
function setPrtocolFeeBuyerAmount(uint48 _buyerAmount) public onlyOwner {
emit BuyerFeeAmountChanged(protocolFee.buyerAmount, _buyerAmount);
protocolFee.buyerAmount = _buyerAmount;
}
function setPrtocolFeeSellerAmount(uint48 _sellerAmount) public onlyOwner {
emit SellerFeeAmountChanged(protocolFee.sellerAmount, _sellerAmount);
protocolFee.sellerAmount = _sellerAmount;
}
function setAllProtocolFeeData(address _receiver, uint48 _buyerAmount, uint48 _sellerAmount) public onlyOwner {
setPrtocolFeeReceiver(_receiver);
setPrtocolFeeBuyerAmount(_buyerAmount);
setPrtocolFeeSellerAmount(_sellerAmount);
}
/**
@notice executes transfers for 2 matched orders
@param left DealSide from the left order (see LibDeal.sol)
@param right DealSide from the right order (see LibDeal.sol)
@param feeSide feeSide of the match
@return totalLeftValue - total amount for the left order
@return totalRightValue - total amout for the right order
*/
function doTransfers(
LibDeal.DealSide memory left,
LibDeal.DealSide memory right,
LibFeeSide.FeeSide feeSide
) override internal returns (uint totalLeftValue, uint totalRightValue) {
totalLeftValue = left.asset.value;
totalRightValue = right.asset.value;
if (feeSide == LibFeeSide.FeeSide.LEFT) {
totalLeftValue = doTransfersWithFees(left, right, protocolFee);
transferPayouts(right.asset.assetType, right.asset.value, right.from, left.payouts, right.proxy);
} else if (feeSide == LibFeeSide.FeeSide.RIGHT) {
totalRightValue = doTransfersWithFees(right, left,protocolFee);
transferPayouts(left.asset.assetType, left.asset.value, left.from, right.payouts, left.proxy);
} else {
transferPayouts(left.asset.assetType, left.asset.value, left.from, right.payouts, left.proxy);
transferPayouts(right.asset.assetType, right.asset.value, right.from, left.payouts, right.proxy);
}
}
/**
@notice executes the fee-side transfers (payment + fees)
@param paymentSide DealSide of the fee-side order
@param nftSide DealSide of the nft-side order
@param _protocolFee protocol fee data
@return totalAmount of fee-side asset
*/
function doTransfersWithFees(
LibDeal.DealSide memory paymentSide,
LibDeal.DealSide memory nftSide,
ProtocolFeeData memory _protocolFee
) internal returns (uint totalAmount) {
uint buyerProtocolFee = paymentSide.protocolFeeEnabled ? _protocolFee.buyerAmount : 0;
uint sellerProtocolFee = nftSide.protocolFeeEnabled ? _protocolFee.sellerAmount : 0;
totalAmount = calculateTotalAmount(paymentSide.asset.value, buyerProtocolFee, paymentSide.originFees);
uint rest = transferProtocolFee(totalAmount, paymentSide.asset.value, paymentSide.from, buyerProtocolFee + sellerProtocolFee, _protocolFee.receiver, paymentSide.asset.assetType, paymentSide.proxy);
rest = transferRoyalties(paymentSide.asset.assetType, nftSide.asset.assetType, nftSide.payouts, rest, paymentSide.asset.value, paymentSide.from, paymentSide.proxy);
if (
paymentSide.originFees.length == 1 &&
nftSide.originFees.length == 1 &&
nftSide.originFees[0].account == paymentSide.originFees[0].account
) {
LibPart.Part[] memory origin = new LibPart.Part[](1);
origin[0].account = nftSide.originFees[0].account;
origin[0].value = nftSide.originFees[0].value + paymentSide.originFees[0].value;
(rest,) = transferFees(paymentSide.asset.assetType, rest, paymentSide.asset.value, origin, paymentSide.from, paymentSide.proxy);
} else {
(rest,) = transferFees(paymentSide.asset.assetType, rest, paymentSide.asset.value, paymentSide.originFees, paymentSide.from, paymentSide.proxy);
(rest,) = transferFees(paymentSide.asset.assetType, rest, paymentSide.asset.value, nftSide.originFees, paymentSide.from, paymentSide.proxy);
}
transferPayouts(paymentSide.asset.assetType, rest, paymentSide.from, nftSide.payouts, paymentSide.proxy);
}
/**
@notice transfers protocol fee to protocol fee receiver
*/
function transferProtocolFee(
uint totalAmount,
uint amount,
address from,
uint protocolFeeTotal,
address protocolFeeReceiver,
LibAsset.AssetType memory matchCalculate,
address proxy
) internal returns (uint) {
(uint rest, uint fee) = subFeeInBp(totalAmount, amount, protocolFeeTotal);
if (fee > 0) {
transfer(LibAsset.Asset(matchCalculate, fee), from, protocolFeeReceiver, proxy);
}
return rest;
}
/**
@notice Transfer royalties. If there is only one royalties receiver and one address in payouts and they match,
nothing is transferred in this function
@param paymentAssetType Asset Type which represents payment
@param nftAssetType Asset Type which represents NFT to pay royalties for
@param payouts Payouts to be made
@param rest How much of the amount left after previous transfers
@param from owner of the Asset to transfer
@param proxy Transfer proxy to use
@return How much left after transferring royalties
*/
function transferRoyalties(
LibAsset.AssetType memory paymentAssetType,
LibAsset.AssetType memory nftAssetType,
LibPart.Part[] memory payouts,
uint rest,
uint amount,
address from,
address proxy
) internal returns (uint) {
LibPart.Part[] memory royalties = getRoyaltiesByAssetType(nftAssetType);
if (
royalties.length == 1 &&
payouts.length == 1 &&
royalties[0].account == payouts[0].account
) {
require(royalties[0].value <= 5000, "Royalties are too high (>50%)");
return rest;
}
(uint result, uint totalRoyalties) = transferFees(paymentAssetType, rest, amount, royalties, from, proxy);
require(totalRoyalties <= 5000, "Royalties are too high (>50%)");
return result;
}
/**
@notice calculates royalties by asset type. If it's a lazy NFT, then royalties are extracted from asset. otherwise using royaltiesRegistry
@param nftAssetType NFT Asset Type to calculate royalties for
@return calculated royalties (Array of LibPart.Part)
*/
function getRoyaltiesByAssetType(LibAsset.AssetType memory nftAssetType) internal returns (LibPart.Part[] memory) {
if (nftAssetType.assetClass == LibAsset.ERC1155_ASSET_CLASS || nftAssetType.assetClass == LibAsset.ERC721_ASSET_CLASS) {
(address token, uint tokenId) = abi.decode(nftAssetType.data, (address, uint));
return royaltiesRegistry.getRoyalties(token, tokenId);
} else if (nftAssetType.assetClass == LibERC1155LazyMint.ERC1155_LAZY_ASSET_CLASS) {
(, LibERC1155LazyMint.Mint1155Data memory data) = abi.decode(nftAssetType.data, (address, LibERC1155LazyMint.Mint1155Data));
return data.royalties;
} else if (nftAssetType.assetClass == LibERC721LazyMint.ERC721_LAZY_ASSET_CLASS) {
(, LibERC721LazyMint.Mint721Data memory data) = abi.decode(nftAssetType.data, (address, LibERC721LazyMint.Mint721Data));
return data.royalties;
}
LibPart.Part[] memory empty;
return empty;
}
/**
@notice Transfer fees
@param assetType Asset Type to transfer
@param rest How much of the amount left after previous transfers
@param amount Total amount of the Asset. Used as a base to calculate part from (100%)
@param fees Array of LibPart.Part which represents fees to pay
@param from owner of the Asset to transfer
@param proxy Transfer proxy to use
@return newRest how much left after transferring fees
@return totalFees total number of fees in bp
*/
function transferFees(
LibAsset.AssetType memory assetType,
uint rest,
uint amount,
LibPart.Part[] memory fees,
address from,
address proxy
) internal returns (uint newRest, uint totalFees) {
totalFees = 0;
newRest = rest;
for (uint256 i = 0; i < fees.length; ++i) {
totalFees = totalFees.add(fees[i].value);
uint feeValue;
(newRest, feeValue) = subFeeInBp(newRest, amount, fees[i].value);
if (feeValue > 0) {
transfer(LibAsset.Asset(assetType, feeValue), from, fees[i].account, proxy);
}
}
}
/**
@notice transfers main part of the asset (payout)
@param assetType Asset Type to transfer
@param amount Amount of the asset to transfer
@param from Current owner of the asset
@param payouts List of payouts - receivers of the Asset
@param proxy Transfer Proxy to use
*/
function transferPayouts(
LibAsset.AssetType memory assetType,
uint amount,
address from,
LibPart.Part[] memory payouts,
address proxy
) internal {
require(payouts.length > 0, "transferPayouts: nothing to transfer");
uint sumBps = 0;
uint rest = amount;
for (uint256 i = 0; i < payouts.length - 1; ++i) {
uint currentAmount = amount.bp(payouts[i].value);
sumBps = sumBps.add(payouts[i].value);
if (currentAmount > 0) {
rest = rest.sub(currentAmount);
transfer(LibAsset.Asset(assetType, currentAmount), from, payouts[i].account, proxy);
}
}
LibPart.Part memory lastPayout = payouts[payouts.length - 1];
sumBps = sumBps.add(lastPayout.value);
require(sumBps == 10000, "Sum payouts Bps not equal 100%");
if (rest > 0) {
transfer(LibAsset.Asset(assetType, rest), from, lastPayout.account, proxy);
}
}
/**
@notice calculates total amount of fee-side asset that is going to be used in match
@param amount fee-side order value
@param buyerProtocolFee buyer protocol fee
@param orderOriginFees fee-side order's origin fee (it adds on top of the amount)
@return total amount of fee-side asset
*/
function calculateTotalAmount(
uint amount,
uint buyerProtocolFee,
LibPart.Part[] memory orderOriginFees
) internal pure returns (uint) {
uint fees = buyerProtocolFee;
for (uint256 i = 0; i < orderOriginFees.length; ++i) {
require(orderOriginFees[i].value <= 10000, "origin fee is too big");
fees = fees + orderOriginFees[i].value;
}
return amount.add(amount.bp(fees));
}
function subFeeInBp(uint value, uint total, uint feeInBp) internal pure returns (uint newValue, uint realFee) {
return subFee(value, total.bp(feeInBp));
}
function subFee(uint value, uint fee) internal pure returns (uint newValue, uint realFee) {
if (value > fee) {
newValue = value.sub(fee);
realFee = fee;
} else {
newValue = 0;
realFee = value;
}
}
uint256[46] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/exchange-interfaces/contracts/ITransferProxy.sol";
import "@rarible/exchange-interfaces/contracts/INftTransferProxy.sol";
import "@rarible/exchange-interfaces/contracts/IERC20TransferProxy.sol";
import "./interfaces/ITransferExecutor.sol";
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "./lib/LibTransfer.sol";
abstract contract TransferExecutor is Initializable, OwnableUpgradeable, ITransferExecutor {
using LibTransfer for address;
mapping (bytes4 => address) internal proxies;
event ProxyChange(bytes4 indexed assetType, address proxy);
function __TransferExecutor_init_unchained(address transferProxy, address erc20TransferProxy) internal {
proxies[LibAsset.ERC20_ASSET_CLASS] = address(erc20TransferProxy);
proxies[LibAsset.ERC721_ASSET_CLASS] = address(transferProxy);
proxies[LibAsset.ERC1155_ASSET_CLASS] = address(transferProxy);
}
function setTransferProxy(bytes4 assetType, address proxy) external onlyOwner {
proxies[assetType] = proxy;
emit ProxyChange(assetType, proxy);
}
function transfer(
LibAsset.Asset memory asset,
address from,
address to,
address proxy
) internal override {
if (asset.assetType.assetClass == LibAsset.ERC721_ASSET_CLASS) {
//not using transfer proxy when transfering from this contract
(address token, uint tokenId) = abi.decode(asset.assetType.data, (address, uint256));
require(asset.value == 1, "erc721 value error");
if (from == address(this)){
IERC721Upgradeable(token).safeTransferFrom(address(this), to, tokenId);
} else {
INftTransferProxy(proxy).erc721safeTransferFrom(IERC721Upgradeable(token), from, to, tokenId);
}
} else if (asset.assetType.assetClass == LibAsset.ERC20_ASSET_CLASS) {
//not using transfer proxy when transfering from this contract
(address token) = abi.decode(asset.assetType.data, (address));
if (from == address(this)){
require(IERC20Upgradeable(token).transfer(to, asset.value), "erc20 transfer failed");
} else {
IERC20TransferProxy(proxy).erc20safeTransferFrom(IERC20Upgradeable(token), from, to, asset.value);
}
} else if (asset.assetType.assetClass == LibAsset.ERC1155_ASSET_CLASS) {
//not using transfer proxy when transfering from this contract
(address token, uint tokenId) = abi.decode(asset.assetType.data, (address, uint256));
if (from == address(this)){
IERC1155Upgradeable(token).safeTransferFrom(address(this), to, tokenId, asset.value, "");
} else {
INftTransferProxy(proxy).erc1155safeTransferFrom(IERC1155Upgradeable(token), from, to, tokenId, asset.value, "");
}
} else if (asset.assetType.assetClass == LibAsset.ETH_ASSET_CLASS) {
if (to != address(this)) {
to.transferEth(asset.value);
}
} else {
ITransferProxy(proxy).transfer(asset, from, to);
}
}
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/lib-asset/contracts/LibAsset.sol";
abstract contract ITransferExecutor {
function transfer(
LibAsset.Asset memory asset,
address from,
address to,
address proxy
) internal virtual;
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "../lib/LibDeal.sol";
import "./ITransferExecutor.sol";
abstract contract ITransferManager is ITransferExecutor {
function doTransfers(
LibDeal.DealSide memory left,
LibDeal.DealSide memory right,
LibFeeSide.FeeSide feeSide
) internal virtual returns (uint totalMakeValue, uint totalTakeValue);
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import "@rarible/lib-part/contracts/LibPart.sol";
import "@rarible/lib-asset/contracts/LibAsset.sol";
import "./LibFeeSide.sol";
library LibDeal {
struct DealSide {
LibAsset.Asset asset;
LibPart.Part[] payouts;
LibPart.Part[] originFees;
address proxy;
address from;
bool protocolFeeEnabled;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@rarible/lib-asset/contracts/LibAsset.sol";
library LibFeeSide {
enum FeeSide {NONE, LEFT, RIGHT}
function getFeeSide(bytes4 leftClass, bytes4 rightClass) internal pure returns (FeeSide) {
if (leftClass == LibAsset.ETH_ASSET_CLASS) {
return FeeSide.LEFT;
}
if (rightClass == LibAsset.ETH_ASSET_CLASS) {
return FeeSide.RIGHT;
}
if (leftClass == LibAsset.ERC20_ASSET_CLASS) {
return FeeSide.LEFT;
}
if (rightClass == LibAsset.ERC20_ASSET_CLASS) {
return FeeSide.RIGHT;
}
if (leftClass == LibAsset.ERC1155_ASSET_CLASS) {
return FeeSide.LEFT;
}
if (rightClass == LibAsset.ERC1155_ASSET_CLASS) {
return FeeSide.RIGHT;
}
return FeeSide.NONE;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
library LibTransfer {
function transferEth(address to, uint value) internal {
(bool success,) = to.call{ value: value }("");
require(success, "transfer failed");
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
import "@rarible/exchange-interfaces/contracts/ITransferProxy.sol";
import "@rarible/lazy-mint/contracts/erc-1155/LibERC1155LazyMint.sol";
import "@rarible/lazy-mint/contracts/erc-1155/IERC1155LazyMint.sol";
import "@rarible/role-operator/contracts/OperatorRole.sol";
contract ERC1155LazyMintTransferProxy is OperatorRole, ITransferProxy {
function transfer(LibAsset.Asset memory asset, address from, address to) override onlyOperator external {
(address token, LibERC1155LazyMint.Mint1155Data memory data) = abi.decode(asset.assetType.data, (address, LibERC1155LazyMint.Mint1155Data));
IERC1155LazyMint(token).transferFromOrMint(data, from, to, asset.value);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
pragma abicoder v2;
import "@rarible/exchange-interfaces/contracts/ITransferProxy.sol";
import "@rarible/lazy-mint/contracts/erc-721/LibERC721LazyMint.sol";
import "@rarible/lazy-mint/contracts/erc-721/IERC721LazyMint.sol";
import "@rarible/role-operator/contracts/OperatorRole.sol";
contract ERC721LazyMintTransferProxy is OperatorRole, ITransferProxy {
function transfer(LibAsset.Asset memory asset, address from, address to) override onlyOperator external {
require(asset.value == 1, "erc721 value error");
(address token, LibERC721LazyMint.Mint721Data memory data) = abi.decode(asset.assetType.data, (address, LibERC721LazyMint.Mint721Data));
IERC721LazyMint(token).transferFromOrMint(data, from, to);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
import "@rarible/role-operator/contracts/OperatorRole.sol";
import "@rarible/exchange-interfaces/contracts/IERC20TransferProxy.sol";
contract ERC20TransferProxy is IERC20TransferProxy, Initializable, OperatorRole {
function __ERC20TransferProxy_init() external initializer {
__Ownable_init();
}
function erc20safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) override external onlyOperator {
require(token.transferFrom(from, to, value), "failure while transferring");
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0;
import "@rarible/role-operator/contracts/OperatorRole.sol";
import "@rarible/exchange-interfaces/contracts/INftTransferProxy.sol";
contract TransferProxy is INftTransferProxy, Initializable, OperatorRole {
function __TransferProxy_init() external initializer {
__Ownable_init();
}
function erc721safeTransferFrom(IERC721Upgradeable token, address from, address to, uint256 tokenId) override external onlyOperator {
token.safeTransferFrom(from, to, tokenId);
}
function erc1155safeTransferFrom(IERC1155Upgradeable token, address from, address to, uint256 id, uint256 value, bytes calldata data) override external onlyOperator {
token.safeTransferFrom(from, to, id, value, data);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import { AssetMatcherCollection } from "@rarible/custom-matchers/contracts/AssetMatcherCollection.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import {ExchangeV2} from "@rarible/exchange-v2/contracts/ExchangeV2.sol";
import {ExchangeMetaV2} from "@rarible/exchange-v2/contracts/ExchangeMetaV2.sol";// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@rarible/exchange-wrapper/contracts/RaribleExchangeWrapper.sol";
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import {RaribleExchangeWrapper} from "@rarible/exchange-wrapper/contracts/RaribleExchangeWrapper.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import {RoyaltiesRegistry} from "@rarible/royalties-registry/contracts/RoyaltiesRegistry.sol";
import {RoyaltiesProviderV2Legacy} from "@rarible/royalties-registry/contracts/providers/RoyaltiesProviderV2Legacy.sol";
import {RoyaltiesProviderArtBlocks} from "@rarible/royalties-registry/contracts/providers/RoyaltiesProviderArtBlocks.sol";
import {RoyaltiesProviderArtBlocksV2} from "@rarible/royalties-registry/contracts/providers/RoyaltiesProviderArtBlocksV2.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
//tokens 721
import {ERC721Rarible} from "@rarible/tokens/contracts/erc-721/ERC721Rarible.sol";
import {ERC721RaribleMinimal} from "@rarible/tokens/contracts/erc-721-minimal/ERC721RaribleMinimal.sol";
import {ERC721RaribleFactoryC2} from "@rarible/tokens/contracts/create-2/ERC721RaribleFactoryC2.sol";
//tokens 1155
import {ERC1155Rarible} from "@rarible/tokens/contracts/erc-1155/ERC1155Rarible.sol";
import {ERC1155RaribleFactoryC2} from "@rarible/tokens/contracts/create-2/ERC1155RaribleFactoryC2.sol";
//meta tokens
import {ERC721RaribleMeta} from "@rarible/tokens/contracts/erc-721-minimal/erc-721-minimal-meta/ERC721RaribleMeta.sol";
import {ERC1155RaribleMeta} from "@rarible/tokens/contracts/erc-1155/erc-1155-meta/ERC1155RaribleMeta.sol";
//beacons
import {ERC1155RaribleBeacon} from "@rarible/tokens/contracts/beacons/ERC1155RaribleBeacon.sol";
import {ERC721RaribleMinimalBeacon} from "@rarible/tokens/contracts/beacons/ERC721RaribleMinimalBeacon.sol";
import {ERC721RaribleBeacon} from "@rarible/tokens/contracts/beacons/ERC721RaribleBeacon.sol";
import {ERC1155RaribleBeaconMeta} from "@rarible/tokens/contracts/beacons/ERC1155RaribleBeaconMeta.sol";
import {ERC721RaribleMinimalBeaconMeta} from "@rarible/tokens/contracts/beacons/ERC721RaribleMinimalBeaconMeta.sol";
import { TestERC20 } from "@rarible/test/contracts/TestERC20.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import {ERC721LazyMintTransferProxy} from "@rarible/transfer-proxy/contracts/lazy-mint/erc721/ERC721LazyMintTransferProxy.sol";
import {ERC1155LazyMintTransferProxy} from "@rarible/transfer-proxy/contracts/lazy-mint/erc1155/ERC1155LazyMintTransferProxy.sol";
import {TransferProxy} from "@rarible/transfer-proxy/contracts/proxy/TransferProxy.sol";
import {ERC20TransferProxy} from "@rarible/transfer-proxy/contracts/proxy/ERC20TransferProxy.sol";// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@openzeppelin/contracts/proxy/ProxyAdmin.sol";
// SPDX-License-Identifier: MIT pragma solidity >=0.6.9 <0.8.0; pragma abicoder v2; import "@rarible/lazy-mint/test/contracts/ERC721LazyMintTest.sol";
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import {RaribleTestHelper} from "@rarible/exchange-v2/test/contracts/RaribleTestHelper.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import { TestERC1155 } from "@rarible/test/contracts/TestERC1155.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import { TestERC1155RoyaltiesV2 } from "@rarible/royalties/test/contracts/TestERC1155RoyaltiesV2.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import { TestERC20 } from "@rarible/test/contracts/TestERC20.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import { TestERC721 } from "@rarible/test/contracts/TestERC721.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import { TestERC721RoyaltiesV1 } from "@rarible/royalties/test/contracts/TestERC721RoyaltiesV1.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import { TestERC721RoyaltiesV2 } from "@rarible/royalties/test/contracts/TestERC721RoyaltiesV2.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import { WrapperHelper } from "@rarible/exchange-wrapper/test/contracts/WrapperHelper.sol";// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
pragma abicoder v2;
import {RaribleTestHelper} from "@rarible/exchange-v2/test/contracts/RaribleTestHelper.sol";{
"libraries": {},
"optimizer": {
"enabled": true,
"mode": "z"
},
"outputSelection": {
"*": {
"*": [
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"BuyerFeeAmountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"Cancel","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"FeeReceiverChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"leftHash","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"rightHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"newLeftFill","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newRightFill","type":"uint256"}],"name":"Match","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes4","name":"assetType","type":"bytes4"},{"indexed":false,"internalType":"address","name":"matcher","type":"address"}],"name":"MatcherChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"address payable","name":"relayerAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"functionSignature","type":"bytes"}],"name":"MetaTransactionExecuted","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":"bytes4","name":"assetType","type":"bytes4"},{"indexed":false,"internalType":"address","name":"proxy","type":"address"}],"name":"ProxyChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"SellerFeeAmountChanged","type":"event"},{"inputs":[{"internalType":"address","name":"_transferProxy","type":"address"},{"internalType":"address","name":"_erc20TransferProxy","type":"address"},{"internalType":"uint256","name":"newProtocolFee","type":"uint256"},{"internalType":"address","name":"newDefaultFeeReceiver","type":"address"},{"internalType":"contract IRoyaltiesProvider","name":"newRoyaltiesProvider","type":"address"}],"name":"__ExchangeV2_init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct LibAsset.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct LibAsset.Asset","name":"makeAsset","type":"tuple"},{"internalType":"address","name":"taker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct LibAsset.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct LibAsset.Asset","name":"takeAsset","type":"tuple"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"},{"internalType":"bytes4","name":"dataType","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct LibOrder.Order","name":"order","type":"tuple"}],"name":"cancel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"bidMaker","type":"address"},{"internalType":"uint256","name":"bidNftAmount","type":"uint256"},{"internalType":"bytes4","name":"nftAssetClass","type":"bytes4"},{"internalType":"bytes","name":"nftData","type":"bytes"},{"internalType":"uint256","name":"bidPaymentAmount","type":"uint256"},{"internalType":"address","name":"paymentToken","type":"address"},{"internalType":"uint256","name":"bidSalt","type":"uint256"},{"internalType":"uint256","name":"bidStart","type":"uint256"},{"internalType":"uint256","name":"bidEnd","type":"uint256"},{"internalType":"bytes4","name":"bidDataType","type":"bytes4"},{"internalType":"bytes","name":"bidData","type":"bytes"},{"internalType":"bytes","name":"bidSignature","type":"bytes"},{"internalType":"uint256","name":"sellOrderPaymentAmount","type":"uint256"},{"internalType":"uint256","name":"sellOrderNftAmount","type":"uint256"},{"internalType":"bytes","name":"sellOrderData","type":"bytes"}],"internalType":"struct LibDirectTransfer.AcceptBid","name":"direct","type":"tuple"}],"name":"directAcceptBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sellOrderMaker","type":"address"},{"internalType":"uint256","name":"sellOrderNftAmount","type":"uint256"},{"internalType":"bytes4","name":"nftAssetClass","type":"bytes4"},{"internalType":"bytes","name":"nftData","type":"bytes"},{"internalType":"uint256","name":"sellOrderPaymentAmount","type":"uint256"},{"internalType":"address","name":"paymentToken","type":"address"},{"internalType":"uint256","name":"sellOrderSalt","type":"uint256"},{"internalType":"uint256","name":"sellOrderStart","type":"uint256"},{"internalType":"uint256","name":"sellOrderEnd","type":"uint256"},{"internalType":"bytes4","name":"sellOrderDataType","type":"bytes4"},{"internalType":"bytes","name":"sellOrderData","type":"bytes"},{"internalType":"bytes","name":"sellOrderSignature","type":"bytes"},{"internalType":"uint256","name":"buyOrderPaymentAmount","type":"uint256"},{"internalType":"uint256","name":"buyOrderNftAmount","type":"uint256"},{"internalType":"bytes","name":"buyOrderData","type":"bytes"}],"internalType":"struct LibDirectTransfer.Purchase","name":"direct","type":"tuple"}],"name":"directPurchase","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bytes","name":"functionSignature","type":"bytes"},{"internalType":"bytes32","name":"sigR","type":"bytes32"},{"internalType":"bytes32","name":"sigS","type":"bytes32"},{"internalType":"uint8","name":"sigV","type":"uint8"}],"name":"executeMetaTransaction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"fills","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct LibAsset.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct LibAsset.Asset","name":"makeAsset","type":"tuple"},{"internalType":"address","name":"taker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct LibAsset.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct LibAsset.Asset","name":"takeAsset","type":"tuple"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"},{"internalType":"bytes4","name":"dataType","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct LibOrder.Order","name":"orderLeft","type":"tuple"},{"internalType":"bytes","name":"signatureLeft","type":"bytes"},{"components":[{"internalType":"address","name":"maker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct LibAsset.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct LibAsset.Asset","name":"makeAsset","type":"tuple"},{"internalType":"address","name":"taker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct LibAsset.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct LibAsset.Asset","name":"takeAsset","type":"tuple"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"},{"internalType":"bytes4","name":"dataType","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct LibOrder.Order","name":"orderRight","type":"tuple"},{"internalType":"bytes","name":"signatureRight","type":"bytes"}],"name":"matchOrders","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFee","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint48","name":"buyerAmount","type":"uint48"},{"internalType":"uint48","name":"sellerAmount","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"royaltiesRegistry","outputs":[{"internalType":"contract IRoyaltiesProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint48","name":"_buyerAmount","type":"uint48"},{"internalType":"uint48","name":"_sellerAmount","type":"uint48"}],"name":"setAllProtocolFeeData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"assetType","type":"bytes4"},{"internalType":"address","name":"matcher","type":"address"}],"name":"setAssetMatcher","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"_buyerAmount","type":"uint48"}],"name":"setPrtocolFeeBuyerAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"setPrtocolFeeReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"_sellerAmount","type":"uint48"}],"name":"setPrtocolFeeSellerAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IRoyaltiesProvider","name":"newRoyaltiesRegistry","type":"address"}],"name":"setRoyaltiesRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"assetType","type":"bytes4"},{"internalType":"address","name":"proxy","type":"address"}],"name":"setTransferProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
9c4d535b0000000000000000000000000000000000000000000000000000000000000000010013a36b64adf0648ee568670457aaf5893d386f15332d419b0394af175c9f00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x000400000000000200000000030100190000006003300270000013000430019700030000004103550002000000010355000013000030019d00000001012001900000000b0000c13d00000000010000194bfc005b0000040f00000001010000394bfc005b0000040f0003000000000002000300000006001d000200000005001d0000130005000041000013000630009c00000000030580190000004003300210000013000640009c00000000040580190000006004400210000000000334019f000013000410009c0000000001058019000000c001100210000000000113019f4bfc44050000040f0000000209000029000000000301001900000060033002700000130003300197000000030430006c000000030500002900000000050340190000001f0450018f00000005055002720000002e0000613d000000000600001900000005076002100000000008790019000000000771034f0001002d0000003d000044a70000013d000000280000413d000000010220018f000000000604004b000000330000613d000100330000003d000047e30000013d00004ac70000013d0003000000000002000300000006001d000200000005001d0000130005000041000013000630009c00000000030580190000004003300210000013000640009c00000000040580190000006004400210000000000334019f000013000410009c0000000001058019000000c001100210000000000113019f4bfc440a0000040f0000000209000029000000000301001900000060033002700000130003300197000000030430006c000000030500002900000000050340190000001f0450018f0000000505500272000000550000613d000000000600001900000005076002100000000008790019000000000771034f000100540000003d000044a70000013d0000004f0000413d000000010220018f000000000604004b0000005a0000613d0001005a0000003d000047e30000013d00004ac70000013d009f0000000000020000008002000039000000400020043f000000000101004b000000680000613d0000000001000416000000000101004b0000006d0000c13d000000200100003900000100001004430000012000000443000013990100004100004bfd0001042e002500000002001d0000000001000031002600000001001d000000030110008c0000006f0000213d000000000100001900004bfe000104300000000209000367000000000709043b000000e008700270000013010170009c000000000f0004100000002601000029002400bf0010003d0000001f0a10018f000000050b100270000000a00e100039000000800d100039000000040510008a00000004049003700000003f0c100039000000240390037000000064019003700000004402900370000001730000813d000013440670009c000001820000813d0000134f0680009c0000008406900370000002290000c13d000000000b09034f00230000000f001d00001308080000410000009f0950008c000000000900001900000000090820190000130805500197000000000a05004b0000000008008019000013080550009c000000000809c019000000000508004b0000006d0000613d000000000504043b002513090050019b002400000005001d000013090450009c0000006d0000213d000000000403043b000013150340009c0000006d0000213d000000230340003900001308050000410000002609000029000000000893004b0000000008000019000000000805401900001308099001970000130803300197000000000a93004b000000000500a019000000000393013f000013080330009c000000000508c019000000000305004b0000006d0000613d000000040540003900000000035b034f000000000303043b000013160830009c00001b020000813d000000bf083000390022002000000092000000220880017f000000800980008a0000138e0990009c00001b020000813d000000400080043f000000800030043f00000000043400190000002404400039000000260440006c0000006d0000213d000000200450003900000000044b034f0000001f0530018f0000000508300272000000c90000613d0000000009000019000000050a900210000000000ba4034f000000000b0b043b000000a00aa000390000000000ba04350000000109900039000000000a89004b000000c10000413d000000000905004b000000d80000613d0000000508800210000000000484034f0000000305500210000000a008800039000000000908043300000000095901cf000000000959022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000494019f0000000000480435000000a0033000390000000000030435000000000101043b002100000001001d000000000102043b002600000001001d000000000106043b000001000210008c0000006d0000813d000000800200043d000000000202004b0000000002000019000000e60000613d000000a00200043d000000000272013f000000400300043d0000138f0220009c00000eac0000a13d001f00ff001001930000006001300039000000400010043f000000250100002900000000001004350000019301000039001b00000001001d000000200010043f00000040020000390000000001000019002000000003001d4bfc43d70000040f000000000101041a00000020020000290000000001120436001e00000001001d000000250300002900000000003104350000004002200039001d00000002001d00000080010000390000000000120435000000400100043d0000008002100039000000400020043f00001391020000410000006003100039000000000023043500001392020000410000004003100039000000000023043500000043020000390000000001210436000013930300004100000000003104354bfc43d70000040f0000001e020000290000000002020433001e00000002001d00000020020000290000000002020433001c00000002001d0000001d020000290000000002020433001d00000001001d00000000120204344bfc43d70000040f000000400400043d002000000004001d00000020024000390000001d03000029000000000032043500000040024000390000001c0300002900000000003204350000001e020000290000130902200197000000600340003900000000002304350000008002400039000101280000003d00004b850000013d000000a002400039000000400020043f00000000020304334bfc43d70000040f0000019402000039000000000202041a00001323030000410000002005000029000000c0045000390000000000340435000000c2035000390000000000230435000000e202500039000101370000003d00004b850000013d0000010202500039001e00000002001d000000400020043f00000000020304334bfc43d70000040f0000001e02000029000000000002043500000020050000290000012202500039000000400020043f00000182035000390000002104000029000000000043043500000162035000390000002604000029000000000043043500000142035000390000001f0400002900000000004304350000000000120435000000400300043d0000000001350049000001a2041000390000000001000414000101510000003d00004b570000013d002100000002001d002600000006001d4bfc00340000040f000000000101004b00000ecd0000c13d000000030100036700000001020000310000001f0420018f0000000503200272000001630000613d00000000050000190000000506500210000000000761034f000000000707043b00000000007604350000000105500039000000000635004b0000015c0000413d000000000504004b000001710000613d00000003044002100000000503300210000000000503043300000000054501cf000000000545022f000000000131034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000000010000194bfc43c30000040f000013020670009c000001dd0000813d0000133d0180009c000002620000c13d0000000001000416000000000101004b0000006d0000c13d0000003301000039000000000101041a0000130901100197000000800010043f000000a0020000390000008001000039000000000212004900004b320000013d000013450180009c000002730000c13d0000000001000416000000000101004b0000006d0000c13d00001308010000410000003f0250008c000000000200001900000000020120190000130805500197000000000605004b0000000001008019000013080550009c000000000102c019000000000101004b0000006d0000613d000000000204043b00001317012001970000000005020019000000000112004b0000006d0000c13d000000000103043b002500000001001d0000130a0110009c0000006d0000813d000000000100041100000000021f004b000001af0000c13d000101a00000003d000047150000013d000001a50000613d0000000001000019000101a40000003d000046950000013d000001a20000413d00000000010a004b000001ac0000613d0000000501b00210000000000219034f0000000303a00210000101ac0000003d000044630000013d00000000000e043500000000010d043300001309011001970000003302000039000000000202041a000000000212013f0000134d030000410000009701000039000013090220019800000ad20000c13d002400000003001d002600000005001d0000000000500435000000200010043f000000400200003900000000010000194bfc43d70000040f000000000201041a0000130d0220019700000025040000290000130903400197000000000232019f000000000021041b000000400100043d0000000000410435000000400200043d00000000012100490000130003000041000013000420009c000000000203801900000040022002100000002001100039000013000410009c00000000010380190000006001100210000000000121019f0000000002000414000013000420009c000101d40000003d000048ac0000013d0000130b011001c70000800d020000390000000203000039000000240400002900000026050000294bfc44050000040f0000000101200190000002a90000c13d0000006d0000013d000013030680009c000002ab0000c13d0000000001000416000000000101004b0000006d0000c13d0000130801000041000101e50000003d000048840000013d0000130803500197000000000503004b0000000001008019000013080330009c000000000102c019000000000101004b0000006d0000613d000000000104043b002513110010019b000013120110009c0000006d0000813d000000000100041100000000021f004b000002040000c13d000101f50000003d000047150000013d000001fa0000613d0000000001000019000101f90000003d000046950000013d000001f70000413d00000000010a004b000002010000613d0000000501b00210000000000219034f0000000303a00210000102010000003d000044630000013d00000000000e043500000000010d043300001309011001970000003302000039000000000202041a000000000112013f000013090110019800000ad20000c13d0001020b0000003d000047f10000013d000000a00110027000001311011001970001020f0000003d00004a9b0000013d0000130003000041000013000410009c000102130000003d00004a5f0000013d000013000420009c000102160000003d000049450000013d0000000002000414000013000420009c0001021a0000003d000048ac0000013d0000130b011001c70000800d0200003900000001030000390000133b040000414bfc44050000040f00000001012001900000006d0000613d0000002501000029000000a0011002100000002603000029000000000203041a0000133c02200197000000000112019f000000000013041b000002a90000013d000013500280009c000004270000c13d00240000000c001d0001022e0000003d000049840000013d0000130801000041000102310000003d000048840000013d0000130803500197000000000503004b0000000001008019000013080330009c000000000102c019000000000101004b0000006d0000613d000000000304043b000013160130009c0000006d0000813d000000040130003900000026021000690000130804000041000001df0520008c000000000500001900000000050420190000130806200197000000000706004b0000000004008019000013080660009c000000000405c019000000000404004b0000006d0000613d000000a403300039000000220430035f000000000504043b00001309045001970000130a0550009c0000006d0000813d000000800000043f0000006005000039000000a00050043f000000e00050043f000000000504004b00000ae10000c13d0000134b04000041000000c00040043f002501000000003d001802000000003d001901e00000003d001e01c00000003d001f01a00000003d001d01800000003d001c01600000003d001b01400000003d001a01200000003d0000022004000039000000220500035f00000af30000013d0000133e0180009c000004900000c13d0000000001000416000000000101004b0000006d0000c13d0000016101000039000000000101041a0000130902100197000000800020043f000000a0021002700000131102200197000000a00020043f000000d001100270000000c00010043f0000008001000039000000600200003900004b320000013d000013460180009c000004c30000c13d0000000001000416000000000101004b0000006d0000c13d00001308010000410001027b0000003d000048840000013d0000130803500197000000000503004b0000000001008019000013080330009c000000000102c019000000000101004b0000006d0000613d000000000204043b00001309012001970000130a0220009c0000006d0000813d000000000200041100000000032f004b0000029f0000c13d000000200200008a000000240220017f000000400020043f0000002602000029000000800020043f00000000020b004b000002950000613d0000000002000019000102930000003d00004afb0000013d0000000003b2004b000002910000413d00000000020a004b0000029c0000613d0000000502b00210000000000329034f0000000304a002100001029c0000003d000048ff0000013d00000000000e043500000000020d043300001309022001970000003303000039000000000303041a000000000223013f000013090220019800000ad20000c13d0000016202000039000000000302041a0000130d03300197000000000113019f000000000012041b000000000100001900004bfd0001042e000013040680009c000004fc0000c13d00240000000c001d00210000000b001d00200000000a001d00220000000903530000000001000416000000000101004b0000006d0000c13d0000130801000041000102b70000003d000048840000013d0000130803500197000000000503004b0000000001008019000013080330009c000000000102c019000000000101004b0000006d0000613d000000000204043b000013150120009c0000006d0000213d0000000401200039000000260310006900001308040000410000011f0530008c000000000500001900000000050420190000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d000001a004000039000000400040043f000000220310035f000000000303043b0000130a0530009c0000006d0000813d000000800030043f0000002003100039000000220330035f000000000303043b000013160530009c0000006d0000813d0000000005130019000000260350006900001308060000410000003f0730008c000000000700001900000000070620190000130803300197000000000803004b0000000006008019000013080330009c000000000607c019000000000306004b0000006d0000613d000001e006000039000000400060043f000000220350035f000000000303043b000013160730009c0000006d0000813d0000000003530019000000260730006900001308080000410000003f0970008c000000000900001900000000090820190000130807700197000000000a07004b0000000008008019000013080770009c000000000809c019000000000708004b0000006d0000613d0000022007000039000000400070043f000000220830035f000000000808043b0000131709800197000000000998004b0000006d0000c13d000001e00080043f0000002008300039000000220880035f000000000808043b000013160980009c0000006d0000813d00000000093800190000001f039000390000130808000041000000260b000029000000000ab3004b000000000a000019000000000a0840190000130803300197000013080bb00197000000000cb3004b000000000800a0190000000003b3013f000013080330009c00000000080ac019000000000308004b0000006d0000613d000000220390035f000000000803043b000013160380009c00001b020000813d0000025f0a800039000000200300008a000000000a3a016f000002200ba0008a000013180bb0009c00001b020000813d0000004000a0043f000002200080043f0000002009900039000000000a890019000000260aa0006c0000006d0000213d000000220990035f0000001f0a80018f000000050b800272000003340000613d000000000c000019000000050dc00210000000000ed9034f000000000e0e043b000002400dd000390000000000ed0435000000010cc00039000000000dbc004b0000032c0000413d000000000c0a004b000003430000613d000000050bb002100000000009b9034f000000030aa00210000002400bb00039000000000c0b0433000000000cac01cf000000000cac022f000000000909043b000001000aa000890000000009a9022f0000000009a901cf0000000009c9019f00000000009b043500000240088000390000000000080435000002000070043f000001a00060043f0000002005500039000000220550035f000000000505043b000001c00050043f000000a00040043f0000004404200039000000220540035f000000000505043b0000130a0650009c0000006d0000813d000000c00050043f0000002004400039000000220440035f000000000404043b000013160540009c0000006d0000813d0000000004140019000000260540006900001308060000410000003f0750008c000000000700001900000000070620190000130805500197000000000805004b0000000006008019000013080550009c000000000607c019000000000506004b0000006d0000613d000000400500043d000013190650009c00001b020000813d000103690000003d00004bc00000013d000013160870009c0000006d0000813d0000000007470019000000260870006900001308090000410000003f0a80008c000000000a000019000000000a0920190000130808800197000000000b08004b0000000009008019000013080880009c00000000090ac019000000000809004b0000006d0000613d0000131a0850009c00001b020000213d0000008008500039000000000968004b00001b020000413d000000400080043f000000220870035f000000000808043b0000131709800197000000000998004b0000006d0000c13d000103850000003d00004baf0000013d000013160980009c0000006d0000813d000000000a7800190000001f07a0003900001308080000410001038c0000003d00004af60000013d0000130807700197000013080bb00197000000000cb7004b000000000800a0190000000007b7013f000013080770009c000000000809c019000000000708004b0000006d0000613d0000002207a0035f000000000707043b000013160870009c00001b020000813d0000003f08700039000000000938016f000000400800043d0000000009980019000000000b89004b00001b020000413d000013160b90009c00001b020000813d000103a30000003d00004a0a0000013d0000006d0000213d000000220ba0035f0025001f00700193000000050c700272000003b10000613d000000000d000019000000050ed00210000000000ae90019000000000eeb034f000000000e0e043b0000000000ea0435000000010dd00039000000000ecd004b000003a90000413d000000250d00006b000003b90000613d000000050cc00210000000000bcb034f000000000cc90019000000250a000029000103b90000003d000046820000013d000103bb0000003d000046f20000013d000000e00050043f0000008404200039000000220440035f000000000404043b000001000040043f000000a404200039000000220440035f000000000404043b000001200040043f000000c404200039000000220440035f000000000404043b000001400040043f000000e402200039000000220420035f000000000404043b0000131705400197000000000554004b0000006d0000c13d000001600040043f0000002002200039000000220220035f000000000202043b000013160420009c0000006d0000813d00000000051200190000001f0150003900001308020000410000002606000029000000000461004b0000000004000019000000000402401900001308011001970000130806600197000000000761004b000000000200a019000000000161013f000013080110009c000000000204c019000000000102004b0000006d0000613d000000220150035f000000000101043b000013160210009c00001b020000813d0000003f02100039000000000432016f000000400200043d0000000004420019000000000624004b00001b020000413d000013160640009c00001b020000813d000000400040043f000000000412043600000020055000390000000006150019000000260660006c0000006d0000213d000000220650035f0000001f0510018f0000000507100272000003fe0000613d0000000008000019000103fd0000003d000045760000013d000003fb0000413d000000000805004b000004020000613d000104020000003d000044790000013d00000000011400190000000000010435000001800020043f000000800100043d000000000200041100000000042f004b000004170000c13d0001040b0000003d0000481e0000013d000004100000613d00000000040000190001040f0000003d000048160000013d0000040d0000413d000000200400006b000004140000613d000104140000003d000044330000013d000104160000003d000046ed0000013d0000130902200197000000000312013f00001336020000410000000b010000390000130903300198000004210000c13d00001337020000410000001401000039000001000300043d000000000303004b00001a0b0000c13d000000400300043d000000440430003900000000002404350000002402300039000000000012043500000eb20000013d000013510280009c000008850000c13d0001042b0000003d000049840000013d0000000002000416000000000202004b0000006d0000c13d00001308020000410000009f0750008c000000000700001900000000070220190000130805500197000000000805004b0000000002008019000013080550009c000000000207c019000000000202004b0000006d0000613d000000000204043b002513090020019b000013090220009c0000006d0000213d000000000203043b001f13090020019b000013090220009c0000006d0000213d000000000101043b000013090110009c0000006d0000213d000000000106043b001d13090010019b0000130a0110009c0000006d0000813d001b0000000e001d001c0000000d001d000000000200041a001aff000020019400000000010000190000000101006039000004600000c13d009e00230000002d000104520000003d0000441d0000013d0000009e0440008a00000020044000c9001e00000002001d00001320020000414bfc43ed0000040f0000001e02000029000000000101004b0000045c0000613d000000ff01200190000004830000c13d000013540120019700000101021001bf000000000020041b000000000100001900000001011001900000002303000029000004740000613d009d00000003001d000104660000003d0000441d0000013d0000009d0440008a00000020044000c9001e00000002001d00001320020000414bfc43ed0000040f0000001e02000029000000000101004b000004700000613d000000ff01200190000004830000c13d000013540120019700000001021001bf000000000020041b0000002303000029001e00000002001d0019ff000020019400000ee70000c13d009c00000003001d0001047a0000003d0000441d0000013d0000009c0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000001e0200002900000ee30000613d000000ff0120019000000ee30000613d0000131001000041000000800010043f0000002001000039000000840010043f0000002e01000039000000a40010043f0000135501000041000000c40010043f0000135601000041000000e40010043f000000800100003900000084020000394bfc43c30000040f0000133f0180009c0000089b0000c13d0000000001000416000000000101004b0000006d0000c13d00001308010000410000003f0250008c000000000200001900000000020120190000130805500197000000000605004b0000000001008019000013080550009c000000000102c019000000000101004b0000006d0000613d000000000204043b00001317012001970000000005020019000000000112004b0000006d0000c13d000000000103043b002500000001001d0000130a0110009c0000006d0000813d000000000100041100000000021f004b000004bd0000c13d000104ae0000003d000047150000013d000004b30000613d0000000001000019000104b20000003d000046950000013d000004b00000413d00000000010a004b000004ba0000613d0000000501b00210000000000219034f0000000303a00210000104ba0000003d000044630000013d00000000000e043500000000010d043300001309011001970000003302000039000000000202041a000000000212013f00001343030000410000006501000039000001b40000013d000013470180009c000009910000c13d00240000000c001d000104c80000003d000049840000013d0000130801000041000104cb0000003d000048840000013d0000130803500197000000000503004b0000000001008019000013080330009c000000000102c019000000000101004b0000006d0000613d000000000204043b000013160120009c0000006d0000813d000000040120003900000026031000690000130804000041000001df0530008c000000000500001900000000050420190000130806300197000000000706004b0000000004008019000013080660009c000000000405c019000000000404004b0000006d0000613d000000a404200039000000220540035f000000000605043b00001309056001970000130a0660009c0000006d0000813d000000800000043f0000006006000039000000a00060043f000000e00060043f000000000605004b00000cc10000c13d0000134b05000041000000c00050043f001701000000003d001902000000003d001a01e00000003d001c01c00000003d001d01a00000003d001b01800000003d001601600000003d001f01400000003d001e01200000003d0000022005000039000000220600035f00000cd30000013d000013050680009c0000099d0000c13d00240000000c001d000105010000003d000049840000013d00001308060000410000007f0750008c000000000700001900000000070620190000130805500197000000000805004b0000000006008019000013080550009c000000000607c019000000000506004b0000006d0000613d000000000504043b000013150450009c0000006d0000213d0000000404500039000000260640006900001308070000410000011f0860008c000000000800001900000000080720190000130806600197000000000906004b0000000007008019000013080660009c000000000708c019000000000607004b0000006d0000613d000001a006000039000000400060043f000000220740035f000000000707043b0000130a0870009c0000006d0000813d000000800070043f0000002007400039000000220770035f000000000707043b000013160870009c0000006d0000813d0000000007470019000000260870006900001308090000410000003f0a80008c000000000a000019000000000a0920190000130808800197000000000b08004b0000000009008019000013080880009c00000000090ac019000000000809004b0000006d0000613d000001e008000039000000400080043f000000220970035f000000000909043b000013160a90009c0000006d0000813d000000000a7900190000002609a00069000013080b0000410000003f0c90008c000000000c000019000000000c0b20190000130809900197000000000d09004b000000000b008019000013080990009c000000000b0cc01900000000090b004b0000006d0000613d0000022009000039000000400090043f000000220ba0035f000000000b0b043b000013170cb00197000000000ccb004b0000006d0000c13d000001e000b0043f000000200ba00039000000220bb0035f000000000b0b043b000013160cb0009c0000006d0000813d000000000bab00190000001f0ab00039000013080c000041000000260e000029000000000dea004b000000000d000019000000000d0c4019000013080aa00197000013080ee00197000000000fea004b000000000c00a019000000000aea013f000013080aa0009c000000000c0dc019000000000a0c004b0000006d0000613d000000220ab0035f000000000a0a043b000013160ca0009c00001b020000813d0000025f0ca00039001f0020000000920000001f0cc0017f000002200dc0008a000013180dd0009c00001b020000813d0000004000c0043f0000022000a0043f000000200bb00039000000000cab0019000000260cc0006c0000006d0000213d000000220bb0035f001e001f00a00193000000050da00272000005820000613d000000000e000019000000050fe00210000000000cfb034f000000000c0c043b000002400ff000390000000000cf0435000000010ee00039000000000cde004b0000057a0000413d0000001e0c00006b000005920000613d000000050cd00210000000000bcb034f0000001e0d000029000000030dd00210000002400cc00039000000000e0c0433000000000ede01cf000000000ede022f000000000b0b043b000001000dd00089000000000bdb022f000000000bdb01cf000000000beb019f0000000000bc0435000002400aa0003900000000000a0435000002000090043f000001a00080043f0000002007700039000000220770035f000000000707043b000001c00070043f000000a00060043f0000004406500039000000220760035f000000000707043b0000130a0870009c0000006d0000813d000000c00070043f0000002006600039000000220660035f000000000606043b000013160760009c0000006d0000813d0000000006460019000000260760006900001308080000410000003f0970008c000000000900001900000000090820190000130807700197000000000a07004b0000000008008019000013080770009c000000000809c019000000000708004b0000006d0000613d000000400700043d000013190870009c00001b020000813d0000004008700039000000400080043f000000220960035f000000000909043b000013160a90009c0000006d0000813d0000000009690019000000260a900069000013080b0000410000003f0ca0008c000000000c000019000000000c0b2019000013080aa00197000000000d0a004b000000000b008019000013080aa0009c000000000b0cc019000000000a0b004b0000006d0000613d0000131a0a70009c00001b020000213d000000800a700039000000000b8a004b00001b020000413d0000004000a0043f000000220a90035f000000000a0a043b000013170ba00197000000000bba004b0000006d0000c13d0000000000a80435000000200a900039000000220aa0035f000000000a0a043b000013160ba0009c0000006d0000813d000000000c9a00190000001f09c00039000013080a000041000000260d000029000000000bd9004b000000000b000019000000000b0a40190000130809900197000013080dd00197000000000ed9004b000000000a00a0190000000009d9013f000013080990009c000000000a0bc01900000000090a004b0000006d0000613d0000002209c0035f000000000909043b000013160a90009c00001b020000813d0000003f0a9000390000001f0aa0017f000000400d00043d000000000bad0019001e0000000d001d000000000adb004b00001b020000413d000013160ab0009c00001b020000813d0000004000b0043f0000001e0a000029000000000b9a0436000000200cc00039000000000a9c0019000000260aa0006c0000006d0000213d000000220dc0035f001d001f00900193000000050e9002720000060b0000613d000000000f000019000000050cf00210000000000acb0019000000000ccd034f000000000c0c043b0000000000ca0435000000010ff00039000000000aef004b000006030000413d0000001d0a00006b0000061b0000613d000000050ae00210000000000cad034f000000000aab00190000001d0d000029000000030dd00210000000000e0a0433000000000ede01cf000000000ede022f000000000c0c043b000001000dd00089000000000cdc022f000000000cdc01cf000000000cec019f0000000000ca043500000000099b0019000000000009043500000060097000390000001e0a0000290000000000a9043500000000088704360000002006600039000000220660035f000000000606043b0000000000680435000000e00070043f0000008406500039000000220660035f000000000606043b000001000060043f000000a406500039000000220660035f000000000606043b000001200060043f000000c406500039000000220660035f000000000606043b000001400060043f000000e405500039000000220650035f000000000606043b0000131707600197000000000776004b0000006d0000c13d000001600060043f0000002005500039000000220550035f000000000505043b000013160650009c0000006d0000813d00000000074500190000001f0470003900001308050000410000002608000029000000000684004b0000000006000019000000000605401900001308044001970000130808800197000000000984004b000000000500a019000000000484013f000013080440009c000000000506c019000000000405004b0000006d0000613d000000220470035f000000000404043b000013160540009c00001b020000813d0000003f054000390000001f0650017f000000400500043d0000000006650019000000000856004b00001b020000413d000013160860009c00001b020000813d000000400060043f000000000645043600000020077000390000000008470019000000260880006c0000006d0000213d000000220870035f0000001f0740018f00000005094002720000066d0000613d000000000a000019000000050ba00210000000000cb60019000000000bb8034f000000000b0b043b0000000000bc0435000000010aa00039000000000b9a004b000006650000413d000000000a07004b0000067c0000613d0000000509900210000000000898034f00000000099600190000000307700210000000000a090433000000000a7a01cf000000000a7a022f000000000808043b0000010007700089000000000878022f00000000077801cf0000000007a7019f000000000079043500000000044600190000000000040435000001800050043f000000000303043b000013160430009c0000006d0000813d000000230430003900001308050000410000002607000029000000000674004b0000000006000019000000000605401900001308077001970000130804400197000000000874004b000000000500a019000000000474013f000013080440009c000000000506c019000000000405004b0000006d0000613d0000000405300039000000220350035f000000000403043b000013160340009c00001b020000813d0000003f034000390000001f0330017f000000400600043d0000000003360019001d00000006001d000000000663004b00001b020000413d000013160630009c00001b020000813d000000400030043f0000001d030000290000000003430436001e00000003001d00000020034000390000000006530019000000260660006c0000006d0000213d0000002005500039000000220650035f0000001f0540018f0000000504400272000006b50000613d000000000700001900000005087002100000001e09800029000000000886034f000000000808043b00000000008904350000000107700039000000000847004b000006ad0000413d000000000705004b000006c40000613d0000000504400210000000000646034f0000001e044000290000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f00000000005404350000001d033000290000000000030435000000000302043b000013160230009c0000006d0000813d0000000402300039000000260420006900001308050000410000011f0640008c000000000600001900000000060520190000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d000000400400043d001700000004001d0000131b0440009c00001b020000813d00000017040000290000012004400039000000400040043f000000220420035f000000000404043b0000130a0540009c0000006d0000813d00000017050000290000000004450436001b00000004001d0000002004200039000000220440035f000000000404043b000013160540009c0000006d0000813d0000000004240019000000260540006900001308060000410000003f0750008c000000000700001900000000070620190000130805500197000000000805004b0000000006008019000013080550009c000000000607c019000000000506004b0000006d0000613d000000400500043d000013190650009c00001b020000813d000106fb0000003d00004bc00000013d000013160870009c0000006d0000813d0000000007470019000000260870006900001308090000410000003f0a80008c000000000a000019000000000a0920190000130808800197000000000b08004b0000000009008019000013080880009c00000000090ac019000000000809004b0000006d0000613d0000131a0850009c00001b020000213d0000008008500039000000000968004b00001b020000413d000000400080043f000000220870035f000000000808043b0000131709800197000000000998004b0000006d0000c13d000107170000003d00004baf0000013d000013160980009c0000006d0000813d000000000a7800190000001f07a0003900001308080000410001071e0000003d00004af60000013d0000130807700197000013080bb00197000000000cb7004b000000000800a0190000000007b7013f000013080770009c000000000809c019000000000708004b0000006d0000613d0000002207a0035f000000000707043b000013160870009c00001b020000813d0000003f087000390000001f0980017f000000400800043d0000000009980019000000000b89004b00001b020000413d000013160b90009c00001b020000813d000107350000003d00004a0a0000013d0000006d0000213d000000220ba0035f0000001f0a70018f000000050c7002720000073e0000613d000000000d0000190001073d0000003d00004aab0000013d0000073b0000413d000000000d0a004b000007450000613d000000050cc00210000000000bcb034f000000000cc90019000107450000003d000046820000013d000107470000003d000046f20000013d0000001b0400002900000000005404350000004404300039000000220540035f000000000505043b0000130a0650009c0000006d0000813d00000017060000290000004006600039001900000006001d00000000005604350000002004400039000000220440035f000000000404043b000013160540009c0000006d0000813d0000000004240019000000260540006900001308060000410000003f0750008c000000000700001900000000070620190000130805500197000000000805004b0000000006008019000013080550009c000000000607c019000000000506004b0000006d0000613d000000400500043d000013190650009c00001b020000813d000107690000003d00004bc00000013d000013160870009c0000006d0000813d0000000007470019000000260870006900001308090000410000003f0a80008c000000000a000019000000000a0920190000130808800197000000000b08004b0000000009008019000013080880009c00000000090ac019000000000809004b0000006d0000613d0000131a0850009c00001b020000213d0000008008500039000000000968004b00001b020000413d000000400080043f000000220870035f000000000808043b0000131709800197000000000998004b0000006d0000c13d000107850000003d00004baf0000013d000013160980009c0000006d0000813d000000000a7800190000001f07a0003900001308080000410001078c0000003d00004af60000013d0000130807700197000013080bb00197000000000cb7004b000000000800a0190000000007b7013f000013080770009c000000000809c019000000000708004b0000006d0000613d0000002207a0035f000000000707043b000013160870009c00001b020000813d0000003f087000390000001f0980017f000000400800043d0000000009980019000000000b89004b00001b020000413d000013160b90009c00001b020000813d000107a30000003d00004a0a0000013d0000006d0000213d000000220ba0035f0000001f0a70018f000000050c700272000007ac0000613d000000000d000019000107ab0000003d00004aab0000013d000007a90000413d000000000d0a004b000007b30000613d000000050cc00210000000000bcb034f000000000cc90019000107b30000003d000046820000013d000107b50000003d000046f20000013d00000017060000290000006004600039001600000004001d00000000005404350000008404300039000000220440035f000000000404043b0000008005600039001800000005001d0000000000450435000000a404300039000000220440035f000000000404043b000000a005600039001500000005001d0000000000450435000000c404300039000000220440035f000000c005600039000000000404043b001400000005001d0000000000450435000000e403300039000000220430035f000000000404043b0000131705400197000000000554004b0000006d0000c13d0000001705000029000000e005500039001300000005001d00000000004504350000002003300039000000220330035f000000000303043b000013160430009c0000006d0000813d00000000052300190000001f0250003900001308030000410000002606000029000000000462004b0000000004000019000000000403401900001308022001970000130806600197000000000762004b000000000300a019000000000262013f000013080220009c000000000304c019000000000203004b0000006d0000613d000000220250035f000000000202043b000013160320009c00001b020000813d0000003f032000390000001f0430017f000000400300043d0000000004430019000000000634004b00001b020000413d000013160640009c00001b020000813d000000400040043f000000000423043600000020055000390000000006250019000000260660006c0000006d0000213d000000220650035f0000001f0520018f0000000507200272000008040000613d0000000008000019000108030000003d000045760000013d000008010000413d000000000805004b000008080000613d000108080000003d000044790000013d0000000002240019000000000002043500000017020000290000010002200039001200000002001d0000000000320435000000000101043b000013160210009c0000006d0000813d000000230210003900001308030000410000002605000029000000000452004b0000000004000019000000000403401900001308055001970000130802200197000000000652004b000000000300a019000000000252013f000013080220009c000000000304c019000000000203004b0000006d0000613d0000000403100039000000220130035f000000000201043b000013160120009c00001b020000813d0000003f012000390000001f0110017f000000400400043d0000000001140019001a00000004001d000000000441004b00001b020000413d000013160410009c00001b020000813d000000400010043f0000001a010000290000000001210436001c00000001001d00000020012000390000000004310019000000260440006c0000006d0000213d0000002003300039000000220430035f0000001f0320018f0000000502200272000008440000613d000000000500001900000005065002100000001c07600029000000000664034f000000000606043b00000000006704350000000105500039000000000625004b0000083c0000413d000000000503004b000008530000613d0000000502200210000000000424034f0000001c022000290000000303300210000000000502043300000000053501cf000000000535022f000000000404043b0000010003300089000000000434022f00000000033401cf000000000353019f00000000003204350000001a011000290000000000010435000001200100043d001100000001001d000000000101004b0000085f0000613d0001085b0000003d000045110000013d0000131c020000414bfc43ed0000040f000000110110006b000025740000813d000001400100043d001100000001001d000000000101004b000008690000613d000108650000003d000045110000013d0000131c020000414bfc43ed0000040f000000110110006b0000257b0000a13d000000800100043d000001000200043d000000000202004b000021bc0000c13d00001309011001980000253e0000613d0000000002000411000000230320006b000008810000c13d0000001f03000029000108750000003d0000481e0000013d0000087a0000613d0000000004000019000108790000003d000048160000013d000008770000413d000000200400006b0000087e0000613d0001087e0000003d000044330000013d000108800000003d000046ed0000013d00001309022001970000130902200197000000000112004b0000253e0000613d00000ea50000013d000013520180009c000009f30000c13d0000000001000416000000000101004b0000006d0000c13d00001308010000410001088d0000003d000048840000013d0000130803500197000000000503004b0000000001008019000013080330009c000000000102c019000000000101004b0000006d0000613d000000000104043b0000012f02000039000000200020043f00000000001004350001089a0000003d000049eb0000013d000009990000013d00230000000f001d000013400180009c00000a0b0000c13d0000000001000416000000000101004b0000006d0000c13d00001308010000410000005f0650008c000000000600001900000000060120190000130805500197000000000705004b0000000001008019000013080550009c000000000106c019000000000101004b0000006d0000613d000000000104043b002513090010019b000013090110009c0000006d0000213d000000000103043b002213110010019b000013120110009c0000006d0000813d000000000102043b002113110010019b002000000001001d000013110110009c0000006d0000213d00000000020004110000002303000029000000000123004b001f00000002001d000000000709034f00000000080b0019000008d90000c13d000108c20000003d000048b00000013d000000000108004b000008cd0000613d00000000010000190000000502100210000000000327034f000000000303043b000000a00220003900000000003204350000000101100039000000000281004b000008c50000413d00000000030a0019000000000103004b000008d50000613d0000000501800210000000000217034f0000000303300210000108d50000003d000044630000013d00000000000e043500000000010d043300001309021001970000002303000029000000330d00003900000000010d041a000000000221013f000013090220019800000ad20000c13d0000001f0230006c0000001f02000029000009000000c13d000000200200008a00000000032c016f000000400200043d0000000003230019000000400030043f00000026030000290000000003320436000000000408004b000008ee0000613d0000000004000019000108ed0000003d000045fb0000013d000008eb0000413d00000000040a004b000008fd0000613d0000000504b00210000000000549034f00000000044300190000000306a00210000000000704043300000000076701cf000000000767022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000575019f0000000000540435000108ff0000003d000046ed0000013d0000130902200197000000000121013f000013090110019800000ad20000c13d00240000000d001d000109060000003d000047f10000013d0000130901100197000109090000003d00004a9b0000013d0000130003000041000013000410009c0001090d0000003d00004a5f0000013d000013000420009c000109100000003d000049450000013d0000000002000414000013000420009c000109140000003d000048ac0000013d0000130b011001c70000800d02000039000000010300003900001342040000414bfc44050000040f00000001012001900000006d0000613d0000002603000029000000000103041a0000130d0210019700000025022001af000000000023041b0000001f03000029000000230230006b0000000002030019000009360000c13d00000000020000310000003f03200039000000200400008a000000000443016f0001092a0000003d000046cd0000013d0000092f0000613d00000000080000190001092e0000003d000045760000013d0000092c0000413d000000000805004b000009330000613d000109330000003d000044790000013d000109350000003d00004a190000013d00001309022001970000002403000029000000000303041a000000000223013f000013090220019800000ad20000c13d000000400200043d000000200320003900000022040000290000000000430435000000a0011002700000131101100197000109430000003d00004a9b0000013d0000130003000041000013000410009c000109470000003d00004a5f0000013d000013000420009c0001094a0000003d000049450000013d0000000002000414000013000420009c0001094e0000003d000048ac0000013d0000130b011001c70000800d0200003900000001030000390000133b040000414bfc44050000040f00000001012001900000006d0000613d0000002201000029000000a0021002100000002604000029000000000104041a0000133c03100197000000000223019f000000000024041b0000001f03000029000000230230006b000009710000c13d00000000020000310000003f03200039000000200400008a000000000443016f000109650000003d000046cd0000013d0000096a0000613d0000000008000019000109690000003d000045760000013d000009670000413d000000000805004b0000096e0000613d0001096e0000003d000044790000013d000109700000003d00004a190000013d001f13090020019b0000002402000029000000000202041a0000001f0220014f000013090220019800000ad20000c13d000000400200043d000000200320003900000021040000290000000000430435000000d0011002700001097d0000003d00004a9b0000013d0000130003000041000013000410009c000109810000003d00004a5f0000013d000013000420009c000109840000003d000049450000013d0000000002000414000013000420009c000109880000003d000048ac0000013d0000130b011001c70000800d02000039000000010300003900001313040000414bfc44050000040f00000001012001900000006d0000613d0000002001000029000009ee0000013d000013480180009c00000a4f0000c13d0000000001000416000000000101004b0000006d0000c13d0000016201000039000000000101041a0000130901100197000000800010043f0000008001000039000000200200003900004b320000013d00000000070b001900000000060a0019000013060180009c00000a890000c13d0000000001000416000000000101004b0000006d0000c13d0000130801000041000109a70000003d000048840000013d0000130803500197000000000503004b0000000001008019000013080330009c000000000102c019000000000101004b0000006d0000613d000000000204043b0000131101200197002500000002001d000013120220009c0000006d0000813d000000000200041100000000032f004b000009cc0000c13d000000200200008a000000240220017f000000400020043f0000002602000029000000800020043f000000000207004b000009c20000613d0000000002000019000109c00000003d00004afb0000013d000000000372004b000009be0000413d000000000206004b000009c90000613d0000000502700210000000000329034f0000000304600210000109c90000003d000048ff0000013d00000000000e043500000000020d043300001309022001970000003303000039000000000303041a000000000223013f000013090220019800000ad20000c13d0000016102000039002600000002001d000000000202041a000000400300043d00000020043000390000000000140435000000d0012002700000000000130435000000400100043d00000000021300490000130003000041000013000410009c000109df0000003d00004a5f0000013d000013000420009c000109e20000003d000049450000013d0000000002000414000013000420009c000109e60000003d000048ac0000013d0000130b011001c70000800d02000039000000010300003900001313040000414bfc44050000040f00000001012001900000006d0000613d0000002501000029000000d0011002100000002603000029000000000203041a0000131402200197000002260000013d000013530180009c0000006d0000c13d0000000001000416000000000101004b0000006d0000c13d0000130801000041000109fb0000003d000048840000013d0000130803500197000000000503004b0000000001008019000013080330009c000000000102c019000000000101004b0000006d0000613d000000000104043b0000130a0210009c0000006d0000813d00000000001004350000019301000039000000200010043f00010a0a0000003d000049eb0000013d0000017d0000013d000013410180009c0000006d0000c13d0000000001000416000000000101004b0000006d0000c13d000013080100004100010a130000003d000048840000013d0000130803500197000000000503004b0000000001008019000013080330009c000000000102c019000000000101004b0000006d0000613d000000000104043b002513090010019b0000130a0110009c0000006d0000813d0000000001000411000000230210006b00000a320000c13d00010a230000003d000047150000013d00000a280000613d000000000100001900010a270000003d000046950000013d00000a250000413d00000000010a004b00000a2f0000613d0000000501b00210000000000219034f0000000303a0021000010a2f0000003d000044630000013d00000000000e043500000000010d043300001309011001970000003302000039000000000202041a000000000112013f000013090110019800000ad20000c13d00010a390000003d000047f10000013d000013090110019700010a3c0000003d00004a9b0000013d0000130003000041000013000410009c00010a400000003d00004a5f0000013d000013000420009c00010a430000003d000049450000013d0000000002000414000013000420009c00010a470000003d000048ac0000013d0000130b011001c70000800d02000039000000010300003900001342040000414bfc44050000040f000000010120019000000ec70000c13d0000006d0000013d000013490180009c0000006d0000c13d0000000001000416000000000101004b0000006d0000c13d000000000100041100000000021f004b00000a6b0000c13d00010a590000003d000048b00000013d00000000050b0019000000000105004b000000000409034f00000a610000613d000000000100001900010a600000003d00004a6f0000013d00000a5e0000413d00000000010a004b00000a680000613d0000000501500210000000000214034f0000000303a0021000010a680000003d000044630000013d00000000000e043500000000010d043300001309011001970000003303000039000000000203041a00001309052001970000130901100197000000000115004b00000ad20000c13d002600000003001d000000400100043d00001300020000410000000003000414000013000430009c0000000003028019000013000410009c00000000010280190000004001100210000000c002300210000000000112019f0000130b011001c70000800d0200003900000003030000390000130c0400004100000000060000194bfc44050000040f00000001012001900000006d0000613d0000002602000029000000000102041a0000130d01100197000000000012041b000002a90000013d000013070180009c0000006d0000c13d0000000001000416000000000101004b0000006d0000c13d000013080100004100010a910000003d000048840000013d0000130803500197000000000503004b0000000001008019000013080330009c000000000102c019000000000101004b0000006d0000613d000000000104043b002513090010019b0000130a0110009c0000006d0000813d000000000100041100000000021f004b00000ab60000c13d00010aa10000003d000048b00000013d000000000107004b00000aac0000613d00000000010000190000000502100210000000000329034f000000000303043b000000a00220003900000000003204350000000101100039000000000271004b00000aa40000413d000000000106004b00000ab30000613d0000000501700210000000000219034f000000030360021000010ab30000003d000044630000013d00000000000e043500000000010d0433000013090110019700001309051001970000003302000039000000000102041a0000130901100197000000000151004b00000ad20000c13d002600000002001d000000400200043d0000002506000029000000000106004b00000eb70000c13d00000064012000390000130e03000041000000000031043500000044012000390000130f03000041000000000031043500000024012000390000002603000039000000000031043500001310010000410000000000120435000000040120003900000020030000390000000000310435000000400100043d000000000212004900004b550000013d000000400200043d00000044012000390000134e0300004100000000003104350000131001000041000000000012043500000024012000390000002003000039000000000031043500000004012000390000000000310435000000400100043d000000000212004900000064022000394bfc43c30000040f0000134a05000041000000c00050043f000001200040043f0000002004000039000001000040043f0000010004000039000000e00040043f002501400000003d001802400000003d001902200000003d001e02000000003d001f01e00000003d001d01c00000003d001c01a00000003d001b01800000003d001a01600000003d0000026004000039000000220500035f000000400040043f000000a00330008a000000000435034f000000000404043b0000130a0540009c0000006d0000813d00000025050000290000000000450435000000400c00043d0000008004c00039000000400040043f0000004003300039000000220430035f000000000404043b0000131705400197000000000554004b0000006d0000c13d000000400dc0003900000000004d0435000000200b3000390000002203b0035f000000000303043b0000001f0220008a000013080530019700001308062001970000130807000041000000000865004b00000000080000190000000008072019000000000565013f000000000623004b0000000007008019000013080550009c000000000807c019000000000508004b0000006d0000613d0000000005130019000000220350035f000000000303043b000013160630009c0000006d0000813d000000260630006900000020055000390000130807000041000000000865004b0000000008000019000000000807201900001308066001970000130809500197000000000a69004b0000000007008019000000000669013f000013080660009c000000000708c019000000000607004b0000006d0000c13d0000001f063000390000134c06600197001600200060003d000000400e00043d0000001606e00029000000400060043f000000220550035f0015001f00300193000000000f3e0436000000050730027200000b3f0000613d00000000080000190000000509800210000000000a9f0019000000000995034f000000000909043b00000000009a04350000000108800039000000000978004b00000b370000413d0017006000c0003d0000001509000029000000000609004b0013000500700218001400030090021800000b510000613d0000001309500360000000130af0002900000000060a0433000000140800002900000000068601cf0012000000860237000000000609043b0000010009800089000000000696022f00000000069601cf00000012066001af00000000006a043500000000063f0019000000000006043500000017060000290000000000e604350000000006dc04360000004008b0008a000000220880035f000000000808043b00000000008604350000001a060000290000000000c604350000001b060000290000000000060435000000400600043d0000004008600039000000400080043f000000c00c0000390000000008c604360000002009b00039000000220990035f000000000909043b00000000009804350000001c0800002900000000006804350000006006b00039000000220660035f000000000606043b0000001d0800002900000000006804350000008006b00039000000220660035f000000000606043b0000001f080000290000000000680435000000a006b00039000000220660035f000000000606043b0000001e080000290000000000680435000000c009b00039000000220690035f000000000b06043b0000131706b0019700000000066b004b0000006d0000c13d00000019060000290000000000b604350000002008900039001700000008001d000000220980035f000000000909043b000013080a000041000000000d29004b000000000d000019000000000d0a4019000013080e200197000013080f9001970000000008ef004b000000000a00a0190000000008ef013f000013080880009c000000000a0dc01900000000080a004b0000006d0000613d0000000009190019000000220690035f000000000606043b001200000006001d000013160660009c0000006d0000813d0000001208000029000000260680006900000020099000390000130808000041000000000a69004b000000000a000019000000000a0820190000130806600197000013080d900197000000000e6d004b000000000800801900000000066d013f000013080660009c00000000080ac019000000000608004b0000006d0000c13d000000120a0000290000001f08a000390000134c08800197000000400e00043d000000200fe0003900000000088f0019000000400080043f000000220d90035f00100000000e001d0000000000ae04350011001f00a001930000000509a0027200000bbd0000613d000000000a0000190000000508a00210000000000e8f001900000000088d034f000000000808043b00000000008e0435000000010aa0003900000000089a004b00000bb50000413d000000110600006b00000bcd0000613d000000050890021000000000098d034f00000000088f00190000001106000029000000030a600210000000000d080433000000000dad01cf000000000dad022f000000000909043b000001000aa000890000000009a9022f0000000009a901cf0000000009d9019f00000000009804350000001208f000290000000000080435000000180600002900000010080000290000000000860435000000400600043d0000012008600039000000400080043f0000000008060436000000400900043d000000400a9000390000004000a0043f000000000ac90436000000170c000029000000400cc00039000000220dc0035f000000000d0d043b0000000000da04350000000000980435001700000006001d00000040086000390000000000080435000000400d00043d0000008008d00039000000400080043f000000400ed0003900000000004e0435000000400400043d0000001608400029000000400080043f000000000a340436000000000807004b00000bf70000613d00000000090000190000000508900210000000000f8a0019000000000885034f000000000808043b00000000008f04350000000109900039000000000879004b00000bef0000413d0000001706000029001600600060003d0000006007d00039000000150600006b00000c080000613d00000013055003600000001306a000290000000008060433000000140900002900000000089801cf000000000898022f000000000505043b0000010009900089000000000595022f00000000059501cf000000000585019f000000000056043500000000033a0019000000000003043500000000004704350000000003ed04360000002004c00039000000220440035f000000000404043b000000000043043500000016030000290000000000d304350000001704000029000000e0034000390000000000b30435000000c0034000390000000000030435000000a0034000390000000000030435000000800340003900000000000304350000004003c00039000000220430035f000000000404043b00001308052001970000130806000041000000000724004b000000000700001900000000070640190000130808400197000000000958004b000000000600a019000000000558013f000013080550009c000000000607c019000000000506004b0000006d0000613d0000000005140019000000220450035f000000000404043b000013160640009c0000006d0000813d000000260640006900000020075000390000130805000041000000000867004b0000000008000019000000000805201900001308066001970000130809700197000000000a69004b0000000005008019000000000669013f000013080660009c000000000508c019000000000505004b0000006d0000c13d0000001f054000390000134c0850019700010c430000003d00004a100000013d00000c480000613d000000000a00001900010c470000003d00004a3b0000013d00000c450000413d000000170a000029000001000aa00039000000000b08004b00000c4e0000613d00010c4e0000003d000047530000013d0000000004460019000000000004043500000000005a0435000000600330008a000000220330035f000000000303043b0000130804000041000000000523004b0000000005000019000000000504401900001308022001970000130806300197000000000726004b000000000400a019000000000226013f000013080220009c000000000405c019000000000204004b0000006d0000613d0000000002130019000000220120035f000000000101043b000013160310009c0000006d0000813d000000260310006900000020022000390000130804000041000000000532004b0000000005000019000000000504201900001308033001970000130806200197000000000736004b0000000004008019000000000336013f000013080330009c000000000405c019000000000304004b0000006d0000c13d0000001f031000390000134c03300197000000400400043d00000020084000390000000003380019000000400030043f000000220220035f001300000004001d00000000001404350000001f0310018f000000050410027200000c870000613d00000000050000190000000506500210000000000768001900010c860000003d000045be0000013d00000c820000413d001500000008001d000000000503004b00000c8f0000613d0000000504400210000000000242034f000000150440002900010c8f0000003d0000446e0000013d000000150110002900000000000104350000001f010000290000000001010433001400000001001d000000000101004b00000c9c0000613d00010c980000003d000045110000013d0000131c020000414bfc43ed0000040f000000140110006b000025740000813d0000001e010000290000000001010433001400000001001d000000000101004b00000ca70000613d00010ca30000003d000045110000013d0000131c020000414bfc43ed0000040f000000140110006b0000257b0000a13d000000250100002900000000010104330000001d020000290000000002020433000000000202004b000010e70000c13d0000130901100198000011910000613d0000000002000411000000230320006b00000ea20000c13d00010cb40000003d0000457e0000013d00000cb90000613d000000000400001900010cb80000003d000045fb0000013d00000cb60000413d000000200400006b00000cbd0000613d00010cbd0000003d000044330000013d00010cbf0000003d000046ed0000013d000013090220019700000ea20000013d0000134a06000041000000c00060043f000001200050043f0000002005000039000001000050043f0000010005000039000000e00050043f001701400000003d001902400000003d001a02200000003d001c02000000003d001d01e00000003d001b01c00000003d001601a00000003d001f01800000003d001e01600000003d0000026005000039000000220600035f000000400050043f000000a00540008a000000000456034f000000000404043b0000130a0640009c0000006d0000813d00000017060000290000000000460435000000400600043d0000004004600039000000400040043f000000c00400003900000000074604360000008008500039000000220880035f000000000808043b00000000008704350000001e0700002900000000006704350000001f060000290000000000060435000000400d00043d0000008006d00039000000400060043f0000004005500039000000220650035f000000000606043b0000131707600197000000000776004b0000006d0000c13d000000400fd0003900000000006f0435000000200e5000390000002205e0035f000000000505043b0000001f0330008a000013080750019700001308083001970000130809000041000000000a87004b000000000a000019000000000a092019000000000787013f000000000835004b0000000009008019000013080770009c000000000a09c01900000000070a004b0000006d0000613d0000000007150019000000220570035f000000000505043b000013160850009c0000006d0000813d000000260850006900000020077000390000130809000041000000000a87004b000000000a000019000000000a0920190000130808800197000013080b700197000000000c8b004b000000000900801900000000088b013f000013080880009c00000000090ac019000000000809004b0000006d0000c13d0000001f085000390000134c08800197001200200080003d000000400900043d0000001208900029000000400080043f000000220770035f0018001f00500193002500000009001d000000000c590436000000050950027200000d2d0000613d000000000a0000190000000508a00210000000000b8c0019000000000887034f000000000808043b00000000008b0435000000010aa0003900000000089a004b00000d250000413d0015006000d0003d000000180a00002900000000080a004b00130005009002180014000300a0021800000d410000613d0011001300700364000000130bc0002900000000080b0433000000140a0000290000000008a801cf0010000000a80237000000110800035f000000000808043b001100000008001d0000010008a00089000000110a80024f00000000088a01cf00000010088001af00000000008b043500000000085c001900000000000804350000002508000029000000150a00002900000000008a04350000000008fd0436000000400ae0008a000000220aa0035f000000000a0a043b0000000000a8043500000016080000290000000000d804350000006008e00039000000220880035f000000000808043b0000001b0a00002900000000008a04350000008008e00039000000220880035f000000000808043b0000001d0a00002900000000008a0435000000a008e00039000000220880035f000000000808043b0000001c0a00002900000000008a0435000000c00ae000390000002208a0035f000000000d08043b0000131708d0019700000000088d004b0000006d0000c13d0000001a080000290000000000d80435000000200aa00039000000220aa0035f000000000a0a043b000013080b000041000000000c3a004b000000000c000019000000000c0b4019000013080e300197000013080fa001970000000008ef004b000000000b00a0190000000008ef013f000013080880009c000000000b0cc01900000000080b004b0000006d0000613d000000000a1a00190000002208a0035f000000000808043b002500000008001d000013160880009c0000006d0000813d000000250b0000290000002608b00069000000200ca00039000013080a000041000000000b8c004b000000000b000019000000000b0a20190000130808800197000013080ec00197000000000f8e004b000000000a00801900000000088e013f000013080880009c000000000a0bc01900000000080a004b0000006d0000c13d000000250a0000290000001f08a000390000134c08800197000000400e00043d000000200be0003900000000088b0019000000400080043f000000220cc0035f00110000000e001d0000000000ae04350015001f00a00193000000050fa0027200000da00000613d000000000a0000190000000508a00210000000000e8b001900000000088c034f000000000808043b00000000008e0435000000010aa000390000000008fa004b00000d980000413d000000150800006b00000db00000613d0000000508f00210000000000a8c034f00000000088b0019000000150c000029000000030cc00210000000000e080433000000000ece01cf000000000ece022f000000000a0a043b000001000cc00089000000000aca022f000000000aca01cf000000000aea019f0000000000a804350000002508b0002900000000000804350000001908000029000000110a0000290000000000a80435000000400a00043d0000012008a00039000000400080043f00250000000a001d00000000080a0436001500000008001d000000400f00043d0000008008f00039000000400080043f000000400bf0003900000000006b0435000000400600043d0000001208600029000000400080043f000000000c560436000000000809004b00000dcf0000613d000000000a0000190000000508a00210000000000e8c0019000000000887034f000000000808043b00000000008e0435000000010aa0003900000000089a004b00000dc70000413d0000006009f00039000000180800006b00000dde0000613d00000013077003600000001308c00029000000000a080433000000140e000029000000000aea01cf000000000aea022f000000000707043b000001000ee000890000000007e7022f0000000007e701cf0000000007a7019f000000000078043500000000055c0019000000000005043500000000006904350000000005bf0436000001a406200039000000220660035f000000000606043b000000000065043500000015050000290000000000f50435000000250700002900000040057000390000000000050435000000400500043d0000004006500039000000400060043f00000000044504360000018406200039000000220660035f000000000606043b0000000000640435000000e0047000390000000000d4043500000060047000390000000000540435000000c0047000390000000000040435000000a004700039000000000004043500000080047000390000000000040435000001c402200039000000220420035f000000000404043b00001308053001970000130806000041000000000734004b000000000700001900000000070640190000130808400197000000000958004b000000000600a019000000000558013f000013080550009c000000000607c019000000000506004b0000006d0000613d0000000005140019000000220450035f000000000404043b000013160640009c0000006d0000813d000000260640006900000020075000390000130805000041000000000867004b0000000008000019000000000805201900001308066001970000130809700197000000000a69004b0000000005008019000000000669013f000013080660009c000000000508c019000000000505004b0000006d0000c13d0000001f054000390000134c0850019700010e250000003d00004a100000013d00000e2a0000613d000000000a00001900010e290000003d00004a3b0000013d00000e270000413d000000250a000029000001000aa00039000000000b08004b00000e300000613d00010e300000003d000047530000013d0000000004460019000000000004043500000000005a0435000000600220008a000000220220035f000000000202043b0000130804000041000000000532004b0000000005000019000000000504401900001308033001970000130806200197000000000736004b000000000400a019000000000336013f000013080330009c000000000405c019000000000304004b0000006d0000613d0000000002120019000000220120035f000000000101043b000013160310009c0000006d0000813d000000260310006900000020022000390000130804000041000000000532004b0000000005000019000000000504201900001308033001970000130806200197000000000736004b0000000004008019000000000336013f000013080330009c000000000405c019000000000304004b0000006d0000c13d0000001f031000390000134c03300197000000400400043d00000020084000390000000003380019000000400030043f000000220220035f001400000004001d00000000001404350000001f0310018f000000050410027200000e690000613d00000000050000190000000506500210000000000768001900010e680000003d000045be0000013d00000e640000413d001800000008001d000000000503004b00000e710000613d0000000504400210000000000242034f000000180440002900010e710000003d0000446e0000013d000000180110002900000000000104350000001d010000290000000001010433001500000001001d000000000101004b00000e7e0000613d00010e7a0000003d000045110000013d0000131c020000414bfc43ed0000040f000000150110006b000025740000813d0000001c010000290000000001010433001500000001001d000000000101004b00000e890000613d00010e850000003d000045110000013d0000131c020000414bfc43ed0000040f000000150110006b0000257b0000a13d000000170100002900000000010104330000001b020000290000000002020433000000000202004b0000117d0000c13d0000130901100198000011910000613d0000000002000411000000230320006b00000ea20000c13d00010e960000003d0000457e0000013d00000e9b0000613d000000000400001900010e9a0000003d000045fb0000013d00000e980000413d000000200400006b00000e9f0000613d00010e9f0000003d000044330000013d00010ea10000003d000046ed0000013d00001309022001970000130902200197000000000112004b000011910000613d000000400200043d00000044012000390000136303000041000000000031043500000024012000390000001603000039000025810000013d000000440130003900001390020000410000000000210435000000240130003900000017020000390000000000210435000013100100004100000000001304350000000401300039000000200200003900000ede0000013d00001300010000410000000003000414000013000430009c0000000003018019000013000420009c00000000020180190000004001200210000000c002300210000000000112019f0000130b011001c70000800d0200003900000003030000390000130c040000414bfc44050000040f00000001012001900000006d0000613d0000002603000029000000000103041a0000130d0110019700000025011001af000000000013041b000002a90000013d000000400100043d002000000001001d000000200110008a0000000001010433000013090110019800000f650000c13d000000200300002900000044013000390000139802000041000000000021043500000024013000390000001102000039000000000021043500001310010000410000000000130435000000040130003900000026020000290000000000210435000000400100043d000000000213004900000064022000394bfc43c30000040f000013540120019700000101011001bf000000000010041b000000230300002900000080010000390000000002000411000000000323004b00000f040000c13d00010eed0000003d000048b00000013d0000002105000029000000000105004b000000220400035f00000ef50000613d000000000100001900010ef40000003d00004a6f0000013d00000ef20000413d000000200100006b00000efe0000613d00000021010000290000000501100210000000220210035f0000002003000029000000030330021000010efe0000003d000044630000013d0000001b010000290000000000010435000000400100043d0000001c020000290000000002020433000013090220019700001309062001970000003302000039000000000302041a0000130d03300197000000000363019f000000000032041b00001300020000410000000003000414000013000430009c0000000003028019000013000410009c00000000010280190000004001100210000000c002300210000000000112019f0000130b011001c70000800d0200003900000003030000390000130c0400004100000000050000194bfc44050000040f00000001012001900000006d0000613d000000000200041a000000190100006b00000f210000c13d0000135701000041000000000212016f000000000020041b002600000002001d0024ff00002001940000000001000019000000010100603900000f380000c13d009b00230000002d00010f290000003d0000441d0000013d0000009b0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b00000f320000613d0000002601000029000000ff0110019000000f5b0000c13d0000002601000029000013540110019700000101011001bf002600000001001d000000000010041b0000000001000019000000400400043d0000004002400039000000400020043f00000020034000390000135802000041001e00000003001d00000000002304350000000802000039001c00000004001d0000000000240435000000400400043d0000004002400039000000400020043f00000020034000390000135902000041002100000003001d00000000002304350000000102000039002200000002001d002000000004001d0000000000240435000000010110019000000f790000613d009500230000002d00010f520000003d0000441d0000013d000000950440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b00000f8e0000613d0000002601000029000000ff0110019000000f8e0000613d000000400200043d00000064012000390000135603000041000000000031043500000044012000390000135503000041000000000031043500000024012000390000002e0300003900000ac90000013d000000250110006c00000f7c0000c13d000000250100002900000000001004350000001b01000029000000200010043f000000400200003900000000010000194bfc43d70000040f000000000201041a000000010300008a000000000332004b0000100e0000c13d000000200300002900000044013000390000138702000041000000000021043500000024013000390000001b0200003900000ed90000013d00010f7b0000003d000047290000013d00000f950000013d000000200300002900000064013000390000139402000041000000000021043500000044013000390000139502000041000000000021043500000024013000390000002102000039000000000021043500001310010000410000000000130435000000040130003900000026020000290000000000210435000000400100043d000000000213004900004b550000013d00010f900000003d000047290000013d0000002601000029000013540110019700000001011001bf002600000001001d000000000010041b000000240100006b00000f9b0000c13d0000135701000041000000260210017f002600000002001d000000000020041b000000400200043d0000004001200039000000400010043f00000020012000390000135a0300004100000000003104350000000e030000390000000000320435000000400400043d002400000004001d0000004003400039000000400030043f0000002005400039002100000005001d0000135b0300004100000000003504350000002203000029000000000034043500000000020204334bfc43d70000040f00000024020000290000000002020433002400000001001d00000021010000294bfc43d70000040f002200000001001d00010fb70000003d000045110000013d00001321020000414bfc43ed0000040f0000135c02000041000000400400043d000000200340003900000000002304350000004002400039000000240300002900000000003204350000006002400039000000220300002900000000003204350000002302000029000013090220019700000080034000390000000000230435000000a00240003900010fca0000003d00004b850000013d002400000004001d000000c002400039002200000002001d000000400020043f00000000020304334bfc43d70000040f0000019402000039000000000012041b0000009701000039000000200010043f0000135d01000041000000000201041a0000130d022001970000001f022001af000000000021041b0000135e01000041000000000201041a0000130d0220019700000025022001af000000000021041b0000135f0100004100000000001004350000136001000041000000000201041a0000130d0220019700000025022001af000000000021041b00000026010000290000ff0001100190000010080000c13d009a00230000002d00010feb0000003d0000441d0000013d0000009a0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b000010880000613d0000002601000029000000ff01100190000010880000613d0000131001000041000000220200002900000000001204350000002403000029000001240130003900001356020000410000000000210435000001040130003900001355020000410000000000210435000000e4013000390000002e020000390000000000210435000000c40130003900000020020000390000000000210435000000400100043d000000000213004900000144022000394bfc43c30000040f0000016201000039000000000201041a0000130d022001970000001d022001af000000000021041b000010920000013d0000000102200039000000000021041b000000a00500003900000020010000290000002001100039000000800200043d0000000004020019000000000301001900000000560504340000001f0740008c0000101c0000a13d0000000003630436000000200440008a000010160000013d00000003054002100000010005500089000000010550020f000000000404004b00000000050060190000000004500049000000000446016f000000010550008a0000000006030433000000000556016f000000000445019f00000000004304350000000001120019000000240200002900000060022002100000000000210435000000400200043d00000000032100490000000c0330008a00000000003204350000001404100039000000400040043f000000000502043300000000030500190000000001040019000000200220003900000000060204330000001f0730008c0000103c0000a13d0000000001610436000000200330008a000010350000013d00000003023002100000010002200089000000010220020f000000000303004b00000000020060190000000003200049000000000336016f000000010220008a0000000006010433000000000226016f000000000232019f0000000000210435000000400300043d000000000100041400000023020000290000130902200197000000040620008c000010540000613d00000000044500190000000004340049000000000503001900000000060000194bfc000d0000040f002100000001001d002400600000003d00000001040000320000107a0000613d0000003f01400039000000220110017f000000400200043d0000000001120019000000400010043f0000001f0140018f002400000002001d0000000002420436000000030300036700000005044002720000106b0000613d000000000500001900000005065002100000000007620019000000000663034f000000000606043b00000000006704350000000105500039000000000645004b000010630000413d000000000501004b0000107a0000613d0000000504400210000000000343034f00000000024200190000000301100210000000000402043300000000041401cf000000000414022f000000000303043b0000010001100089000000000313022f00000000011301cf000000000141019f0000000000120435000000400200043d000000210100006b000010980000c13d00000044012000390000139703000041000000000031043500000024012000390000001c030000390000000000310435000013100100004100000000001204350000000401200039000000260300002900000adc0000013d0000016201000039000000000201041a0000130d022001970000001d022001af000000000021041b0000002601000029000013540110019700000001011001bf002600000001001d000000000010041b0000001a0100006b000002a90000c13d0000135701000041000000260110017f000000000010041b000002a90000013d0000004001200039000000600300003900000000003104350000000001000411000013090110019700000020032000390000000000130435000000250100002900000000001204350000006001200039000000800300043d00000000003104350000008001200039000000800200043d0000000003000019000000000423004b000010af0000813d0000000004130019000000a005300039000000000505043300000000005404350000002003300039000010a70000013d00000000011200190000001f02200190000010b90000613d0000000003210049000000030120021000000100021000890000000014030434000000000424022f00000000022401cf0000000000230435000000400200043d00000000012100490000130003000041000013000420009c00000000020380190000004002200210000013000410009c00000000010380190000006001100210000000000121019f0000000002000414000013000420009c000110c70000003d000048ac0000013d0000130b011001c70000800d02000039000000010300003900001396040000414bfc44050000040f00000001012001900000006d0000613d000000400200043d0000002601000029000000000312043600000024060000290000000001060433000000000013043500000040022000390000000003000019000000000413004b000010de0000813d00000000042300190000002003300039000000000563001900000000050504330000000000540435000010d60000013d000000000313004b000010e20000a13d000000000321001900000000000304350000001f01100039000000220110017f0000000002120019000000400100043d000001800000013d0000000002000411000000230320006b000010f80000c13d000110ec0000003d0000457e0000013d000010f10000613d0000000004000019000110f00000003d000045fb0000013d000010ee0000413d000000200400006b000010f50000613d000110f50000003d000044330000013d000110f70000003d000046ed0000013d0000130902200197000000000112013f0000130901100198000011910000613d0000001a0100002900000000010104330000000021010434002200000002001d0000000012010434002600000002001d00000000010104330000002502000029002500000002001d000111060000003d000049d60000013d0000131702200197000111090000003d000049110000013d0000131d030000410001110c0000003d0000448d0000013d0000131e030000410001110f0000003d000045d80000013d0000001b020000290000000002020433002200000002001d0000001c0200002900000000020204330000000032020434002000000003001d0000000023020434001c00000003001d0000000002020433002100000001001d00000000120204344bfc43d70000040f0000001c020000290000131702200197000111200000003d000049ae0000013d0000131d03000041000111230000003d000045020000013d0000131e05000041000111260000003d0000453e0000013d0000001d020000290000000002020433002000000002001d0000001f020000290000000002020433001f00000002001d0000001e020000290000000002020433001d00000002001d00000019020000290000000002020433001c00000002001d00000018020000290000000002020433001e00000001001d00000000120204344bfc43d70000040f0000001c0200002900001317022001970001113b0000003d000045650000013d00001309022001970001113e0000003d000048f80000013d0000130902200197000002400340003900000000002304350000131f02000041000111440000003d000048740000013d00000025020000290000000002020433002400000002001d003e13090020019b002200000001001d0001114b0000003d0000441d0000013d0000003e0440008a00000020044000c90000132002000041000111500000003d00004bcc0000013d000111520000003d000045110000013d0000132102000041000111550000003d0000471c0000013d0000132202000041000111580000003d0000486e0000013d00001309011001970001115b0000003d000045c40000013d00001323020000410001115e0000003d000046a90000013d002413090020019b000111610000003d0000468d0000013d000011c50000c13d00000013060000290000000006060433000000410660008c0000126f0000c13d00000015060000290000000006060433002100000006001d00000013070000290001116c0000003d000048680000013d000013280770009c0000130e0000813d000000f8076002700000132b0660009c000004a206900039000017db0000813d0000001b0870008a000000020880008c000017f50000813d0000002202000029000111780000003d000044f30000013d0000000001000414000000200530008a00000001020000390000002006000039000017e60000013d0000000002000411000000230320006b0000118e0000c13d000111820000003d0000457e0000013d000011870000613d0000000004000019000111860000003d000045fb0000013d000011840000413d000000200400006b0000118b0000613d0001118b0000003d000044330000013d0001118d0000003d000046ed0000013d0000130902200197000000000112013f0000130901100198000011d50000c13d000111930000003d000049dc0000013d00000000003204350000000000010435000111970000003d0000491d0000013d00000025010000290000002001100039001f00000001001d00000000010104330000000005010433000000160100002900000000010104330000000004010433000111a10000003d0000491d0000013d000111a30000003d00004b800000013d002200000003001d00000000003204350000000000010435002000000004001d0000000012040434002400000002001d001d00000001001d002600000005001d0000000021050434001e00000002001d0000131701100197002100000001001d0000134b0110009c000011b50000c13d000000240100002900001317011001970000134b0110009c000012d40000013d00000021010000290000134a0110009c000011bd0000c13d000000240100002900001317011001970000134a0110009c000012d60000c13d000012c80000013d0000002101000029000013640110009c000012670000c13d00000024010000290000131701100197000013640110009c000012d60000c13d000012c80000013d00001324060000410000002207000029000111c90000003d000049ff0000013d0000001302000029000111cc0000003d000049610000013d0000001506000029000000000412004b000012450000813d00000000043200190000000005620019000000000505043300000000005404350000002002200039000011cd0000013d0000001e01000029000111d80000003d00004adf0000013d001700000002001d000111db0000003d000049d60000013d0000131702200197000111de0000003d000049110000013d0000131d03000041000111e10000003d0000448d0000013d0000131e03000041000111e40000003d000045d80000013d0000001f02000029000111e70000003d000047c70000013d0000131702200197000111ea0000003d000049ae0000013d0000131d03000041000111ed0000003d000045020000013d0000131e05000041000111f00000003d0000453e0000013d0000001b020000290000000002020433002000000002001d0000001d020000290000000002020433001f00000002001d0000001c020000290000000002020433001d00000002001d0000001a020000290000000002020433001c00000002001d00000019020000290000000002020433001e00000001001d00000000120204344bfc43d70000040f0000001c020000290000131702200197000112050000003d000045650000013d0000130902200197000112080000003d000048f80000013d0000130902200197000002400340003900000000002304350000131f020000410001120e0000003d000047610000013d002400000002001d003d13090020019b002200000001001d000112130000003d0000441d0000013d0000003d0440008a00000020044000c90000132002000041000112180000003d00004bcc0000013d0001121a0000003d000045110000013d00001321020000410001121d0000003d0000471c0000013d0000132202000041000112200000003d0000486e0000013d0000130901100197000112230000003d000045c40000013d0000132302000041000112260000003d000046a90000013d002413090020019b000112290000003d0000468d0000013d0000127c0000c13d00000014060000290000000006060433000000410660008c0000126f0000c13d00000018060000290000000006060433002100000006001d0000001407000029000112340000003d000048680000013d000013280770009c0000130e0000813d000000f8076002700000132b0660009c000004a2069000390000194c0000813d0000001b0870008a000000020880008c000019650000813d0000002202000029000112400000003d000044f30000013d0000000001000414000000200530008a00000001020000390000002006000039000019570000013d002600000031001d0000001f011001900000124a0000613d0001124a0000003d000047050000013d000000400100043d002200000001001d009900240000002d0001124f0000003d0000441d0000013d000000990440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002402000029000000040220008c0000125e0000613d0001125b0000003d00004a770000013d000001560000613d000000400100043d002200000001001d00000001010000310000001f0110008c0000006d0000a13d000000220100002900000000010104330000131701100197000013240110009c000011910000613d000012ad0000013d00000021010000290000135f0110009c000012bc0000c13d000000240100002900001317011001970000135f0110009c000012d60000c13d000012c80000013d000013100100004100000022030000290000000000130435000013270100004100000000001504350000001f01000039000000000014043500000020010000390000000000120435000000400100043d0000000002190049000004e6022000394bfc43c30000040f00001324060000410000002207000029000112800000003d000049ff0000013d0000001402000029000112830000003d000049610000013d0000001806000029000000000412004b0000128c0000813d00000000043200190000000005620019000000000505043300000000005404350000002002200039000012840000013d002600000031001d0000001f01100190000012910000613d000112910000003d000047050000013d000000400100043d002200000001001d009800240000002d000112960000003d0000441d0000013d000000980440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002402000029000000040220008c000012a50000613d000112a20000003d00004a770000013d000001560000613d000000400100043d002200000001001d00000001010000310000001f0110008c0000006d0000a13d000000220100002900000000010104330000131701100197000013240110009c000011910000613d000000220300002900000064013000390000132502000041000000000021043500000044013000390000132602000041000000000021043500000024013000390000002b020000390000000000210435000013100100004100000000001304350000000401300039000000200200003900000f8a0000013d0000002101000029000112bf0000003d000048bc0000013d001c00000002001d4bfc43d70000040f000000000101041a001b13090010019c000013150000c13d00000024010000290000131701100197000000210110006c000017d40000c13d000112ca0000003d000048010000013d0000001e01000029000000000101043300000000120104344bfc43d70000040f0000001d020000290000000002020433002400000001001d00000000120204344bfc43d70000040f000000240110006b002400260000002d000012e00000613d000000400200043d0000004001200039000000400010043f002400000002001d000112dc0000003d000048b60000013d000000000001043500000024010000290000002001100039000000000021043500000024010000290000000001010433000013660110009c000013f10000813d000112e60000003d000049dc0000013d001c00000003001d0000000000320435000000000001043500000026010000290000000001010433002400000001001d000000200100002900000000010104330000131701100197002100000001001d0000134b0110009c000012f60000c13d000000240100002900001317011001970000134b0110009c000013e10000013d00000021010000290000134a0110009c000012fe0000c13d000000240100002900001317011001970000134a0110009c000013e30000c13d000013d20000013d0000002101000029000013640110009c000013060000c13d00000024010000290000131701100197000013640110009c000013e30000c13d000013d20000013d00000021010000290000135f0110009c000013c60000c13d000000240100002900001317011001970000135f0110009c000013e30000c13d000013d20000013d000013100100004100000022060000290000000000160435000013290100004100000000001304350000132a010000410000196b0000013d000000400100043d0000136502000041000000000021043500000004021000390000001c050000290000000000520435000000260300002900000000030304330000131703300197000000440410003900000000003404350000001e03000029000113230000003d000046360000013d000000000847004b000013280000813d000113270000003d000048ec0000013d000013230000013d000000000647004b0000132c0000a13d000000000554001900000000000504350000001f04400039001a0020000000920000001a0440017f0000000003340019000000200430003900000000022400490000002401100039000000000021043500000020010000290000000001010433000013170110019700000000001404350000001d01000029000000000101043300000040023000390000001c040000290001133e0000003d000047460000013d000000000352004b000013430000813d000113420000003d000048da0000013d0000133e0000013d001c00000006001d002400000005001d000000000152004b0000134a0000a13d0000001c0200002900000024012000290000000000010435000000400100043d002100000001001d003f001b0000002d0001134f0000003d0000441d0000013d0000003f0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001b02000029000000040220008c000013650000613d00000024020000290000001f022000390000001a0220017f0000001c02200029000000210300002900000000043200490000001b02000029000113620000003d000049890000013d000001560000613d000000400100043d002100000001001d000113670000003d000048260000013d00000021080000290000136f0000613d0000000005000019000000050650021000000000076800190001136e0000003d000045be0000013d0000136a0000413d000000000503004b000013760000613d0000000504400210000000000242034f0000002104400029000113760000003d0000446e0000013d0000130802000041000113790000003d00004ac30000013d0000130804100197000000000504004b0000000002008019000013080440009c000000000203c0190000001f031000390000001a0330017f0000002103300029002400000003001d000000400030043f000000000202004b0000006d0000613d00000021020000290000000002020433000013160320009c0000006d0000813d00000021011000290000002102200029000000000321004900001308040000410001138f0000003d00004abf0000013d0000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d0000002403000029000013190330009c00001b020000813d00000024030000290000004003300039000000400030043f00000000340204340000131705400197000000000554004b0000006d0000c13d000000240500002900000000004504350000000003030433000013160430009c0000006d0000813d00000000022300190000001f032000390000130804000041000113aa0000003d00004abb0000013d00001308033001970000130806100197000113ae0000003d00004ab70000013d000013080330009c000000000405c019000000000304004b0000006d0000613d0000000043020434000013160230009c00001b020000813d0000003f023000390000001a0520017f000000400200043d0000000005520019000000000625004b00001b020000413d000013160650009c00001b020000813d000113bf0000003d00004a1e0000013d0000006d0000213d0000000001000019000000000631004b00001ad20000813d000113c50000003d000048d40000013d000013c10000013d0000002101000029000113c90000003d000048bc0000013d001b00000002001d4bfc43d70000040f000000000101041a001a13090010019c000017f60000c13d00000024010000290000131701100197000000210110006c000017d40000c13d000113d40000003d00004b800000013d0000001c03000029000000000032043500000000000104350000001d01000029000000000101043300000000120104344bfc43d70000040f0000001e020000290000000002020433002600000001001d00000000120204344bfc43d70000040f000000260110006b002400200000002d000013ed0000613d000000400200043d0000004001200039000000400010043f002400000002001d000113e90000003d000048b60000013d000000000001043500000024010000290000002001100039000000000021043500000024010000290000000001010433000013660110009c000015540000413d00000025010000290000006001100039001d00000001001d0000000001010433000000000501043300000017010000290000002001100039001c00000001001d00000000010104330000000004010433000113fd0000003d000048010000013d000113ff0000003d0000491d0000013d001e00000004001d0000000012040434002100000002001d001a00000001001d002600000005001d0000000021050434001b00000002001d0000131701100197002000000001001d0000134b0110009c0000140e0000c13d000000210100002900001317011001970000134b0110009c0000143e0000013d00000020010000290000134a0110009c000014160000c13d000000210100002900001317011001970000134a0110009c000014400000c13d000014320000013d0000002001000029000013640110009c0000141e0000c13d00000021010000290000131701100197000013640110009c000014400000c13d000014320000013d00000020010000290000135f0110009c000014260000c13d000000210100002900001317011001970000135f0110009c000014400000c13d000014320000013d0000002001000029000114290000003d000048bc0000013d001900000002001d4bfc43d70000040f000000000101041a001813090010019c000014780000c13d00000021010000290000131701100197000000200110006c000017d40000c13d000114340000003d000048010000013d0000001b01000029000000000101043300000000120104344bfc43d70000040f0000001a020000290000000002020433002100000001001d00000000120204344bfc43d70000040f000000210110006b002100260000002d0000144a0000613d000000400200043d0000004001200039000000400010043f002100000002001d000114460000003d000048b60000013d000000000001043500000021010000290000002001100039000000000021043500000021010000290000000001010433000013660110009c0000155b0000813d000114500000003d000049dc0000013d001900000003001d0000000000320435000000000001043500000026010000290000000001010433002100000001001d0000001e0100002900000000010104330000131701100197002000000001001d0000134b0110009c000014600000c13d000000210100002900001317011001970000134b0110009c000015440000013d00000020010000290000134a0110009c000014680000c13d000000210100002900001317011001970000134a0110009c000015460000c13d000015350000013d0000002001000029000013640110009c000014700000c13d00000021010000290000131701100197000013640110009c000015460000c13d000015350000013d00000020010000290000135f0110009c000015290000c13d000000210100002900001317011001970000135f0110009c000015460000c13d000015350000013d000000400100043d00001365020000410000000000210435000000040210003900000019050000290000000000520435000000260300002900000000030304330000131703300197000000440410003900000000003404350000001b03000029000114860000003d000046360000013d000000000847004b0000148b0000813d0001148a0000003d000048ec0000013d000014860000013d000000000647004b0000148f0000a13d000000000554001900000000000504350000001f044000390015002000000092000000150440017f000000000334001900000020043000390000000002240049000000240110003900000000002104350000001e010000290000000001010433000013170110019700000000001404350000001a01000029000000000101043300000040023000390000001904000029000114a10000003d000047460000013d000000000352004b000014a60000813d000114a50000003d000048da0000013d000014a10000013d001900000006001d002100000005001d000000000152004b000014ad0000a13d000000190200002900000021012000290000000000010435000000400100043d002000000001001d004100180000002d000114b20000003d0000441d0000013d000000410440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001802000029000000040220008c000014c80000613d00000021020000290000001f02200039000000150220017f0000001902200029000000200300002900000000043200490000001802000029000114c50000003d000049890000013d000001560000613d000000400100043d002000000001001d000114ca0000003d000048260000013d0000002008000029000014d20000613d000000000500001900000005065002100000000007680019000114d10000003d000045be0000013d000014cd0000413d000000000503004b000014d90000613d0000000504400210000000000242034f0000002004400029000114d90000003d0000446e0000013d0000130802000041000114dc0000003d00004ac30000013d0000130804100197000000000504004b0000000002008019000013080440009c000000000203c0190000001f03100039000000150330017f0000002003300029002100000003001d000000400030043f000000000202004b0000006d0000613d00000020020000290000000002020433000013160320009c0000006d0000813d0000002001100029000000200220002900000000032100490000130804000041000114f20000003d00004abf0000013d0000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d0000002103000029000013190330009c00001b020000813d00000021030000290000004003300039000000400030043f00000000340204340000131705400197000000000554004b0000006d0000c13d000000210500002900000000004504350000000003030433000013160430009c0000006d0000813d00000000022300190000001f0320003900001308040000410001150d0000003d00004abb0000013d00001308033001970000130806100197000115110000003d00004ab70000013d000013080330009c000000000405c019000000000304004b0000006d0000613d0000000043020434000013160230009c00001b020000813d0000003f02300039000000150520017f000000400200043d0000000005520019000000000625004b00001b020000413d000013160650009c00001b020000813d000115220000003d00004a1e0000013d0000006d0000213d0000000001000019000000000631004b00001ad60000813d000115280000003d000048d40000013d000015240000013d00000020010000290001152c0000003d000048bc0000013d001800000002001d4bfc43d70000040f000000000101041a001513090010019c000018a10000c13d00000021010000290000131701100197000000200110006c000017d40000c13d000115370000003d00004b800000013d0000001903000029000000000032043500000000000104350000001a01000029000000000101043300000000120104344bfc43d70000040f0000001b020000290000000002020433002600000001001d00000000120204344bfc43d70000040f000000260110006b0021001e0000002d000015500000613d000000400200043d0000004001200039000000400010043f002100000002001d0001154c0000003d000048b60000013d000000000001043500000021010000290000002001100039000000000021043500000021010000290000000001010433000013660110009c0000155b0000813d000000400200043d00000044012000390000138d03000041000000000031043500000024012000390000001203000039000025810000013d000000400100043d0000008002100039000000400020043f00000020021000390000002203000029000000000032043500000060021000390000000000020435000000000031043500000040011000390000000000010435000000400100043d0000008002100039000000400020043f0000002002100039000000000032043500000000003104350000006002100039000000000002043500000040011000390000000000010435000115720000003d000047380000013d0000001f01000029000000000101043300000000010104330000000012010434002000000002001d00000000010104330000002503000029002500000003001d000000e0023000390000000003030433002600000003001d001b00000002001d0000000002020433001e00000002001d00000000120104344bfc43d70000040f00000020020000290000131702200197000000400400043d002000000004001d000000400340003900000000002304350000131d0300004100000020024000390001158c0000003d0000465a0000013d0000001d02000029000000000202043300000000020204330000000023020434001900000003001d0000000002020433001a00000001001d00000000120204344bfc43d70000040f000000190200002900001317022001970000002004000029000000c0034000390000000000230435000000a0024000390000131d030000410001159e0000003d000046650000013d0000001e090000290000131703900197000000260200002900001309052001970000002006000029002601a00060003d000001800260003900000160046000390000014007600039000000000a0600190000012008600039000000250b0000290000008006b00039001400000006001d0000000006060433000013380990009c001e010000b0003d000015ca0000213d000013390330009c000015ca0000613d0000001e03000029000000000303043300000000005804350000001a05000029000000000057043500000000001404350000000000620435000000a00100003900000026020000290000000000120435000001c001a0003900000000020304330000000000210435000001e001a0003900000000020304330000000004000019000000000524004b000015d30000813d00000000051400190000002004400039000000000634001900000000060604330000000000650435000015c20000013d00000000005804350000001a03000029000000000037043500000000001404350000000000620435000000400100043d00000000021200490000000000210435000015dc0000013d002600000012001d0000001f01200190000015d80000613d000115d80000003d000047050000013d000000400100043d0000002602100069000000200220008a00000000002104350000002602000029002600000002001d000000400020043f000000000201043300000020011000394bfc43d70000040f0000001c020000290000000002020433000000000202043300000020032000390000000002020433002000000002001d0000000002030433001200000001001d0000001701000029001700000001001d0000000003010433001a00000003001d000000e001100039001500000001001d0000000001010433001900000001001d00000000120204344bfc43d70000040f0000002002000029000013170220019700000026040000290000004003400039000000000023043500000020024000390000131d03000041000115fd0000003d0000465a0000013d0000001602000029000000000202043300000000020204330000000023020434002000000003001d0000000002020433001800000001001d00000000120204344bfc43d70000040f000000200200002900001317022001970000002604000029000000c0034000390000000000230435000000a0024000390000131d030000410001160f0000003d000046650000013d0000002603000029002001a00030003d0000018002300039000001600430003900000140053000390000012007300039000000190900002900001317039001970000001a060000290000130908600197000000170a0000290000008006a00039001300000006001d0000000006060433000013380990009c001a010000a0003d0000163b0000213d000013390330009c0000163b0000613d0000001a03000029000000000303043300000000008704350000001807000029000000000075043500000000001404350000000000620435000000a001000039000000200200002900000000001204350000002604000029000001c00140003900000000020304330000000000210435000001e00140003900000000020304330000000004000019000000000524004b000016440000813d00000000051400190000002004400039000000000634001900000000060604330000000000650435000016330000013d00000000008704350000001803000029000000000035043500000000001404350000000000620435000000400100043d00000000021200490000000000210435000016530000013d002000000012001d0000001f012001900000164f0000613d0000002002100069000000030110021000000100011000890000000043020434002000000004001d000000000313022f00000000011301cf0000000000120435000000400100043d0000002002100069000000200220008a00000000002104350000002002000029000000400020043f000000000201043300000020011000394bfc43d70000040f001900000001001d0000000002000411000000230120006b001100000002001d0000000001020019000016850000c13d00000000010000310000003f02100039000000200300008a000000000232016f00000020040000290000000002420019000000400020043f0000001f0310018f000000000214043600000002040003670000000505100272000016710000613d000000000600001900000005076002100000000008720019000000000774034f000116700000003d000044a70000013d0000166b0000413d000000000603004b000016800000613d0000000505500210000000000454034f00000000055200190000000303300210000000000605043300000000063601cf000000000636022f000000000404043b0000010003300089000000000434022f00000000033401cf000000000363019f0000000000350435000000000212001900000000000204350000002001100029000000000101043300001309011001970000002502000029000000000202043300001309022001980000168c0000c13d000013090210019700000025030000290000000000230435000000170200002900000000020204330000130902200198000016930000c13d000013090110019700000017020000290000000000120435000000400200043d0000008001200039000000400010043f00000020032000390000002201000029002000000003001d000000000013043500000000001204350000006001200039001800000001001d0000000000010435002600000002001d000000400120003900000000000104350000001b0200002900000000020204330000131703200197000013390430009c000017080000c13d0000001e020000290000000002020433000000003202043400001308040000410000001f0520008c000000000500001900000000050420190000130806200197000000000706004b0000000004008019000013080660009c000000000405c019000000000404004b0000006d0000613d0000000004030433000013160540009c0000006d0000813d00000000022300190000000004340019000000000342004900001308050000410000003f0630008c000000000600001900000000060520190000130803300197000000000703004b0000000005008019000013080330009c000000000506c019000000000305004b0000006d0000613d000000400300043d000013190530009c00001b020000813d0000004005300039000000400050043f0000000067040434000013160870009c0000006d0000813d00000000074700190000001f087000390000130809000041000000000a28004b000000000a000019000000000a0940190000130808800197000013080b200197000116d70000003d00004b600000013d000013080880009c00000000090ac019000000000809004b0000006d0000613d0000000087070434000013160970009c00001b020000813d000000050a7002100000006009300039000000000aa90019000013160ba0009c00001b020000813d0000004000a0043f0000000000750435000000060a700210000000000aa80019000000000aa2004b0000006d0000413d000013080a000041000000000b000019000000000c7b004b000019890000813d000000000c8200490000003f0dc0008c000000000d000019000000000d0a2019000013080cc00197000000000e0c004b000000000e000019000000000e0a4019000013080cc0009c000000000e0dc019000000000c0e004b0000006d0000613d000000400c00043d000013190dc0009c00001b020000813d000000400dc000390000004000d0043f00000000de0804340000130a0fe0009c0000006d0000813d000000000eec0436000000000d0d04330000136b0fd0009c0000006d0000813d000117070000003d00004b5b0000013d000016eb0000013d000013680430009c0000176b0000c13d0000001e02000029000000000202043300000000230204340000130804000041000117100000003d000049aa0000013d0000130806300197000000000706004b0000000004008019000013080660009c000000000405c019000000000404004b0000006d0000613d0000000004020433000013160540009c0000006d0000813d00000000033200190000000002240019000000000423004900001308050000410000005f0640008c000000000600001900000000060520190000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d000000400400043d0000136a0540009c00001b020000813d0000006005400039000000400050043f0000000067020434000013160870009c0000006d0000813d00000000072700190000001f087000390000130809000041000000000a38004b000000000a000019000000000a0940190000130808800197000013080b3001970001173a0000003d00004b600000013d000013080880009c00000000090ac019000000000809004b0000006d0000613d0000000087070434000013160970009c00001b020000813d000000050a7002100000008009400039000000000aa90019000013160ba0009c00001b020000813d0000004000a0043f0000000000750435000000060a700210000000000aa80019000000000aa3004b0000006d0000413d000013080a000041000000000b000019000000000c7b004b000019cb0000813d000000000c8300490000003f0dc0008c000000000d000019000000000d0a2019000013080cc00197000000000e0c004b000000000e000019000000000e0a4019000013080cc0009c000000000e0dc019000000000c0e004b0000006d0000613d000000400c00043d000013190dc0009c00001b020000813d000000400dc000390000004000d0043f00000000de0804340000130a0fe0009c0000006d0000813d000000000eec0436000000000d0d04330000136b0fd0009c0000006d0000813d0001176a0000003d00004b5b0000013d0000174e0000013d000013690330009c000017ce0000c13d0000001e02000029000000000202043300000000230204340000130804000041000117730000003d000049aa0000013d0000130806300197000000000706004b0000000004008019000013080660009c000000000405c019000000000404004b0000006d0000613d0000000004020433000013160540009c0000006d0000813d00000000033200190000000002240019000000000423004900001308050000410000005f0640008c000000000600001900000000060520190000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d000000400400043d0000136a0540009c00001b020000813d0000006005400039000000400050043f0000000067020434000013160870009c0000006d0000813d00000000072700190000001f087000390000130809000041000000000a38004b000000000a000019000000000a0940190000130808800197000013080b3001970001179d0000003d00004b600000013d000013080880009c00000000090ac019000000000809004b0000006d0000613d0000000087070434000013160970009c00001b020000813d000000050a7002100000008009400039000000000aa90019000013160ba0009c00001b020000813d0000004000a0043f0000000000750435000000060a700210000000000aa80019000000000aa3004b0000006d0000413d000013080a000041000000000b000019000000000c7b004b00001a550000813d000000000c8300490000003f0dc0008c000000000d000019000000000d0a2019000013080cc00197000000000e0c004b000000000e000019000000000e0a4019000013080cc0009c000000000e0dc019000000000c0e004b0000006d0000613d000000400c00043d000013190dc0009c00001b020000813d000000400dc000390000004000d0043f00000000de0804340000130a0fe0009c0000006d0000813d000000000eec0436000000000d0d04330000136b0fd0009c0000006d0000813d000117cd0000003d00004b5b0000013d000017b10000013d000013170220009c00001ae90000813d000000400200043d00000044012000390000136c03000041000017d70000013d000000400200043d00000044012000390000136703000041000000000031043500000024012000390000001703000039000025810000013d000117dd0000003d000049a40000013d000017f50000813d0000132c02000041000117e10000003d00004bd50000013d000117e30000003d000045530000013d0000000001000414000117e60000003d00004b570000013d4bfc00340000040f000000000101004b000001560000613d000000400200043d000000200120008a000000000101043300001309011001980000195f0000613d000000240110006c000019800000c13d000000250100002900000000010104330000130901100198000011910000c13d0000197a0000013d000019650000013d000000400100043d0000136502000041000000000021043500000004021000390000001b050000290000000000520435000000200300002900000000030304330000131703300197000000440410003900000000003404350000001d03000029000118040000003d000046360000013d000000000847004b000018090000813d000118080000003d000048ec0000013d000018040000013d000000000647004b0000180d0000a13d000000000554001900000000000504350000001f044000390020002000000092000000200440017f000118120000003d00004ad30000013d000013170110019700000000001404350000001e01000029000000000101043300000040023000390000001b040000290001181a0000003d000047460000013d000000000352004b0000181f0000813d0001181e0000003d000048da0000013d0000181a0000013d002100000006001d002400000005001d000000000152004b000018260000a13d000000210200002900000024012000290000000000010435000000400100043d002600000001001d0040001a0000002d0001182b0000003d0000441d0000013d000000400440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001a02000029000000040220008c000018410000613d00000024020000290000001f02200039000000200220017f0000002102200029000000260300002900000000043200490000001a020000290001183e0000003d000049890000013d000001560000613d000000400100043d002600000001001d000118430000003d000048260000013d0000184a0000613d000000000500001900000005065002100000002607600029000118490000003d000045be0000013d000018450000413d000000000503004b000018510000613d0000000504400210000000000242034f0000002604400029000118510000003d0000446e0000013d0000130802000041000118540000003d00004ac30000013d0000130804100197000000000504004b0000000002008019000013080440009c000000000203c0190000001f03100039000000200330017f0000002603300029002400000003001d000000400030043f000000000202004b0000006d0000613d00000026020000290000000002020433000013160320009c0000006d0000813d00000026011000290000002602200029000000000321004900001308040000410001186a0000003d00004abf0000013d0000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d0000002403000029000013190330009c00001b020000813d00000024030000290000004003300039000000400030043f00000000340204340000131705400197000000000554004b0000006d0000c13d000000240500002900000000004504350000000003030433000013160430009c0000006d0000813d00000000022300190000001f032000390000130804000041000118850000003d00004abb0000013d00001308033001970000130806100197000118890000003d00004ab70000013d000013080330009c000000000405c019000000000304004b0000006d0000613d0000000043020434000013160230009c00001b020000813d0000003f02300039000000200520017f000000400200043d0000000005520019000000000625004b00001b020000413d000013160650009c00001b020000813d0001189a0000003d00004a1e0000013d0000006d0000213d0000000001000019000000000631004b00001ada0000813d000118a00000003d000048d40000013d0000189c0000013d000000400100043d000013650200004100000000002104350000000402100039000000180500002900000000005204350000001e0300002900000000030304330000131703300197000000440410003900000000003404350000001a03000029000118af0000003d000046360000013d000000000847004b000018b40000813d000118b30000003d000048ec0000013d000018af0000013d000000000647004b000018b80000a13d000000000554001900000000000504350000001f04400039001e0020000000920000001e0440017f000118bd0000003d00004ad30000013d000013170110019700000000001404350000001b01000029000000000101043300000040023000390000001804000029000118c50000003d000047460000013d000000000352004b000018ca0000813d000118c90000003d000048da0000013d000018c50000013d002000000006001d002100000005001d000000000152004b000018d10000a13d000000200200002900000021012000290000000000010435000000400100043d002600000001001d004200150000002d000118d60000003d0000441d0000013d000000420440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001502000029000000040220008c000018ec0000613d00000021020000290000001f022000390000001e0220017f0000002002200029000000260300002900000000043200490000001502000029000118e90000003d000049890000013d000001560000613d000000400100043d002600000001001d000118ee0000003d000048260000013d000018f50000613d000000000500001900000005065002100000002607600029000118f40000003d000045be0000013d000018f00000413d000000000503004b000018fc0000613d0000000504400210000000000242034f0000002604400029000118fc0000003d0000446e0000013d0000130802000041000118ff0000003d00004ac30000013d0000130804100197000000000504004b0000000002008019000013080440009c000000000203c0190000001f031000390000001e0330017f0000002603300029002100000003001d000000400030043f000000000202004b0000006d0000613d00000026020000290000000002020433000013160320009c0000006d0000813d0000002601100029000000260220002900000000032100490000130804000041000119150000003d00004abf0000013d0000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d0000002103000029000013190330009c00001b020000813d00000021030000290000004003300039000000400030043f00000000340204340000131705400197000000000554004b0000006d0000c13d000000210500002900000000004504350000000003030433000013160430009c0000006d0000813d00000000022300190000001f032000390000130804000041000119300000003d00004abb0000013d00001308033001970000130806100197000119340000003d00004ab70000013d000013080330009c000000000405c019000000000304004b0000006d0000613d0000000043020434000013160230009c00001b020000813d0000003f023000390000001e0520017f000000400200043d0000000005520019000000000625004b00001b020000413d000013160650009c00001b020000813d000119450000003d00004a1e0000013d0000006d0000213d0000000001000019000000000631004b00001ade0000813d0001194b0000003d000048d40000013d000019470000013d0001194e0000003d000049a40000013d000019650000813d0000132c02000041000119520000003d00004bd50000013d000119540000003d000045530000013d0000000001000414000119570000003d00004b570000013d4bfc00340000040f000000000101004b000001560000613d000000400200043d000000200120008a00000000010104330000130901100198000019740000c13d00000044012000390000133103000041000000000031043500000024012000390000001803000039000025810000013d000013100100004100000022060000290000000000160435000013290100004100000000001304350000132d0100004100000000001504350000002201000039000000000014043500000020010000390000000000120435000000400100043d000000000219004900000506022000394bfc43c30000040f000000240110006c000019800000c13d000000170100002900000000010104330000130901100198000011910000c13d00000044012000390000133003000041000000000031043500000024012000390000000803000039000025810000013d00000064012000390000132e03000041000000000031043500000044012000390000132f0300004100000000003104350000002401200039000000220300003900000ac90000013d00000000055304360000000006060433000013160760009c0000006d0000813d00000000044600190000001f064000390000130807000041000000000826004b0000000008000019000000000807401900001308066001970000130809200197000119970000003d000049970000013d000013080660009c000000000708c019000000000607004b0000006d0000613d0000000064040434000013160740009c00001b020000813d0000000508400210000000400700043d00000000087800190000002008800039000000000978004b00001b020000413d000013160980009c00001b020000813d000000400080043f000000000047043500000006084002100000000008860019000000000882004b0000006d0000413d00001308080000410000000009070019000000000a000019000000000b4a004b00001ae20000813d000000000b6200490000003f0cb0008c000000000c000019000000000c082019000013080bb00197000000000d0b004b000000000d000019000000000d084019000013080bb0009c000000000d0cc019000000000b0d004b0000006d0000613d000000400b00043d000013190cb0009c00001b020000813d000119c20000003d00004b2e0000013d0000130a0ec0009c0000006d0000813d000000000ccb0436000000000d0d04330000136b0ed0009c0000006d0000813d000119ca0000003d0000474d0000013d000019af0000013d00000000055404360000000006060433000013160760009c0000006d0000813d00000000062600190000001f076000390000130808000041000000000937004b000000000900001900000000090840190000130807700197000013080a300197000000000ba7004b000000000800a0190000000007a7013f000013080770009c000000000809c019000000000708004b0000006d0000613d0000000076060434000013160860009c00001b020000813d0000000509600210000119e40000003d00004baa0000013d00001b020000413d000013160a90009c00001b020000813d000000400090043f000000000068043500000006096002100000000009970019000000000993004b0000006d0000413d0000130809000041000000000a080019000000000b000019000000000c6b004b00001ed60000813d000119f40000003d00004b170000013d000013080cc00197000000000e0c004b000000000e000019000000000e094019000013080cc0009c000000000e0dc019000000000c0e004b0000006d0000613d000000400c00043d000013190dc0009c00001b020000813d000000400dc000390000004000d0043f00000000ed0704340000130a0fd0009c0000006d0000813d000000000ddc0436000000000e0e04330000136b0fe0009c0000006d0000813d00011a0a0000003d00004a040000013d000019f00000013d000000a00100043d00000000010104330000000012010434002600000002001d00000000010104330000000012010434000000800300043d002500000003001d000001600300043d002400000003001d4bfc43d70000040f0000002602000029000013170220019700011a1a0000003d000049110000013d0000131d03000041000000200240003900011a1e0000003d0000465a0000013d000000e00200043d00000000020204330000000023020434002200000003001d0000000002020433002300000001001d00000000120204344bfc43d70000040f000000220200002900001317022001970000002604000029000000c0034000390000000000230435000000a0024000390000131d0300004100011a2f0000003d000046650000013d00000024090000290000131702900197000000250300002900001309053001970000002606000029000001a00a600039000001800360003900000160046000390000014007600039000000000b0600190000012008600039000001000600043d000013380990009c00001a950000213d000013390220009c00001a950000613d000001800200043d00000000005804350000002305000029000000000057043500000000001404350000000000630435000000a00100003900000000001a0435000001c001b0003900000000030204330000000000310435000001e001b0003900000000030204330000000004000019000000000534004b00001a9e0000813d0000000005140019000000200440003900000000062400190000000006060433000000000065043500001a4d0000013d00000000055404360000000006060433000013160760009c0000006d0000813d00000000062600190000001f076000390000130808000041000000000937004b000000000900001900000000090840190000130807700197000013080a300197000000000ba7004b000000000800a0190000000007a7013f000013080770009c000000000809c019000000000708004b0000006d0000613d0000000076060434000013160860009c00001b020000813d000000050960021000011a6e0000003d00004baa0000013d00001b020000413d000013160a90009c00001b020000813d000000400090043f000000000068043500000006096002100000000009970019000000000993004b0000006d0000413d0000130809000041000000000a080019000000000b000019000000000c6b004b00001edc0000813d00011a7e0000003d00004b170000013d000013080cc00197000000000e0c004b000000000e000019000000000e094019000013080cc0009c000000000e0dc019000000000c0e004b0000006d0000613d000000400c00043d000013190dc0009c00001b020000813d000000400dc000390000004000d0043f00000000ed0704340000130a0fd0009c0000006d0000813d000000000ddc0436000000000e0e04330000136b0fe0009c0000006d0000813d00011a940000003d00004a040000013d00001a7a0000013d00000000005804350000002302000029000000000027043500000000001404350000000000630435000000400100043d0000000002130049000000000021043500001aac0000013d000000000a1300190000001f0130019000001aa80000613d00000000021a00490000000301100210000001000110008900000000a3020434000000000313022f00000000011301cf0000000000120435000000400100043d00000000021a0049000000200220008a000000000021043500260000000a001d0000004000a0043f000000000201043300000020011000394bfc43d70000040f002500000001001d00000000001004350000012f01000039000000200010043f000000400200003900000000010000194bfc43d70000040f000000010200008a000000000021041b0000002602000029000000250100002900011abe0000003d00004a9b0000013d0000130003000041000013000410009c000000000103801900000040011002100000002002200039000013000420009c00011ac60000003d000049450000013d0000000002000414000013000420009c00011aca0000003d000048ac0000013d0000130b011001c70000800d0200003900000001030000390000133a040000414bfc44050000040f0000000101200190000002a90000c13d0000006d0000013d000000000131004b000012dd0000a13d0000000001350019000012dc0000013d000000000131004b000014470000a13d0000000001350019000014460000013d000000000131004b000013ea0000a13d0000000001350019000013e90000013d000000000131004b0000154d0000a13d00000000013500190000154c0000013d0000000000750435000000000203043300000026030000290000000000230435000000000205043300000020030000290000000000230435000000260200002900000000020204330000000002020433000000000202004b00001b0b0000c13d00000025020000290000000004020433000000400200043d000000010300003900000000033204360000008005200039000000400050043f000000600520003900000000000504350000004005200039000000000053043500000000000504350000000006020433000000000606004b00001b020000613d000013090440019700000000004504350000000004020433000000000404004b00001b050000c13d000000010100008a00000000000104350000000000000431000000000303043300000020033000390000271004000039000000000043043500000026030000290000000000230435000000400300043d0000008002300039000000400020043f00000020043000390000002202000029001b00000004001d000000000024043500000000002304350000006002300039001000000002001d0000000000020435001e00000003001d00000040023000390000000000020435000000150300002900000000030304330000131704300197000013390540009c00001b820000c13d0000001a030000290000000003030433000000004303043400001308050000410000001f0630008c000000000600001900000000060520190000130807300197000000000807004b0000000005008019000013080770009c000000000506c019000000000505004b0000006d0000613d0000000005040433000013160650009c0000006d0000813d00000000033400190000000005450019000000000453004900001308060000410000003f0740008c000000000700001900000000070620190000130804400197000000000804004b0000000006008019000013080440009c000000000607c019000000000406004b0000006d0000613d000000400400043d000013190640009c00001b020000813d0000004006400039000000400060043f0000000078050434001a00000007001d000013160780009c0000006d0000813d00000000085800190000001f078000390000130809000041000000000a37004b000000000a000019000000000a0940190000130807700197000013080b300197000000000cb7004b000000000900a0190000000007b7013f000013080770009c00000000090ac019000000000709004b0000006d0000613d0000000098080434000013160a80009c00001b020000813d0000000507800210000000600a400039000000000b7a00190000131607b0009c00001b020000813d0000004000b0043f000000000086043500000006078002100000000007790019000000000773004b0000006d0000413d000013080b000041000000000c000019000000000d8c004b00001db50000813d00000000079300490000003f0d70008c000000000d000019000000000d0b20190000130807700197000000000e07004b000000000e000019000000000e0b4019000013080770009c000000000e0dc01900000000070e004b0000006d0000613d000000400d00043d000013190ed0009c00001b020000813d000000400ed000390000004000e0043f00000000ef0904340000130a07f0009c0000006d0000813d000000000ffd0436000000000e0e04330000136b07e0009c0000006d0000813d00011b810000003d00004bb40000013d00001b650000013d000013680540009c00001be80000c13d0000001a030000290000000003030433000000003403043400001308050000410000001f0640008c000000000600001900000000060520190000130807400197000000000807004b0000000005008019000013080770009c000000000506c019000000000505004b0000006d0000613d0000000005030433000013160650009c0000006d0000813d00000000044300190000000003350019000000000534004900001308060000410000005f0750008c000000000700001900000000070620190000130805500197000000000805004b0000000006008019000013080550009c000000000607c019000000000506004b0000006d0000613d000000400500043d0000136a0650009c00001b020000813d0000006006500039000000400060043f0000000078030434001a00000007001d000013160780009c0000006d0000813d00000000083800190000001f078000390000130809000041000000000a47004b000000000a000019000000000a0940190000130807700197000013080b400197000000000cb7004b000000000900a0190000000007b7013f000013080770009c00000000090ac019000000000709004b0000006d0000613d0000000098080434000013160a80009c00001b020000813d0000000507800210000000800a500039000000000b7a00190000131607b0009c00001b020000813d0000004000b0043f000000000086043500000006078002100000000007790019000000000774004b0000006d0000413d000013080b000041000000000c000019000000000d8c004b00001df60000813d00000000079400490000003f0d70008c000000000d000019000000000d0b20190000130807700197000000000e07004b000000000e000019000000000e0b4019000013080770009c000000000e0dc01900000000070e004b0000006d0000613d000000400d00043d000013190ed0009c00001b020000813d000000400ed000390000004000e0043f00000000ef0904340000130a07f0009c0000006d0000813d000000000ffd0436000000000e0e04330000136b07e0009c0000006d0000813d00011be70000003d00004bb40000013d00001bcb0000013d000013690440009c00001c4e0000c13d0000001a030000290000000003030433000000003403043400001308050000410000001f0640008c000000000600001900000000060520190000130807400197000000000807004b0000000005008019000013080770009c000000000506c019000000000505004b0000006d0000613d0000000005030433000013160650009c0000006d0000813d00000000044300190000000003350019000000000534004900001308060000410000005f0750008c000000000700001900000000070620190000130805500197000000000805004b0000000006008019000013080550009c000000000607c019000000000506004b0000006d0000613d000000400500043d0000136a0650009c00001b020000813d0000006006500039000000400060043f0000000078030434001a00000007001d000013160780009c0000006d0000813d00000000083800190000001f078000390000130809000041000000000a47004b000000000a000019000000000a0940190000130807700197000013080b400197000000000cb7004b000000000900a0190000000007b7013f000013080770009c00000000090ac019000000000709004b0000006d0000613d0000000098080434000013160a80009c00001b020000813d0000000507800210000000800a500039000000000b7a00190000131607b0009c00001b020000813d0000004000b0043f000000000086043500000006078002100000000007790019000000000774004b0000006d0000413d000013080b000041000000000c000019000000000d8c004b00001e820000813d00000000079400490000003f0d70008c000000000d000019000000000d0b20190000130807700197000000000e07004b000000000e000019000000000e0b4019000013080770009c000000000e0dc01900000000070e004b0000006d0000613d000000400d00043d000013190ed0009c00001b020000813d000000400ed000390000004000e0043f00000000ef0904340000130a07f0009c0000006d0000813d000000000ffd0436000000000e0e04330000136b07e0009c0000006d0000813d00011c4d0000003d00004bb40000013d00001c310000013d000013380330009c000017d00000a13d0000001e0300002900000000030304330000000003030433000000000303004b00001c6f0000c13d00000017030000290000000005030433000000400300043d000000010400003900000000044304360000008006300039000000400060043f000000600630003900000000000604350000004006300039000000000064043500000000000604350000000007030433000000000707004b00001b020000613d000013090550019700000000005604350000000005030433000000000505004b00001b020000613d00000000040404330000002004400039000027100500003900000000005404350000001e0400002900000000003404350000000002020433000c00000002001d0000000001010433001500000001001d00011c750000003d000047380000013d00000014010000290000000001010433000000000101004b001a00000000001d00001c810000613d000000120100002900000000001004350000012f01000039000000200010043f00011c800000003d000049eb0000013d001a00000001001d00000013010000290000000001010433000000000101004b000f00000000001d00001c8d0000613d000000190100002900000000001004350000012f01000039000000200010043f00011c8c0000003d000049eb0000013d000f00000001001d00011c8f0000003d000047380000013d000000150100006b00001cc60000c13d0000001d01000029000000000101043300000020011000390000000002010433000e00000002001d0000001a0120006c00001ccd0000413d0000000e0100006b00001cd60000613d0000000e020000290000001a0220006a0000001f01000029000000000101043300000020011000390000000001010433000d00000001001d000000000101004b00000000010000190000000101006039000900000001001d000a00000002001d000000000102004b00001cbb0000613d0000000d0100006b00001cbb0000613d0000000a010000290000000d020000290000000e030000294bfc43610000040f0000000d040000290000000a324000b900000000434200d90000000a0330006c000041ad0000c13d000000000301004b000000000300001900001cb90000613d00011cb80000003d00004a370000013d000041ad0000c13d000000000123004b00001e5e0000813d0000000d0100006b000000000100001900001cc30000613d0000000d030000290000000a213000b900000000323100d90000000a0220006c000041ad0000c13d000b000e10100102000800000000001d00001d080000013d0000001f01000029000000000101043300000020011000390000000002010433000d00000002001d0000001a0120006c00001cd40000813d000000400200043d00000044012000390000138c03000041000000000031043500000024012000390000001e03000039000025810000013d0000000d0100006b00001cdd0000c13d000000400200043d00000044012000390000138b03000041000000000031043500000024012000390000001003000039000025810000013d0000000d020000290000001a0220006a0000001d01000029000000000101043300000020011000390000000001010433000e00000001001d000000000101004b00000000010000190000000101006039000800000001001d000b00000002001d000000000102004b00001cfe0000613d0000000e0100006b00001cfe0000613d0000000b010000290000000e020000290000000d030000294bfc43610000040f0000000e040000290000000b324000b900000000434200d90000000b0330006c000041ad0000c13d000000000301004b000000000300001900001cfc0000613d00011cfb0000003d00004a370000013d000041ad0000c13d000000000123004b00001e5e0000813d0000000e0100006b000000000100001900001d060000613d0000000b040000290000000e214000b90000000e321000fa000000000242004b000041ad0000c13d000a000d10100102000900000000001d0000000c0100006b00001d3f0000c13d0000001601000029000000000101043300000020011000390000000002010433000700000002001d0000000f0120006c00001ccd0000413d000000070100006b00001cd60000613d00000007020000290000000f0220006a0000001c01000029000000000101043300000020011000390000000001010433000600000001001d000000000101004b00000000010000190000000101006039000300000001001d000500000002001d000000000102004b00001d340000613d000000060100006b00001d340000613d0000000501000029000000060200002900000007030000294bfc43610000040f000000060400002900000005324000b900000000434200d9000000050330006c000041ad0000c13d000000000301004b000000000300001900001d320000613d00011d310000003d00004a370000013d000041ad0000c13d000000000123004b00001e5e0000813d000000060100006b000000000100001900001d3c0000613d000000050400002900000006214000b900000006321000fa000000000242004b000041ad0000c13d0004000710100102000200000000001d00001d730000013d0000001c01000029000000000101043300000020011000390000000002010433000600000002001d0000000f0120006c00001ccd0000413d000000060100006b00001cd60000613d00000006020000290000000f0220006a0000001601000029000000000101043300000020011000390000000001010433000700000001001d000000000101004b00000000010000190000000101006039000200000001001d000400000002001d000000000102004b00001d690000613d000000070100006b00001d690000613d0000000401000029000000070200002900000006030000294bfc43610000040f000000070400002900000004324000b900000000434200d9000000040330006c000041ad0000c13d000000000301004b000000000300001900001d670000613d00011d660000003d00004a370000013d000041ad0000c13d000000000123004b00001e5e0000813d000000070100006b000000000100001900001d710000613d000000040400002900000007214000b900000007321000fa000000000242004b000041ad0000c13d0005000610100102000300000000001d00011d750000003d000047380000013d00000005020000290000000b0120006c00001d980000213d00000005020000290000000b012001b000001d980000613d0000000901000029000000010110019000001cd60000c13d000000050100006b000000080100002900000001011061bf000000010110019000001e370000613d000000050100006b000000000100001900001d8b0000613d00000005030000290000000e213000b900000000323100d90000000e0220006c000041ad0000c13d0000000d121000fa000000400100043d000e00000001001d000a00000002001d000000040120006c00001e650000a13d0000000e0300002900000044013000390000136d0200004100000000002104350000002401300039000000190200003900000eb10000013d0000000301000029000000010110019000001cd60000c13d0000000a0100006b000000020100002900000001011061bf000000010110019000001e4b0000613d0000000a0100006b000000000100001900001da80000613d00000007040000290000000a214000b90000000a321000fa000000000242004b000041ad0000c13d00000006211000fa000000400200043d000e00000002001d0000000b0110006c0005000b0000002d00001e650000a13d0000000e0300002900000044013000390000138a0200004100000000002104350000002401300039000000180200003900000eb10000013d00000000066404360000001a070000290000000007070433000013160870009c0000006d0000813d00000000055700190000001f075000390000130808000041000000000937004b000000000900001900000000090840190000130807700197000013080a300197000000000ba7004b000000000800a0190000000007a7013f000013080770009c000000000809c019000000000708004b0000006d0000613d0000000075050434000013160850009c00001b020000813d000000050950021000011dcf0000003d00004baa0000013d00001b020000413d000013160a90009c00001b020000813d000000400090043f000000000058043500000006095002100000000009970019000000000993004b0000006d0000413d0000130809000041000000000a080019000000000b000019000000000c5b004b000020130000813d00011ddf0000003d00004b170000013d000013080cc00197000000000e0c004b000000000e000019000000000e094019000013080cc0009c000000000e0dc019000000000c0e004b0000006d0000613d000000400c00043d000013190dc0009c00001b020000813d000000400dc000390000004000d0043f00000000ed0704340000130a0fd0009c0000006d0000813d000000000ddc0436000000000e0e04330000136b0fe0009c0000006d0000813d00011df50000003d00004a040000013d00001ddb0000013d00000000066504360000001a070000290000000007070433000013160870009c0000006d0000813d00000000073700190000001f087000390000130809000041000000000a48004b000000000a000019000000000a0940190000130808800197000013080b40019700011e050000003d00004b600000013d000013080880009c00000000090ac019000000000809004b0000006d0000613d0000000087070434000013160970009c00001b020000813d00011e0e0000003d00004b9c0000013d00001b020000413d0000131609a0009c00001b020000813d00011e130000003d00004aef0000013d0000006d0000413d000013080a0000410000001a0b000029000000000c000019000000000d7c004b000022690000813d00000000098400490000003f0d90008c000000000d000019000000000d0a20190000130809900197000000000e09004b000000000e000019000000000e0a4019000013080990009c000000000e0dc01900000000090e004b0000006d0000613d000000400d00043d000013190ed0009c00001b020000813d000000400ed000390000004000e0043f00000000fe0804340000130a09e0009c0000006d0000813d000000000eed0436000000000f0f04330000136b09f0009c0000006d0000813d000000200bb000390000000000fe04350000000000db0435000000010cc00039000000400880003900001e170000013d0000000e01000029000e00000001001d0000000502000029000500000002001d0000000d030000294bfc43610000040f00000005040000290000000e324000b900000000434200d90000000e0330006c000041ad0000c13d000000000301004b000000000300001900001e480000613d00011e470000003d00004a370000013d000041ad0000c13d000000000123004b00001d830000413d00001e5e0000013d0000000701000029000700000001001d0000000a02000029000a00000002001d00000006030000294bfc43610000040f0000000a0400002900000007324000b900000000434200d9000000070330006c000041ad0000c13d000000000301004b000000000300001900001e5c0000613d00011e5b0000003d00004a370000013d000041ad0000c13d000000000123004b00001da00000413d000000400200043d00000044012000390000136e03000041000000000031043500000024012000390000000e03000039000025810000013d0000000e020000290000004001200039000000400010043f000000050100002900000000021204360000000a01000029000d00000002001d00000000001204350000001f0100002900011e700000003d00004a2c0000013d00001e750000c13d000000160100002900011e740000003d00004a2c0000013d00001e790000613d0000000e010000290000000001010433000000000101004b00001ec50000613d0000001d0100002900011e7c0000003d00004a2c0000013d00001ec30000c13d0000001c0100002900011e800000003d00004a2c0000013d00001ec30000c13d00001ecc0000013d00000000066504360000001a070000290000000007070433000013160870009c0000006d0000813d00000000073700190000001f087000390000130809000041000000000a48004b000000000a000019000000000a0940190000130808800197000013080b40019700011e910000003d00004b600000013d000013080880009c00000000090ac019000000000809004b0000006d0000613d0000000087070434000013160970009c00001b020000813d00011e9a0000003d00004b9c0000013d00001b020000413d0000131609a0009c00001b020000813d00011e9f0000003d00004aef0000013d0000006d0000413d000013080a0000410000001a0b000029000000000c000019000000000d7c004b0000226f0000813d00000000098400490000003f0d90008c000000000d000019000000000d0a20190000130809900197000000000e09004b000000000e000019000000000e0a4019000013080990009c000000000e0dc01900000000090e004b0000006d0000613d000000400d00043d000013190ed0009c00001b020000813d000000400ed000390000004000e0043f00000000fe0804340000130a09e0009c0000006d0000813d000000000eed0436000000000f0f04330000136b09f0009c0000006d0000813d000000200bb000390000000000fe04350000000000db0435000000010cc00039000000400880003900001ea30000013d0000000a0100006b00001ecc0000c13d000000400200043d00000044012000390000138903000041000000000031043500000024012000390000000f03000039000025810000013d00000014010000290000000001010433000000000101004b00001eec0000613d000000150100006b00001ee50000c13d0000000a02000029001f001a0020002e000041bf0000413d00001ee90000013d00011ed80000003d00004a9f0000013d0000006d0000c13d00011edb0000003d000047990000013d00001ae90000013d00011ede0000003d00004a9f0000013d0000006d0000c13d00011ee10000003d000047990000013d00000001020000390000001803000029000000000023043500001ae90000013d0000000e010000290000000001010433001f001a0010002e000041bf0000413d000000120100002900011eec0000003d000049f00000013d00000013010000290000000001010433000000000101004b00001efe0000613d0000000c0100006b00001ef70000c13d0000000e010000290000000001010433001f000f0010002e000041bf0000413d00001efb0000013d0000000d010000290000000001010433001f000f0010002e000041bf0000413d000000190100002900011efe0000003d000049f00000013d0000000d0100002900000000010104330000000e020000290000000002020433000000400300043d000000600430003900000000002404350000004002300039000000000012043500000020013000390000001902000029000000000021043500000012010000290000000000130435000000400100043d00000000021300490000130003000041000013000410009c000000000103801900000040011002100000008002200039000013000420009c00011f160000003d000049450000013d0000000002000414000013000420009c00011f1a0000003d000048ac0000013d0000130b011001c70000800d020000390000000103000039001f00000003001d0000136f040000414bfc44050000040f00000001012001900000006d0000613d000000400500043d001300000005001d0000010001500039000000400010043f000000c001500039000000240200002900000000002104350000000004020019002400000004001d0000000e020000290000000002020433000000e0035000390000000000230435000000000215043600000026010000290000000001010433000b00000002001d0000000000120435000000200100002900000000010104330000004002500039000a00000002001d00000000001204350000000001040433000013170110019700000000001004350000009701000039002600000001001d000000200010043f0000004002000039001500000002001d00000000010000194bfc43d70000040f000000000101041a000013090110019700000013030000290000006002300039000f00000002001d00000000001204350000002501000029000000000101043300001309011001970000008002300039001200000002001d000000000012043500000018010000290000000001010433000000000101004b0000000001000019000000010100c039000000a002300039002500000002001d0000000000120435000000400500043d001400000005001d0000010001500039000000400010043f000000c001500039000000210400002900000000004104350000000d020000290000000002020433000000e003500039000000000023043500000000021504360000001e010000290000000001010433000c00000002001d00000000001204350000001b0100002900000000010104330000004002500039000900000002001d00000000001204350000000001040433000013170110019700000000001004350000002601000029000000200010043f000000000100001900000015020000294bfc43d70000040f000000000101041a000013090110019700000014030000290000006002300039000e00000002001d00000000001204350000001701000029000000000101043300001309011001970000008002300039000d00000002001d000000000012043500000010010000290000000001010433000000000101004b0000000002000019000000010200c039000000a00130003900000000002104350000002402000029000000000202043300001317022001970000134b0320009c0000001f0300002900001fa50000613d00000002050000390000002103000029000000000303043300001317043001970000134b0340009c001f00000000001d000000000305001900001fa50000613d001f00010000003d0000134a0320009c0000001f0300002900001fa50000613d0000134a0340009c001f00000000001d000000000305001900001fa50000613d00000001030000390000135f0220009c001f00000003001d00001fa50000613d0000135f0240009c00000000030000190000000203006039001f00000000001d0000001402000029000000000202043300000020022000390000000002020433001000000002001d0000001f0200006b00001fda0000613d000000400200043d0000006003200039000000400030043f0000016103000039000000000403041a0000004005200039000000d003400270000000000035043500001309054001970000000005520436000000a0044002700000131104400197000000000045043500000025040000290000000004040433000000000404004b000000000400001900001fbf0000613d00000000040504330000000001010433000000000101004b000000000300601900001311044001970000000a01000029000000000101043300000020071000390000000008010433000000130100002900000000010104330000002005100039000000000505043300000000060400190000000009000019000000000a89004b0000201b0000813d000000050a900210000000000aa70019000000000a0a0433000000200aa00039000000000a0a0433000013700aa00197000027110ba0008c0000200f0000813d00000000066a0019000000010990003900001fcd0000013d0000001302000029000000000202043300000020042000390000000004040433002000000004001d000000020330008c000020670000c13d000000400200043d0000006003200039000000400030043f0000016103000039000000000503041a0000004004200039000000d003500270000000000034043500001309045001970000000004420436000000a005500270000013110550019700000000005404350000000001010433000000000101004b000000000100001900001ff30000613d000000000104043300000025040000290000000004040433000000000404004b000000000300601900001311041001970000000901000029000000000101043300000020071000390000000008010433000000140100002900000000010104330000002005100039000000000505043300000000060400190000000009000019000000000a89004b000022780000813d000000050a900210000000000aa70019000000000a0a0433000000200aa00039000000000a0a0433000013700aa00197000027110ba0008c0000200f0000813d00000000066a00190000000109900039000020020000013d000000400200043d00000044012000390000138803000041000042300000013d000000000086043500000000030404330000001e04000029000000000034043500000000030604330000001b04000029000000000034043500001c500000013d000000000705004b0000000007000019000020220000613d00000000875600a900000000985700d9000000000668004b000041ad0000c13d000027107670011a002000000056001e000041bf0000413d0000000f06000029000000000d0604330000000006010433000000000202043300000012010000290000000001010433000000000705004b0000000007000019000020330000613d000000000343001900000000475300a900000000545700d9000000000334004b000041ad0000c13d000027104370011a0000002007300069000000200470006c00000000040000190000000104002039000000000404004b000000000700c019002200000007001d000000200430006b0000002003004029000000000403004b000026d70000613d000120410000003d00004acb0000013d0000131707700197000013640870009c001e0000000d001d000022c40000c13d0000000004060433000000005604043400001308070000410000003f0860008c000000000800001900000000080720190000130806600197000000000906004b0000000007008019000013080660009c000000000708c019000000000607004b0000006d0000613d0000000005050433002613090050019b0000130a0550009c0000006d0000813d000000010330008c000042340000c13d0001205a0000003d00004b340000013d000013090220019700000004074000390000130901100197000000230810006b000023090000c13d0000137801000041000000000014043500000023010000290000130901100197000000000017043500000000002604350000000000350435000023dd0000013d0000000c010000290000000001010433001e00000001001d0000000031010434001b00000003001d000000000301004b0000405f0000613d0000000002020433001800000002001d0000002302000029001613090020019b00000012020000290000000002020433001a13090020019b0000000f020000290000000002020433001913090020019b002500000000001d001f00200000002d002600000000001d000000010210008a000000260320006b0000230d0000813d000000260110006b00001b020000813d000120820000003d000045370000013d0000137002200197000000200300006b00000000040000190000208a0000613d00000020342000b900000020534000fa000000000323004b000041ad0000c13d002500250020002e000041bf0000413d000027100240008c000021700000413d000027102340011a0000001f0230006b00001ccd0000413d000120930000003d000045e20000013d00001b020000813d001f001f00300071000120970000003d000049360000013d0000131707700197000013640870009c000020b70000c13d0001209c0000003d00004b510000013d0000130808000041000000000600001900000000060820190000130805500197000120a20000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000003030433001d13090030019b0000130a0330009c0000006d0000813d000027100340008a000027100330008c000042340000813d000120af0000003d000045300000013d0000130901100197000120b20000003d000046a50000013d000020f80000c13d0000137807000041000120b60000003d000044870000013d0000211c0000013d0000134a0470009c000020ff0000c13d000120bb0000003d00004b4d0000013d0000130807000041000000000500001900000000050720190000130804400197000120c10000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000002020433001d13090020019b0000130a0220009c0000006d0000813d000120cb0000003d000049ca0000013d00001309011001970000001a06000029000000230560006b0000212f0000c13d0000137505000041000120d20000003d0000490a0000013d0037001d0000002d000120d50000003d0000441d0000013d000000370440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c000020e50000613d0000001c03000029000120e20000003d000045ec0000013d000001560000613d000000400100043d001c00000001001d00000001010000310000001f0210008c0000130805000041000000000200001900000000020520190000130803100197000120ed0000003d000047250000013d000013080330009c000120f00000003d000044d40000013d0000006d0000613d0000001c01000029000120f40000003d0000445d0000013d0000006d0000c13d000000000101004b000021700000c13d0000233d0000013d000013770700004100000000007304350000001d07000029000120fd0000003d00004b420000013d001d00840030003d0000215a0000013d0000135f0470009c000021440000c13d000121030000003d00004b490000013d0000130808000041000000000600001900000000060820190000130805500197000121090000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000004040433001d13090040019b0000130a0440009c0000006d0000813d000000400500043d001c00c40050003d000121150000003d000045890000013d000013090a100197000121180000003d000045b90000013d000021500000c13d00001373020000410001211c0000003d000044c30000013d000000400100043d001700000001001d0091001d0000002d000121210000003d0000441d0000013d000000910440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c000021700000613d00000017030000290000001c043000690000001d020000290000216d0000013d00001374050000410000001c06000029000121330000003d000044b70000013d006900190000002d000121360000003d0000441d0000013d000000690440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000021700000613d0000001d030000290000001c0230006900000084042000390000216c0000013d0000134b0470009c000021730000c13d0000130904100197000000230140006b000021700000613d000000400200043d0000000001000414000000040540008c0000219f0000c13d00000001020000390000000101000031000021ac0000013d000013720200004100000000002504350000001d0200002900000000002b04350000001a02000029000121570000003d00004bf50000013d0000001c010000290000000000010435001d00e40050003d000000400100043d001c00000001001d007d00190000002d0001215f0000003d0000441d0000013d0000007d0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000021700000613d0000001d020000290000001c03000029000000000432004900000019020000290001216f0000003d0000452b0000013d000001560000613d000121720000003d000048520000013d0000207b0000013d000000400300043d0000137104000041000000000043043500000004043000390000002206000029000000000064043500000000040504330001217c0000003d000045210000013d00001317044001970001217f0000003d0000461e0000013d0000001d0650006c000021850000813d0000001c06500029000121840000003d000045260000013d0000217f0000013d0000001d0450006c0000218a0000a13d0000001d050000290000001c045000290000000000040435000000000202043300001309011001970001218e0000003d000044430000013d005300190000002d000121910000003d0000441d0000013d000000530440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000021700000613d0000001d020000290001219e0000003d000045a50000013d0000216b0000013d000013000510009c00001300060000410000000001068019000013000520009c0000000002068019000121a60000003d0000460e0000013d0000130b011001c70000800902000039000121aa0000003d000044570000013d000113000010019d0000130001100197000000000301004b000021b90000613d000121b00000003d000044290000013d000021b50000613d0000000006000019000121b40000003d000044210000013d000021b20000413d0000001f01100190000021b90000613d000121b90000003d0000440f0000013d000000000102004b000021700000c13d0000435d0000013d0000000002000411000000230320006b000021ce0000c13d0000001f03000029000121c20000003d0000481e0000013d000021c70000613d0000000004000019000121c60000003d000048160000013d000021c40000413d000000200400006b000021cb0000613d000121cb0000003d000044330000013d000121cd0000003d000046ed0000013d0000130902200197000000000112013f00001309011001980000253e0000613d000000a00100043d0000000021010434002200000002001d0000000012010434002600000002001d00000000010104330000000012010434000000800300043d002400000003001d4bfc43d70000040f00000026020000290000131702200197000121df0000003d000049110000013d0000131d03000041000121e20000003d0000448d0000013d0000131e03000041000121e50000003d000045d80000013d000000e00200043d0000000032020434002000000003001d0000000023020434001100000003001d0000000002020433002200000001001d0000000012020434000000c00300043d002100000003001d4bfc43d70000040f00000011020000290000131702200197000121f40000003d000049ae0000013d0000131d03000041000121f70000003d000045020000013d0000131e05000041000121fa0000003d0000453e0000013d002000000001001d000001800100043d0000000012010434000001000300043d001100000003001d000001200300043d001000000003001d000001400300043d000f00000003001d000001600300043d000e00000003001d4bfc43d70000040f0000000e02000029000013170220019700000026040000290000032003400039000000000023043500000300024000390000000f030000290000000000320435000002e00240003900000010030000290000000000320435000002c00240003900000011030000290000000000320435000002a00240003900000020030000290000000000320435000000210200002900001309022001970000028003400039000000000023043500000260024000390000002203000029000000000032043500000024020000290000130902200197000002400340003900000000002304350000131f02000041000122250000003d000048740000013d000000800200043d002200000002001d003c13090020019b002400000001001d0001222b0000003d0000441d0000013d0000003c0440008a00000020044000c900001320020000414bfc43ed0000040f000000c902000039000000000202041a002000000002001d000000ca02000039000000000202041a001100000002001d002100000001001d000122380000003d000045110000013d00001321020000414bfc43ed0000040f0000002604000029000003c00240003900000011030000290000000000320435000003a002400039000000200300002900000000003204350000132202000041000122440000003d0000486e0000013d0000130901100197000122470000003d000045c40000013d00001323020000410001224a0000003d000046bb0000013d002213090020019b0001224d0000003d0000468d0000013d0000233e0000c13d0000001d060000290000000006060433000000410660008c000027780000c13d0000001e060000290000000006060433002100000006001d0000001d07000029000122580000003d000048680000013d000013280770009c0000277b0000813d000000f8076002700000132b0660009c000004a2069000390000234d0000813d0000001b0870008a000000020880008c00002b020000813d0000002402000029000122640000003d000044f30000013d0000000001000414000000200530008a000000010200003900000020060000390000236a0000013d0001226b0000003d0000498e0000013d0000006d0000c13d0001226e0000003d000047ab0000013d00001c500000013d000122710000003d0000498e0000013d0000006d0000c13d000122740000003d000047ab0000013d00000001030000390000001004000029000000000034043500001c500000013d000000000705004b00000000070000190000227f0000613d00000000875600a900000000985700d9000000000668004b000041ad0000c13d000027107670011a001000000056001e000041bf0000413d0000000e06000029000000000d060433000000000601043300000000020204330000000d010000290000000001010433000000000705004b0000000007000019000022900000613d000000000343001900000000475300a900000000545700d9000000000334004b000041ad0000c13d000027104370011a0000001007300069000000100470006c00000000040000190000000104002039000000000404004b000000000700c019001f00000007001d000000100430006b0000001003004029000000000403004b000027ba0000613d0001229e0000003d00004acb0000013d0000131707700197000013640870009c001d0000000d001d000023730000c13d0000000004060433000000005604043400001308070000410000003f0860008c000000000800001900000000080720190000130806600197000000000906004b0000000007008019000013080660009c000000000708c019000000000607004b0000006d0000613d0000000005050433002613090050019b0000130a0550009c0000006d0000813d000000010330008c000042340000c13d000122b70000003d00004b340000013d000013090220019700000004074000390000130901100197000000230810006b000023b80000c13d00001378010000410000000000140435000000230100002900001309011001970000000000170435000000000026043500000000003504350000249f0000013d0000134a0870009c000023bc0000c13d0000000004060433000000004504043400001308060000410000001f0750008c000000000700001900000000070620190000130805500197000000000805004b0000000006008019000013080550009c000000000607c019000000000506004b0000006d0000613d0000000004040433002513090040019b0000130a0440009c0000006d0000813d000000400500043d001f00440050003d0000002404500039002600000005001d000000040550003900001309022001970000130901100197000000230610006b000023f00000c13d0000137501000041000122e30000003d00004b8e0000013d002700250000002d000122e60000003d0000441d0000013d000000270440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002502000029000000040220008c000022f70000613d00000026030000290000001f04300069000122f40000003d000045900000013d000001560000613d000000400100043d002600000001001d00000001010000310000130803000041000122fb0000003d0000499b0000013d0000130804100197000000000504004b0000000003008019000013080440009c000123010000003d0000454b0000013d0000006d0000613d0000002601000029000123050000003d0000445d0000013d0000006d0000c13d000000000101004b000026d70000c13d0000422e0000013d00001377080000410001230c0000003d0000497b0000013d000024df0000013d000000000101004b00001b020000613d00000005012002100000001b011000290000000001010433000000200210003900000000020204330000137002200197000000250220002a000041bf0000413d000027100220008c000041ea0000c13d0000001f0200006b000029580000613d0001231d0000003d000046700000013d0000131705500197000013640650009c0000240e0000c13d000000000203043300000000340204340000130805000041000123250000003d000048800000013d0000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d0000000003030433002613090030019b0000130a0330009c0000006d0000813d0000001f03000029000000010330008c000042340000c13d000123350000003d0000467b0000013d0000130901100197000123380000003d000046a50000013d000024520000c13d00001378070000410001233c0000003d000044870000013d000025100000013d0000422e0000013d00001324060000410000002407000029000123420000003d000049ff0000013d0000001d02000029000123450000003d000049610000013d000000000412004b000024560000813d00000000043200190000001e05200029000000000505043300000000005404350000002002200039000023450000013d000000fc07700039000000ff0770018f001e00000007001d0000001b0770008a000000020770008c00002b020000813d0000132c02000041000123560000003d00004be20000013d00000000000204350000002605000029000004fe02500039000000400020043f0000055e03500039000000200400002900000000004304350000053e03500039000000210400002900000000004304350000051e035000390000001e0400002900000000004304350000000000120435000000400300043d00000000013500490000057e0410003900000000010004140001236a0000003d00004b570000013d4bfc00340000040f000000000101004b000001560000613d000000400200043d000000200120008a00000000010104330000130901100198000024780000c13d0000195f0000013d0000134a0870009c0000247e0000c13d0000000004060433000000004504043400001308060000410000001f0750008c000000000700001900000000070620190000130805500197000000000805004b0000000006008019000013080550009c000000000607c019000000000506004b0000006d0000613d0000000004040433002513090040019b0000130a0440009c0000006d0000813d000000400500043d001e00440050003d0000002404500039002600000005001d000000040550003900001309022001970000130901100197000000230610006b000024b20000c13d0000137501000041000123920000003d00004b8e0000013d002e00250000002d000123950000003d0000441d0000013d0000002e0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002502000029000000040220008c000023a60000613d00000026030000290000001e04300069000123a30000003d000045900000013d000001560000613d000000400100043d002600000001001d00000001010000310000130803000041000123aa0000003d0000499b0000013d0000130804100197000000000504004b0000000003008019000013080440009c000123b00000003d0000454b0000013d0000006d0000613d0000002601000029000123b40000003d0000445d0000013d0000006d0000c13d000000000101004b000027ba0000c13d0000422e0000013d0000137708000041000123bb0000003d0000497b0000013d000025960000013d0000135f0870009c000024d00000c13d0000000005060433000000004605043400001308070000410000003f0860008c000000000800001900000000080720190000130806600197000000000906004b0000000007008019000013080660009c000000000708c019000000000607004b0000006d0000613d0000000004040433002613090040019b0000130a0440009c0000006d0000813d000123d10000003d00004a230000013d000013090b200197000000400250003900000000020204330000130901100197000000230510006b000024dc0000c13d0000137301000041000000000016043500000023010000290000130901100197000123dd0000003d00004a430000013d000000400100043d001f00000001001d008100260000002d000123e20000003d0000441d0000013d000000810440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002602000029000000040220008c000026d70000613d0000001f0300002900000025043000690000002602000029000026d20000013d0000137406000041000000260700002900000000006704350000002506000029000000000065043500000000001404350000001f01000029000000000021043500000064017000390000000000310435000000400100043d002500000001001d0059130900d0019b000123ff0000003d0000441d0000013d000000590440008a00000020044000c900001320020000414bfc43ed0000040f0000001e020000290000130902200197000000000101004b0000006d0000613d0000000001000414000000040320008c000026d70000613d000000250500002900000026035000690000008404300039000024f10000013d0000134a0650009c000024f30000c13d000000000203043300000000230204340000130804000041000124150000003d000049aa0000013d0000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d0000000002020433002513090020019b0000130a0220009c0000006d0000813d000000400300043d001e00440030003d0000002402300039002600000003001d000000040330003900001309011001970000001a05000029000000230450006b000025230000c13d00001375040000410001242c0000003d000047f90000013d003800250000002d0001242f0000003d0000441d0000013d000000380440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002502000029000000040220008c000024400000613d00000026030000290000001e043000690001243d0000003d000045900000013d000001560000613d000000400100043d002600000001001d00000001010000310000130803000041000124440000003d0000499b0000013d0000130804100197000000000504004b0000000003008019000013080440009c0001244a0000003d0000454b0000013d0000006d0000613d00000026010000290001244e0000003d0000445d0000013d0000006d0000c13d000000000101004b000029580000c13d0000422e0000013d0000137707000041000124550000003d000045ce0000013d000025e80000013d002400000031001d0000001f011001900000245b0000613d0001245b0000003d000049660000013d000000400100043d002600000001001d009600220000002d000124600000003d0000441d0000013d000000960440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002202000029000000040220008c0000246f0000613d0001246c0000003d00004a4b0000013d000001560000613d000000400100043d002600000001001d00000001010000310000001f0110008c0000006d0000a13d000000260100002900000000010104330000131701100197000013240110009c0000253e0000613d00002b000000013d000000220110006c0000253d0000c13d000000800100043d00001309011001980000253e0000c13d0000197a0000013d0000135f0870009c000025870000c13d0000000005060433000000004605043400001308070000410000003f0860008c000000000800001900000000080720190000130806600197000000000906004b0000000007008019000013080660009c000000000708c019000000000607004b0000006d0000613d0000000004040433002613090040019b0000130a0440009c0000006d0000813d000124930000003d00004a230000013d000013090b200197000000400250003900000000020204330000130901100197000000230510006b000025930000c13d00001373010000410000000000160435000000230100002900001309011001970001249f0000003d00004a430000013d000000400100043d001e00000001001d008800260000002d000124a40000003d0000441d0000013d000000880440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002602000029000000040220008c000027ba0000613d0000001e0300002900000025043000690000002602000029000027b50000013d0000137406000041000000260700002900000000006704350000002506000029000000000065043500000000001404350000001e01000029000000000021043500000064017000390000000000310435000000400100043d002500000001001d0060130900d0019b000124c10000003d0000441d0000013d000000600440008a00000020044000c900001320020000414bfc43ed0000040f0000001d020000290000130902200197000000000101004b0000006d0000613d0000000001000414000000040320008c000027ba0000613d000000250500002900000026035000690000008404300039000025a80000013d0000134b0670009c000025aa0000c13d0000130904200197000000230140006b000026d70000613d000000400200043d0000000001000414000000040540008c000025bc0000c13d00000001020000390000000105000031000025c90000013d0000137205000041000124df0000003d000048090000013d000000400100043d002500000001001d006d130900d0019b000124e40000003d0000441d0000013d0000006d0440008a00000020044000c900001320020000414bfc43ed0000040f0000001e020000290000130902200197000000000101004b0000006d0000613d0000000001000414000000040320008c000026d70000613d000000250500002900000026045000690000000003050019000026d30000013d0000135f0650009c000025d90000c13d000000000203043300000000340204340000130805000041000124fa0000003d000048800000013d0000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d0000000003030433002613090030019b0000130a0330009c0000006d0000813d000000400400043d002500c40040003d000125090000003d000044cd0000013d00001309091001970001250c0000003d0000499f0000013d000025e50000c13d0000137302000041000125100000003d0000464f0000013d000000400100043d001f00000001001d009200260000002d000125150000003d0000441d0000013d000000920440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002602000029000000040220008c000029580000613d0000001f0300002900000025043000690000002602000029000029550000013d0000137404000041000125260000003d00004b270000013d0000001e02000029000000000012043500000064015000390000001f020000290000000000210435000000400100043d002500000001001d006a00190000002d000125300000003d0000441d0000013d0000006a0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000029580000613d0001253c0000003d00004b8a0000013d000029540000013d000019800000013d00000015010000290000000001010433002600000001001d000000000101004b000025490000613d000125450000003d000045110000013d0000131c020000414bfc43ed0000040f000000260110006b000025740000813d00000014010000290000000001010433002600000001001d000000000101004b000025540000613d000125500000003d000045110000013d0000131c020000414bfc43ed0000040f000000260110006b0000257b0000a13d0000001701000029000000000101043300000018020000290000000002020433000000000202004b000025fa0000c13d000013090110019800002cdb0000613d0000000002000411000000230320006b000025700000c13d00000000020000310000003f032000390000001f0430017f000125640000003d000046cd0000013d000025690000613d0000000008000019000125680000003d000045760000013d000025660000413d000000000805004b0000256d0000613d0001256d0000003d000044790000013d0001256f0000003d00004a190000013d00001309022001970000130902200197000000000112004b00002cdb0000613d00000ea50000013d000000400200043d00000044012000390000136103000041000000000031043500000024012000390000001d03000039000025810000013d000000400200043d00000044012000390000136203000041000000000031043500000024012000390000001b030000390000000000310435000013100100004100000000001204350000000401200039000000200300003900000adc0000013d0000134b0670009c000026800000c13d0000130904200197000000230140006b000027ba0000613d000000400200043d0000000001000414000000040540008c000026920000c13d000000010200003900000001050000310000269f0000013d0000137205000041000125960000003d000048090000013d000000400100043d002500000001001d0074130900d0019b0001259b0000003d0000441d0000013d000000740440008a00000020044000c900001320020000414bfc43ed0000040f0000001d020000290000130902200197000000000101004b0000006d0000613d0000000001000414000000040320008c000027ba0000613d000000250500002900000026045000690000000003050019000027b60000013d000000400300043d0000137106000041000000000063043500000004063000390000006007000039000125b10000003d00004b3b0000013d0000131705500197000125b40000003d0000485c0000013d000000260760006c000026af0000813d00000025076000290000002006600039000000000856001900000000080804330000000000870435000025b40000013d0000130005000041000013000610009c0000000001058019000013000620009c0000000002058019000125c30000003d0000460e0000013d0000130b011001c70000800902000039000125c70000003d000044570000013d000113000010019d0000130005100197000000000105004b000025d60000613d000125cd0000003d000044ac0000013d000025d20000613d0000000006000019000125d10000003d000044210000013d000025cf0000413d000000000601004b000025d60000613d000125d60000003d0000440f0000013d000000000102004b000026d70000c13d0000435d0000013d0000134b0350009c0000273b0000c13d0000130904100197000000230140006b000029580000613d000000400200043d0000000001000414000000040340008c0000274b0000c13d00000001020000390000000105000031000027590000013d0000137202000041000125e80000003d000045960000013d000000400100043d002500000001001d007e00190000002d000125ed0000003d0000441d0000013d0000007e0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000029580000613d00000026020000290000002503000029000029530000013d0000000002000411000000230320006b0000260e0000c13d00000000020000310000003f032000390000001f0430017f000126020000003d000046cd0000013d000026070000613d0000000008000019000126060000003d000045760000013d000026040000413d000000000805004b0000260b0000613d0001260b0000003d000044790000013d0001260d0000003d00004a190000013d0000130902200197000000000112013f000013090110019800002cdb0000613d0000001b01000029000126140000003d00004adf0000013d000126160000003d000049d60000013d0000131702200197000126190000003d000049110000013d0000131d030000410001261c0000003d0000448d0000013d0000131e030000410001261f0000003d000045d80000013d0000001902000029000126220000003d000047c70000013d0000131702200197000126250000003d000049ae0000013d0000131d03000041000126280000003d000045020000013d0000131e050000410001262b0000003d0000453e0000013d00000018020000290000000002020433002000000002001d00000015020000290000000002020433001f00000002001d00000014020000290000000002020433001d00000002001d00000013020000290000000002020433001b00000002001d00000012020000290000000002020433001e00000001001d00000000120204344bfc43d70000040f0000001b020000290000131702200197000126400000003d000045650000013d0000130902200197000126430000003d000048f80000013d0000130902200197000002400340003900000000002304350000131f02000041000126490000003d000047610000013d002200000002001d003b13090020019b002400000001001d0001264e0000003d0000441d0000013d0000003b0440008a00000020044000c90000132002000041000126530000003d00004bcc0000013d000126550000003d000045110000013d0000132102000041000126580000003d0000471c0000013d00001322020000410001265b0000003d0000486e0000013d00001309011001970001265e0000003d000045c40000013d0000132302000041000126610000003d000046bb0000013d002213090020019b000126640000003d0000468d0000013d000027690000c13d0000001a060000290000000006060433000000410660008c000027780000c13d0000001c060000290000000006060433002100000006001d0000001a070000290001266f0000003d000048680000013d000013280770009c0000277b0000813d000000f8076002700000132b0660009c000004a2069000390000277e0000813d0000001b0870008a000000020880008c00002b020000813d00000024020000290001267b0000003d000044f30000013d0000000001000414000000200530008a00000001020000390000002006000039000027890000013d000000400300043d0000137106000041000000000063043500000004063000390000002207000029000126870000003d00004b3b0000013d00001317055001970001268a0000003d0000485c0000013d000000260760006c000027920000813d000000250760002900000020066000390000000008560019000000000808043300000000008704350000268a0000013d0000130005000041000013000610009c0000000001058019000013000620009c0000000002058019000126990000003d0000460e0000013d0000130b011001c700008009020000390001269d0000003d000044570000013d000113000010019d0000130005100197000000000105004b000026ac0000613d000126a30000003d000044ac0000013d000026a80000613d0000000006000019000126a70000003d000044210000013d000026a50000413d000000000601004b000026ac0000613d000126ac0000003d0000440f0000013d000000000102004b000027ba0000c13d0000435d0000013d001f130900d0019b000000260560006c000026b50000a13d000000260600002900000025056000290000000000050435000000000404043300001309022001970000004405300039000000000025043500001309011001970000002402300039000000000012043500000084013000390000000000410435000000400100043d001e00000001001d0043001f0000002d000126c30000003d0000441d0000013d000000430440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001f02000029000000040220008c000026d70000613d000126cf0000003d0000496f0000013d0000001e0300002900000000043200490000001f02000029000000000503001900000000060000194bfc000d0000040f000000000101004b000001560000613d0000000f010000290000000001010433001d00000001001d00000012010000290000000001010433001c00000001001d0000000c010000290000000001010433001a00000001001d000000130100002900000000010104330000000012010434001800000002001d0000000001010433001e00000001001d000000140100002900000000010104330000000001010433000000001201043400001317022001970000135f0320009c0000281e0000613d000013640320009c0000281e0000613d000013790320009c000028b10000c13d0000000003010433000000002103043400001308040000410000003f0510008c000000000500001900000000050420190000130806100197000000000706004b0000000004008019000013080660009c000000000405c019000000000404004b0000006d0000613d00000000040204330000130a0440009c0000006d0000813d00000040033000390000000003030433000013160430009c0000006d0000813d0000000001120019000000000423001900000000024100490000130803000041000000bf0520008c000000000500001900000000050320190000130802200197000000000602004b0000000003008019000013080220009c000000000305c019000000000203004b0000006d0000613d000000400200043d002600000002001d0000137c0320009c00001b020000813d000127190000003d00004b100000013d000013160630009c0000006d0000813d00000000034300190000001f063000390000130807000041000127200000003d00004adb0000013d00001308066001970000130809100197000127240000003d000049970000013d000013080660009c000000000708c019000000000607004b0000006d0000613d0000000086030434000013160360009c00001b020000813d0001272d0000003d00004bc50000013d00001b020000413d000013160a90009c00001b020000813d000000400090043f0000000009670436000000000a680019000000000a1a004b0000006d0000213d000000000a000019000000000b6a004b000028fe0000813d0001273a0000003d000048e60000013d000027360000013d000000400300043d0000137105000041000000000053043500000004053000390000002206000029000127420000003d000044a00000013d0000131704400197000127450000003d000044e70000013d000000260650006c0000293a0000813d00000025065000290001274a0000003d000045260000013d000027450000013d0000130003000041000013000510009c0000000001038019000013000520009c0000000002038019000127520000003d0000460e0000013d0000130b011001c700008009020000390000001f03000029000127570000003d000044570000013d000113000010019d0000130005100197000000000105004b000027660000613d0001275d0000003d000044ac0000013d000027620000613d0000000006000019000127610000003d000044210000013d0000275f0000413d000000000601004b000027660000613d000127660000003d0000440f0000013d000000000102004b000029580000c13d0000435d0000013d000013240600004100000024070000290001276d0000003d000049ff0000013d0000001a02000029000127700000003d000049610000013d000000000412004b00002adf0000813d00000000043200190000001c05200029000000000505043300000000005404350000002002200039000027700000013d00001310010000410000002403000029000012710000013d00001310010000410000002406000029000013100000013d000127800000003d000049a40000013d00002b020000813d0000132c02000041000127840000003d00004be20000013d000127860000003d000045530000013d0000000001000414000127890000003d00004b570000013d4bfc00340000040f000000000101004b000001560000613d000000400200043d000000200120008a0000000001010433000013090110019800002b050000c13d0000195f0000013d001e130900d0019b000000260560006c000027980000a13d000000260600002900000025056000290000000000050435000000000404043300001309022001970000004405300039000000000025043500001309011001970000002402300039000000000012043500000084013000390000000000410435000000400100043d001d00000001001d004a001e0000002d000127a60000003d0000441d0000013d0000004a0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001e02000029000000040220008c000027ba0000613d000127b20000003d0000496f0000013d0000001d0300002900000000043200490000001e02000029000000000503001900000000060000194bfc000d0000040f000000000101004b000001560000613d0000000e010000290000000001010433001d00000001001d0000000d010000290000000001010433001c00000001001d0000000b010000290000000001010433001a00000001001d000000140100002900000000010104330000000012010434001800000002001d0000000001010433001e00000001001d000000130100002900000000010104330000000001010433000000001201043400001317022001970000135f0320009c00002b0c0000613d000013640320009c00002b0c0000613d000013790320009c00002b9f0000c13d0000000003010433000000002103043400001308040000410000003f0510008c000000000500001900000000050420190000130806100197000000000706004b0000000004008019000013080660009c000000000405c019000000000404004b0000006d0000613d00000000040204330000130a0440009c0000006d0000813d00000040033000390000000003030433000013160430009c0000006d0000813d0000000001120019000000000423001900000000024100490000130803000041000000bf0520008c000000000500001900000000050320190000130802200197000000000602004b0000000003008019000013080220009c000000000305c019000000000203004b0000006d0000613d000000400200043d002600000002001d0000137c0320009c00001b020000813d000127fc0000003d00004b100000013d000013160630009c0000006d0000813d00000000034300190000001f063000390000130807000041000128030000003d00004adb0000013d00001308066001970000130809100197000128070000003d000049970000013d000013080660009c000000000708c019000000000607004b0000006d0000613d0000000086030434000013160360009c00001b020000813d000128100000003d00004bc50000013d00001b020000413d000013160a90009c00001b020000813d000000400090043f0000000009670436000000000a680019000000000a1a004b0000006d0000213d000000000a000019000000000b6a004b00002beb0000813d0001281d0000003d000048e60000013d000028190000013d000000000101043300000000230104340000130804000041000128230000003d00004abf0000013d0000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d00000000020204330000130a0320009c0000006d0000813d0000016203000039000000000503041a001f00000005001d00000040011000390000000001010433000000400400043d000000240340003900000000001304350000137d01000041000128380000003d00004b640000013d005713090050019b0001283b0000003d0000441d0000013d000000570440008a00000020044000c900001320020000414bfc43ed0000040f0000001f020000290000130902200197000000000101004b0000006d0000613d0000000001000414000000040320008c0000284b0000613d000128480000003d00004a570000013d000001560000613d000000400100043d002600000001001d0001284d0000003d000048260000013d000028540000613d000000000500001900000005065002100000002607600029000128530000003d000045be0000013d0000284f0000413d000000000503004b0000285b0000613d0000000504400210000000000242034f00000026044000290001285b0000003d0000446e0000013d00001308020000410001285e0000003d00004ac30000013d0000130804100197000000000504004b0000000002008019000013080440009c000000000203c0190000001f03100039000000200400008a000000000343016f0000002603300029001f00000003001d000000400030043f000000000202004b0000006d0000613d00000026020000290000000002020433000013160320009c0000006d0000813d000000260110002900000026022000290000001f032000390000130804000041000128750000003d00004abb0000013d00001308033001970000130806100197000128790000003d00004ab70000013d000013080330009c000000000405c019000000000304004b0000006d0000613d0000000032020434000013160420009c00001b020000813d00000005042002100000001f0440002900000020044000390000001f0540006c00001b020000413d000013160540009c00001b020000813d000000400040043f0000001f04000029000000000024043500000006042002100000000004430019000000000441004b0000006d0000413d00001308040000410000001f050000290000000006000019000000000726004b00002ff60000813d00000000073100490000003f0870008c000000000800001900000000080420190000130807700197000000000907004b00000000090000190000000009044019000013080770009c000000000908c019000000000709004b0000006d0000613d000000400700043d000013190870009c00001b020000813d0000004008700039000000400080043f00000000980304340000130a0a80009c0000006d0000813d000000000887043600000000090904330000136b0a90009c0000006d0000813d00000020055000390000000000980435000000000075043500000001066000390000004003300039000028910000013d001f00600000003d0000137a0220009c00002ff60000c13d0000000003010433000000002103043400001308040000410000003f0510008c000000000500001900000000050420190000130806100197000000000706004b0000000004008019000013080660009c000000000405c019000000000404004b0000006d0000613d00000000040204330000130a0440009c0000006d0000813d00000040033000390000000003030433000013160430009c0000006d0000813d00000000011200190000000004230019000000000241004900001308030000410000009f0520008c000000000500001900000000050320190000130802200197000000000602004b0000000003008019000013080220009c000000000305c019000000000203004b0000006d0000613d000000400200043d002600000002001d0000137b0220009c00001b020000813d000128dc0000003d00004b200000013d000013160320009c0000006d0000813d00000000034200190000001f023000390000130806000041000128e30000003d00004ab30000013d00001308022001970000130808100197000128e70000003d00004aa70000013d000013080220009c000000000607c019000000000206004b0000006d0000613d0000000086030434000013160260009c00001b020000813d000128f00000003d00004ba30000013d00001b020000413d000013160920009c00001b020000813d000000400020043f00000000096704360000000002680019000000000212004b0000006d0000213d000000000a00001900000000026a004b00002c270000813d000128fd0000003d000048e60000013d000028f90000013d00000000026a004b000029020000a13d00000000026900190000000000020435000129040000003d000049e20000013d000013160650009c0000006d0000813d00000000054500190000001f0650003900001308070000410001290b0000003d00004adb0000013d000013080660019700001308091001970001290f0000003d000049970000013d000013080660009c000000000708c019000000000607004b0000006d0000613d0000000065050434000013160750009c00001b020000813d000129180000003d000048ce0000013d00001b020000413d000013160980009c00001b020000813d0001291d0000003d000048c80000013d0000006d0000413d00001308080000410000000009070019000000000a000019000000000b5a004b00002c650000813d000129250000003d000046fc0000013d0000130802200197000129280000003d0000495d0000013d000013080220009c000000000c0bc01900000000020c004b0000006d0000613d000000400b00043d000013190cb0009c00001b020000813d000129310000003d00004b2e0000013d0000130a0ec0009c0000006d0000813d000000000ccb0436000000000d0d04330000136b0ed0009c0000006d0000813d000129390000003d0000474d0000013d000029210000013d000000260450006c0000293e0000a13d0001293e0000003d00004b1c0000013d00000000020204330000130901100197000129420000003d000049bc0000013d001f00000001001d005400190000002d000129460000003d0000441d0000013d000000540440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000029580000613d000129520000003d0000496f0000013d0000001f0300002900000000043200490000001902000029000129570000003d0000452b0000013d000001560000613d0000000b010000290000000001010433001d00000001001d0000000021010434001a00000002001d000000000201004b0000405f0000613d000000140200002900000000020204330000000023020434001700000003001d00000000030204330000000d020000290000000002020433001913090020019b0000000e020000290000000002020433001813090020019b002500000000001d001f00000003001d001e00000003001d002600000000001d000000010210008a000000260320006b00002ca00000813d000000260110006b00001b020000813d000000260100002900000005011002100000001a0110002900000000020104330000002002200039000000000202043300001370022001970000001f0300006b0000000004000019000029810000613d0000001f342000b90000001f534000fa000000000323004b000041ad0000c13d002500250020002e000041bf0000413d000027100240008c00002a840000413d000027102340011a0000001e0230006b00001ccd0000413d000000400500043d0000004002500039000000400020043f0000001702000029000000000225043600000000003204350000001d060000290000000006060433000000260660006b00001b020000813d001e001e00300071000129950000003d000049360000013d0000131707700197000013640870009c000029b60000c13d0001299a0000003d00004b510000013d0000130808000041000000000600001900000000060820190000130805500197000129a00000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000003030433001c13090030019b0000130a0330009c0000006d0000813d000027100340008a000027100330008c000042340000813d000129ad0000003d0000473f0000013d000013090110019700000004063000390000001908000029000000230780006b000029fd0000c13d0000137807000041000129b50000003d000044870000013d00002a270000013d0000134a0470009c00002a080000c13d000129ba0000003d00004b4d0000013d0000130807000041000000000500001900000000050720190000130804400197000129c00000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000002020433001c13090020019b0000130a0220009c0000006d0000813d000000400400043d001400440040003d0000002402400039001b00000004001d000000040440003900001309011001970000001906000029000000230560006b00002a3a0000c13d0000137505000041000129d40000003d0000470e0000013d0039001c0000002d000129d70000003d0000441d0000013d000000390440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001c02000029000000040220008c000029ea0000613d0000001b03000029000000140430006900000020060000390000001c02000029000129e70000003d0000460a0000013d000001560000613d000000400100043d001b00000001001d00000001010000310000001f0210008c0000130805000041000000000200001900000000020520190000130803100197000129f20000003d000047250000013d000013080330009c000129f50000003d0000469d0000013d0000006d0000613d0000001b01000029000129f90000003d0000445d0000013d0000006d0000c13d000000000101004b00002a840000c13d00002cd90000013d000013770700004100000000007304350000001c0700002900000000007604350000001906000029000000000065043500000000001404350000001b010000290000000000210435001c00840030003d00002a6e0000013d0000135f0470009c00002a580000c13d00012a0c0000003d00004b490000013d000013080800004100000000060000190000000006082019000013080550019700012a120000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000004040433001c13090040019b0000130a0440009c0000006d0000813d000000400500043d001b00c40050003d00012a1e0000003d000045890000013d000013090a10019700000040012000390000000001010433000000190c0000290000002302c0006b00002a640000c13d000013730200004100012a270000003d000044c30000013d000000400100043d001400000001001d0093001c0000002d00012a2c0000003d0000441d0000013d000000930440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001c02000029000000040220008c00002a840000613d00000014030000290000001b043000690000001c0200002900002a810000013d00001374050000410000001b0600002900000000005604350000001c050000290000000000540435000000190400002900000000004204350000001402000029000000000012043500000064016000390000000000310435000000400100043d001c00000001001d006b00180000002d00012a4a0000003d0000441d0000013d0000006b0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001802000029000000040220008c00002a840000613d0000001c030000290000001b02300069000000840420003900002a800000013d0000134b0470009c00002a890000c13d0000130904100197000000230140006b00002a840000613d000000400200043d0000000001000414000000040540008c00002ac20000c13d0000000102000039000000010100003100002acf0000013d000013720200004100000000002504350000001c0200002900000000002b0435000000190200002900012a6b0000003d00004bf50000013d0000001b010000290000000000010435001c00e40050003d000000400100043d001b00000001001d007f00180000002d00012a730000003d0000441d0000013d0000007f0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001802000029000000040220008c00002a840000613d0000001c020000290000001b030000290000000004320049000000180200002900012a830000003d0000452b0000013d000001560000613d0000001d0100002900000000010104330000002602000029002600010020003d0000296e0000013d000000400300043d00001371040000410000000000430435000000040430003900000022060000290000000000640435000000000405043300012a920000003d000045210000013d0000131704400197000000a40630003900000000004604350000000004050433000000c4053000390000000000750435000000e4053000390000000006040433001c00000006001d0000000000650435001b01040030003d00000000050000190000001c0650006c00002aa40000813d0000001b0650002900012aa30000003d000045260000013d00002a9e0000013d0000001c0450006c00002aa90000a13d0000001c050000290000001b0450002900000000000404350000000002020433000013090110019700012aad0000003d000049b30000013d001400000001001d005500180000002d00012ab10000003d0000441d0000013d000000550440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001802000029000000040220008c00002a840000613d0000001c020000290000001f02200039000000200300008a000000000232016f0000001b02200029000000140300002900002a7f0000013d000013000510009c00001300060000410000000001068019000013000520009c000000000206801900012ac90000003d0000460e0000013d0000130b011001c7000080090200003900012acd0000003d000044570000013d000113000010019d0000130001100197000000000301004b00002adc0000613d00012ad30000003d000044290000013d00002ad80000613d000000000600001900012ad70000003d000044210000013d00002ad50000413d0000001f0110019000002adc0000613d00012adc0000003d0000440f0000013d000000000102004b00002a840000c13d0000435d0000013d002400000031001d0000001f0110019000002ae40000613d00012ae40000003d000049660000013d000000400100043d002600000001001d009700220000002d00012ae90000003d0000441d0000013d000000970440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002202000029000000040220008c00002af80000613d00012af50000003d00004a4b0000013d000001560000613d000000400100043d002600000001001d00000001010000310000001f0110008c0000006d0000a13d000000260100002900000000010104330000131701100197000013240110009c00002cdb0000613d0000002603000029000012ae0000013d00001310010000410000002406000029000019670000013d000000220110006c00002cda0000c13d00000017010000290000000001010433000013090110019800002cdb0000c13d0000197a0000013d00000000010104330000000023010434000013080400004100012b110000003d00004abf0000013d0000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d00000000020204330000130a0320009c0000006d0000813d0000016203000039000000000503041a002200000005001d00000040011000390000000001010433000000400400043d000000240340003900000000001304350000137d0100004100012b260000003d00004b640000013d005813090050019b00012b290000003d0000441d0000013d000000580440008a00000020044000c900001320020000414bfc43ed0000040f00000022020000290000130902200197000000000101004b0000006d0000613d0000000001000414000000040320008c00002b390000613d00012b360000003d00004a570000013d000001560000613d000000400100043d002600000001001d00012b3b0000003d000048260000013d00002b420000613d00000000050000190000000506500210000000260760002900012b410000003d000045be0000013d00002b3d0000413d000000000503004b00002b490000613d0000000504400210000000000242034f000000260440002900012b490000003d0000446e0000013d000013080200004100012b4c0000003d00004ac30000013d0000130804100197000000000504004b0000000002008019000013080440009c000000000203c0190000001f03100039000000200400008a000000000343016f0000002603300029002200000003001d000000400030043f000000000202004b0000006d0000613d00000026020000290000000002020433000013160320009c0000006d0000813d000000260110002900000026022000290000001f03200039000013080400004100012b630000003d00004abb0000013d0000130803300197000013080610019700012b670000003d00004ab70000013d000013080330009c000000000405c019000000000304004b0000006d0000613d0000000032020434000013160420009c00001b020000813d000000050420021000000022044000290000002004400039000000220540006c00001b020000413d000013160540009c00001b020000813d000000400040043f0000002204000029000000000024043500000006042002100000000004430019000000000441004b0000006d0000413d000013080400004100000022050000290000000006000019000000000726004b000030380000813d00000000073100490000003f0870008c000000000800001900000000080420190000130807700197000000000907004b00000000090000190000000009044019000013080770009c000000000908c019000000000709004b0000006d0000613d000000400700043d000013190870009c00001b020000813d0000004008700039000000400080043f00000000980304340000130a0a80009c0000006d0000813d000000000887043600000000090904330000136b0a90009c0000006d0000813d0000002005500039000000000098043500000000007504350000000106600039000000400330003900002b7f0000013d0000137a0220009c000030380000c13d0000000003010433000000002103043400001308040000410000003f0510008c000000000500001900000000050420190000130806100197000000000706004b0000000004008019000013080660009c000000000405c019000000000404004b0000006d0000613d00000000040204330000130a0440009c0000006d0000813d00000040033000390000000003030433000013160430009c0000006d0000813d00000000011200190000000004230019000000000241004900001308030000410000009f0520008c000000000500001900000000050320190000130802200197000000000602004b0000000003008019000013080220009c000000000305c019000000000203004b0000006d0000613d000000400200043d002600000002001d0000137b0220009c00001b020000813d00012bc90000003d00004b200000013d000013160320009c0000006d0000813d00000000034200190000001f02300039000013080600004100012bd00000003d00004ab30000013d0000130802200197000013080810019700012bd40000003d00004aa70000013d000013080220009c000000000607c019000000000206004b0000006d0000613d0000000086030434000013160260009c00001b020000813d00012bdd0000003d00004ba30000013d00001b020000413d000013160920009c00001b020000813d000000400020043f00000000096704360000000002680019000000000212004b0000006d0000213d000000000a00001900000000026a004b00002d020000813d00012bea0000003d000048e60000013d00002be60000013d00000000026a004b00002bef0000a13d0000000002690019000000000002043500012bf10000003d000049e20000013d000013160650009c0000006d0000813d00000000054500190000001f06500039000013080700004100012bf80000003d00004adb0000013d0000130806600197000013080910019700012bfc0000003d000049970000013d000013080660009c000000000708c019000000000607004b0000006d0000613d0000000065050434000013160750009c00001b020000813d00012c050000003d000048ce0000013d00001b020000413d000013160980009c00001b020000813d00012c0a0000003d000048c80000013d0000006d0000413d00001308080000410000000009070019000000000a000019000000000b5a004b00002d400000813d00012c120000003d000046fc0000013d000013080220019700012c150000003d0000495d0000013d000013080220009c000000000c0bc01900000000020c004b0000006d0000613d000000400b00043d000013190cb0009c00001b020000813d00012c1e0000003d00004b2e0000013d0000130a0ec0009c0000006d0000813d000000000ccb0436000000000d0d04330000136b0ed0009c0000006d0000813d00012c260000003d0000474d0000013d00002c0e0000013d00000000026a004b00002c2b0000a13d00000000026900190000000000020435000000000075043500000040024000390000000002020433000013160520009c0000006d0000813d00000000054200190000001f02500039000013080600004100012c350000003d00004ab30000013d0000130802200197000013080810019700012c390000003d00004aa70000013d000013080220009c000000000607c019000000000206004b0000006d0000613d0000000065050434000013160250009c00001b020000813d00012c420000003d000048c20000013d00001b020000413d000013160820009c00001b020000813d00012c470000003d000048e00000013d0000006d0000413d00001308080000410000000009070019000000000a00001900000000025a004b00002d7b0000813d00012c4f0000003d000046fc0000013d000013080220019700012c520000003d0000495d0000013d000013080220009c000000000c0bc01900000000020c004b0000006d0000613d000000400b00043d0000131902b0009c00001b020000813d0000004002b00039000000400020043f00000000c20604340000130a0d20009c0000006d0000813d00000000022b0436000000000c0c04330000136b0dc0009c0000006d0000813d00012c640000003d000048f20000013d00002c4b0000013d00000026020000290000006005200039000000000075043500000080054000390000000005050433000013160650009c0000006d0000813d00000000054500190000001f06500039000013080700004100012c710000003d00004adb0000013d0000130806600197000013080910019700012c750000003d000049970000013d000013080660009c000000000708c019000000000607004b0000006d0000613d0000000065050434000013160750009c00001b020000813d00012c7e0000003d000048ce0000013d00001b020000413d000013160980009c00001b020000813d00012c830000003d000048c80000013d0000006d0000413d00001308080000410000000009070019000000000a000019000000000b5a004b00002db70000813d00012c8b0000003d000046fc0000013d000013080220019700012c8e0000003d0000495d0000013d000013080220009c000000000c0bc01900000000020c004b0000006d0000613d000000400b00043d000013190cb0009c00001b020000813d00012c970000003d00004b2e0000013d0000130a0ec0009c0000006d0000813d000000000ccb0436000000000d0d04330000136b0ed0009c0000006d0000813d00012c9f0000003d0000474d0000013d00002c870000013d000000000101004b00001b020000613d00000005012002100000001a011000290000000001010433000000200210003900000000020204330000137002200197000000250220002a000041bf0000413d000027100220008c000041ea0000c13d0000001e0200006b000042e80000613d000000400400043d0000004002400039000000400020043f00000020024000390000001e03000029000000000032043500000017030000290000000000340435000000000101043300000000350304340000131705500197000013640650009c00002e0b0000c13d00000000020304330000000034020434000013080500004100012cc00000003d000048800000013d0000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d0000000003030433002613090030019b0000130a0330009c0000006d0000813d0000001e03000029000000010330008c000042340000c13d00012cd00000003d0000467b0000013d000013090110019700000004063000390000001908000029000000230780006b00002e510000c13d000013780700004100012cd80000003d000044870000013d00002f6a0000013d0000422e0000013d000019800000013d000000c00100043d000013090410019800002ce70000613d00000017010000290000000001010433000013090510019800002ce70000613d000013320300004100001333020000410000002301000039000000000445004b00002cf30000c13d000000190100002900000000010104330000130904100198000011910000613d000000800100043d0000130905100198000011910000613d000013340300004100001335020000410000002401000039000000000454004b000011910000613d000000400400043d00000064054000390000000000350435000000440340003900000000002304350000002402400039000000000012043500001310010000410000000000140435000000040140003900000020020000390000000000210435000000400100043d000000000214004900004b550000013d00000000026a004b00002d060000a13d00000000026900190000000000020435000000000075043500000040024000390000000002020433000013160520009c0000006d0000813d00000000054200190000001f02500039000013080600004100012d100000003d00004ab30000013d0000130802200197000013080810019700012d140000003d00004aa70000013d000013080220009c000000000607c019000000000206004b0000006d0000613d0000000065050434000013160250009c00001b020000813d00012d1d0000003d000048c20000013d00001b020000413d000013160820009c00001b020000813d00012d220000003d000048e00000013d0000006d0000413d00001308080000410000000009070019000000000a00001900000000025a004b00002e5c0000813d00012d2a0000003d000046fc0000013d000013080220019700012d2d0000003d0000495d0000013d000013080220009c000000000c0bc01900000000020c004b0000006d0000613d000000400b00043d0000131902b0009c00001b020000813d0000004002b00039000000400020043f00000000c20604340000130a0d20009c0000006d0000813d00000000022b0436000000000c0c04330000136b0dc0009c0000006d0000813d00012d3f0000003d000048f20000013d00002d260000013d00000026020000290000006005200039000000000075043500000080054000390000000005050433000013160650009c0000006d0000813d00000000054500190000001f06500039000013080700004100012d4c0000003d00004adb0000013d0000130806600197000013080910019700012d500000003d000049970000013d000013080660009c000000000708c019000000000607004b0000006d0000613d0000000065050434000013160750009c00001b020000813d00012d590000003d000048ce0000013d00001b020000413d000013160980009c00001b020000813d00012d5e0000003d000048c80000013d0000006d0000413d00001308080000410000000009070019000000000a000019000000000b5a004b00002e980000813d00012d660000003d000046fc0000013d000013080220019700012d690000003d0000495d0000013d000013080220009c000000000c0bc01900000000020c004b0000006d0000613d000000400b00043d000013190cb0009c00001b020000813d00012d720000003d00004b2e0000013d0000130a0ec0009c0000006d0000813d000000000ccb0436000000000d0d04330000136b0ed0009c0000006d0000813d00012d7a0000003d0000474d0000013d00002d620000013d00000026020000290000004002200039000000000072043500000060024000390000000002020433000013160520009c0000006d0000813d00000000054200190000001f02500039000013080600004100012d870000003d00004ab30000013d0000130802200197000013080810019700012d8b0000003d00004aa70000013d000013080220009c000000000607c019000000000206004b0000006d0000613d0000000065050434000013160250009c00001b020000813d00012d940000003d000048c20000013d00001b020000413d000013160820009c00001b020000813d00012d990000003d000048e00000013d0000006d0000413d00001308080000410000000009070019000000000a00001900000000025a004b00002eec0000813d00012da10000003d000046fc0000013d000013080220019700012da40000003d0000495d0000013d000013080220009c000000000c0bc01900000000020c004b0000006d0000613d000000400b00043d0000131902b0009c00001b020000813d0000004002b00039000000400020043f00000000c20604340000130a0d20009c0000006d0000813d00000000022b0436000000000c0c04330000136b0dc0009c0000006d0000813d00012db60000003d000048f20000013d00002d9d0000013d00000026020000290000008002200039001f00000002001d0000000000720435000000a0054000390000000005050433000013160650009c0000006d0000813d00000000064500190000001f046000390000130805000041000000000714004b0000000007000019000000000705401900001308044001970000130808100197000000000984004b000000000500a019000000000484013f000013080440009c000000000507c019000000000405004b0000006d0000613d0000000007060433000013160470009c00001b020000813d00012dd30000003d00004b790000013d00001b020000413d000013160850009c00001b020000813d000000400050043f000000250900002900000000007904350000130808000041000000000a060019000000000b00001900000000057b004b00002f400000813d00012de00000003d000046db0000013d0000130802200197000013080c10019700012de40000003d000049c50000013d000013080220009c000000000d05c01900000000020d004b0000006d0000613d0000002005e00039000000000c0504330000131605c0009c00001b020000813d0000003f05c00039000000000535016f000000400d00043d00000000055d0019000000000fd5004b00001b020000413d000013160f50009c00001b020000813d000000400050043f000000000fcd0436000000400ee000390000000005ce0019000000000515004b0000006d0000213d000000200990003900000000050000190000000002c5004b00002e040000813d0000000002f5001900000000045e001900000000040404330000000000420435000000200550003900002dfc0000013d0000000002c5004b00002e080000a13d0000000002cf001900000000000204350000000000d90435000000010bb0003900002ddc0000013d0000134a0650009c00002f430000c13d00000000020304330000000023020434000013080400004100012e120000003d000049aa0000013d0000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d0000000002020433002513090020019b0000130a0220009c0000006d0000813d00012e1f0000003d000049f90000013d00001309011001970000001905000029000000230450006b00002f7a0000c13d00001375040000410000002605000029000000000045043500000000001304350000001e010000290000000000120435000000400100043d002600000001001d003a00250000002d00012e2e0000003d0000441d0000013d0000003a0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002502000029000000040220008c00002e3f0000613d0000002603000029000000220430006900012e3c0000003d000045900000013d000001560000613d000000400100043d002600000001001d0000000101000031000013080300004100012e430000003d0000499b0000013d0000130804100197000000000504004b0000000003008019000013080440009c00012e490000003d0000454b0000013d0000006d0000613d000000260100002900012e4d0000003d0000445d0000013d0000006d0000c13d000000000101004b000042e80000c13d0000422e0000013d000013770700004100000000007304350000002607000029000000000076043500000019060000290000000000650435000000000014043500000025010000290000000000210435002600840030003d0000301f0000013d00000026020000290000004002200039000000000072043500000060024000390000000002020433000013160520009c0000006d0000813d00000000054200190000001f02500039000013080600004100012e680000003d00004ab30000013d0000130802200197000013080810019700012e6c0000003d00004aa70000013d000013080220009c000000000607c019000000000206004b0000006d0000613d0000000065050434000013160250009c00001b020000813d00012e750000003d000048c20000013d00001b020000413d000013160820009c00001b020000813d00012e7a0000003d000048e00000013d0000006d0000413d00001308080000410000000009070019000000000a00001900000000025a004b00002f980000813d00012e820000003d000046fc0000013d000013080220019700012e850000003d0000495d0000013d000013080220009c000000000c0bc01900000000020c004b0000006d0000613d000000400b00043d0000131902b0009c00001b020000813d0000004002b00039000000400020043f00000000c20604340000130a0d20009c0000006d0000813d00000000022b0436000000000c0c04330000136b0dc0009c0000006d0000813d00012e970000003d000048f20000013d00002e7e0000013d00000026020000290000008002200039002200000002001d0000000000720435000000a0054000390000000005050433000013160650009c0000006d0000813d00000000064500190000001f046000390000130805000041000000000714004b0000000007000019000000000705401900001308044001970000130808100197000000000984004b000000000500a019000000000484013f000013080440009c000000000507c019000000000405004b0000006d0000613d0000000007060433000013160470009c00001b020000813d00012eb40000003d00004b790000013d00001b020000413d000013160850009c00001b020000813d000000400050043f000000250900002900000000007904350000130808000041000000000a060019000000000b00001900000000057b004b00002fec0000813d00012ec10000003d000046db0000013d0000130802200197000013080c10019700012ec50000003d000049c50000013d000013080220009c000000000d05c01900000000020d004b0000006d0000613d0000002005e00039000000000c0504330000131605c0009c00001b020000813d0000003f05c00039000000000535016f000000400d00043d00000000055d0019000000000fd5004b00001b020000413d000013160f50009c00001b020000813d000000400050043f000000000fcd0436000000400ee000390000000005ce0019000000000515004b0000006d0000213d000000200990003900000000050000190000000002c5004b00002ee50000813d0000000002f5001900000000045e001900000000040404330000000000420435000000200550003900002edd0000013d0000000002c5004b00002ee90000a13d0000000002cf001900000000000204350000000000d90435000000010bb0003900002ebd0000013d00000026020000290000006002200039001f00000002001d000000000072043500000080024000390000000002020433000013160520009c0000006d0000813d00000000064200190000001f026000390000130804000041000000000512004b0000000005000019000000000504401900001308022001970000130807100197000000000872004b000000000400a019000000000272013f000013080220009c000000000405c019000000000204004b0000006d0000613d0000000007060433000013160270009c00001b020000813d00012f080000003d00004b6b0000013d00001b020000413d000013160520009c00001b020000813d000000400020043f000000250900002900000000007904350000130808000041000000000a060019000000000b00001900000000027b004b00002fef0000813d00012f150000003d000046db0000013d0000130802200197000013080c10019700012f190000003d000049c50000013d000013080220009c000000000d05c01900000000020d004b0000006d0000613d0000002002e00039000000000c0204330000131602c0009c00001b020000813d0000003f02c00039000000000232016f000000400d00043d00000000022d00190000000005d2004b00001b020000413d000013160520009c00001b020000813d000000400020043f000000000fcd0436000000400ee000390000000002ce0019000000000212004b0000006d0000213d000000200990003900000000020000190000000005c2004b00002f390000813d0000000005f2001900000000042e001900000000040404330000000000450435000000200220003900002f310000013d0000000002c2004b00002f3d0000a13d0000000002cf001900000000000204350000000000d90435000000010bb0003900002f110000013d0000002601000029000000a00110003900002ff10000013d0000135f0650009c000030080000c13d00000000020304330000000034020434000013080500004100012f4a0000003d000048800000013d0000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d0000000003030433002613090030019b0000130a0330009c0000006d0000813d000000400400043d002500c40040003d00012f590000003d000044cd0000013d000013090910019700000040012000390000000001010433000000190b0000290000002302b0006b000030140000c13d00001373020000410000000000240435000000160200002900000000002a0435000000000098043500000000001704350000001e010000290000000000160435000000a00100003900000000001504350000000000030435000000400100043d002300000001001d009400260000002d00012f6f0000003d0000441d0000013d000000940440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002602000029000000040220008c000042e80000613d000042680000013d00001374040000410000002605000029000000000045043500000025040000290000000000430435000000190300002900000000003204350000002202000029000000000012043500000064015000390000001e020000290000000000210435000000400100043d002500000001001d006c00180000002d00012f8b0000003d0000441d0000013d0000006c0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001802000029000000040220008c000042e80000613d00012f970000003d00004b8a0000013d0000349a0000013d00000026020000290000006002200039002200000002001d000000000072043500000080024000390000000002020433000013160520009c0000006d0000813d00000000064200190000001f026000390000130804000041000000000512004b0000000005000019000000000504401900001308022001970000130807100197000000000872004b000000000400a019000000000272013f000013080220009c000000000405c019000000000204004b0000006d0000613d0000000007060433000013160270009c00001b020000813d00012fb40000003d00004b6b0000013d00001b020000413d000013160520009c00001b020000813d000000400020043f000000250900002900000000007904350000130808000041000000000a060019000000000b00001900000000027b004b000030310000813d00012fc10000003d000046db0000013d0000130802200197000013080c10019700012fc50000003d000049c50000013d000013080220009c000000000d05c01900000000020d004b0000006d0000613d0000002002e00039000000000c0204330000131602c0009c00001b020000813d0000003f02c00039000000000232016f000000400d00043d00000000022d00190000000005d2004b00001b020000413d000013160520009c00001b020000813d000000400020043f000000000fcd0436000000400ee000390000000002ce0019000000000212004b0000006d0000213d000000200990003900000000020000190000000005c2004b00002fe50000813d0000000005f2001900000000042e001900000000040404330000000000450435000000200220003900002fdd0000013d0000000002c2004b00002fe90000a13d0000000002cf001900000000000204350000000000d90435000000010bb0003900002fbd0000013d0000002601000029000000a001100039000030330000013d00000026010000290000008001100039000000250200002900000000002104350000001f010000290000000001010433001f00000001001d0000001f010000290000000021010434001b00000002001d000000010210008c0000304a0000c13d0000001a020000290000000023020434000000010330008c0000304a0000c13d000130010000003d00004b720000013d00001309033001980000304a0000c13d00000000010204330000137001100197000013890110008c000033020000413d000037620000013d0000134b0350009c0000318e0000c13d0000130904100197000000230140006b000042e80000613d000000400200043d0000000001000414000000040340008c0000319e0000c13d00000001020000390000000105000031000031ac0000013d00001372020000410000000000240435000000260200002900000000002a043500000019020000290000000000280435000000000097043500000000001604350000001e010000290001301f0000003d000046430000013d000000400100043d002500000001001d008000180000002d000130240000003d0000441d0000013d000000800440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001802000029000000040220008c000042e80000613d00000026020000290000002503000029000034990000013d000000260100002900000080011000390000002502000029000000000021043500000022010000290000000001010433002200000001001d00000022010000290000000021010434001b00000002001d000000010210008c000031ba0000c13d0000001a020000290000000023020434000000010330008c000031ba0000c13d000130430000003d00004b720000013d0000130903300198000031ba0000c13d00000000010204330000137001100197000013890110008c000034a00000413d000037620000013d0000002302000029001613090020019b0000001c02000029001a13090020019b0000001d02000029001913090020019b002500000000001d002600000000001d0000002203000029000000260110006b000032fe0000813d000130570000003d000045370000013d0000137002200197002500250020002e000041bf0000413d0000001e0400006b0000000004000019000030610000613d0000001e542000b90000001e654000fa000000000225004b000041ad0000c13d000130630000003d00004a7f0000013d002200000005001d000000000423004b0000000003028019000000000203004b000031450000613d0001306a0000003d00004a8b0000013d0000001f050000290000000005050433000000260550006b00001b020000813d00000000010104330000000001010433000000000504043300000000560504340000131706600197000013640760009c000030920000c13d000000000205043300000000450204340000003f0650008c00001308080000410000000006000019000000000608201900001308055001970001307e0000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000004040433001d13090040019b0000130a0440009c0000006d0000813d000000010330008c000042340000c13d0001308a0000003d000045300000013d00001309011001970001308d0000003d000046a50000013d000030d40000c13d0000137807000041000130910000003d000044870000013d000030f80000013d0000134a0760009c000030da0000c13d000000000205043300000000240204340000001f0540008c00001308070000410000000005000019000000000507201900001308044001970001309d0000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000002020433001d13090020019b0000130a0220009c0000006d0000813d000130a70000003d000049ca0000013d00001309011001970000001a06000029000000230560006b0000310b0000c13d0000137505000041000130ae0000003d0000490a0000013d0028001d0000002d000130b10000003d0000441d0000013d000000280440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c000030c10000613d0000001c03000029000130be0000003d000045ec0000013d000001560000613d000000400100043d001c00000001001d00000001010000310000001f0210008c0000130805000041000000000200001900000000020520190000130803100197000130c90000003d000047250000013d000013080330009c000130cc0000003d000044d40000013d0000006d0000613d0000001c01000029000130d00000003d0000445d0000013d0000006d0000c13d000000000101004b000031450000c13d000034800000013d000013770700004100000000007304350000001d07000029000130d90000003d000045f30000013d0000312f0000013d0000135f0760009c000031200000c13d000000000205043300000000450204340000003f0650008c0000130808000041000000000600001900000000060820190000130805500197000130e50000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000004040433001d13090040019b0000130a0440009c0000006d0000813d000000400500043d001c00c40050003d000130f10000003d000045890000013d000013090a100197000130f40000003d000045b90000013d0000312c0000c13d0000137302000041000130f80000003d000044c30000013d000000400100043d001700000001001d0082001d0000002d000130fd0000003d0000441d0000013d000000820440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c000031450000613d00000017030000290000001c043000690000001d02000029000031420000013d00001374050000410000001c060000290001310f0000003d000044b70000013d005a00190000002d000131120000003d0000441d0000013d0000005a0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000031450000613d0000001d030000290000001c023000690000008404200039000031410000013d0000134b0560009c0000314a0000c13d0000130904100197000000230140006b000031450000613d000000400200043d0000000001000414000000040540008c000031710000c13d000000010200003900000001010000310000317e0000013d00001372020000410001312f0000003d0000478b0000013d000000400100043d001d00000001001d006e00190000002d000131340000003d0000441d0000013d0000006e0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000031450000613d0000001c020000290000001d0300002900000000043200490000001902000029000131440000003d0000452b0000013d000001560000613d0000001f0100002900000000010104330000002602000029002600010020003d000030520000013d000000400300043d00001371050000410001314e0000003d0000444d0000013d0000131704400197000131510000003d0000461e0000013d0000001d0650006c000031570000813d0000001c06500029000131560000003d000045260000013d000031510000013d0000001d0450006c0000315c0000a13d0000001d050000290000001c04500029000000000004043500000000020204330000130901100197000131600000003d000044430000013d004400190000002d000131630000003d0000441d0000013d000000440440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000031450000613d0000001d02000029000131700000003d000045a50000013d000031400000013d000013000510009c00001300060000410000000001068019000013000520009c0000000002068019000131780000003d0000460e0000013d0000130b011001c700008009020000390001317c0000003d000044570000013d000113000010019d0000130001100197000000000301004b0000318b0000613d000131820000003d000044290000013d000031870000613d0000000006000019000131860000003d000044210000013d000031840000413d0000001f011001900000318b0000613d0001318b0000003d0000440f0000013d000000000102004b000031450000c13d0000435d0000013d000000400300043d0000137105000041000000000053043500000004053000390000002206000029000131950000003d000044a00000013d0000131704400197000131980000003d000044e70000013d000000260650006c000034810000813d00000025065000290001319d0000003d000045260000013d000031980000013d0000130003000041000013000510009c0000000001038019000013000520009c0000000002038019000131a50000003d0000460e0000013d0000130b011001c700008009020000390000001e03000029000131aa0000003d000044570000013d000113000010019d0000130005100197000000000105004b000042c80000613d000131b00000003d000044ac0000013d000031b50000613d0000000006000019000131b40000003d000044210000013d000031b20000413d000000000601004b000042c80000613d000131b90000003d0000440f0000013d000042c80000013d0000002302000029001613090020019b0000001c02000029001a13090020019b0000001d02000029001913090020019b002500000000001d002600000000001d0000001f03000029000000260110006b0000349c0000813d000131c70000003d000045370000013d0000137002200197002500250020002e000041bf0000413d0000001e0400006b0000000004000019000031d10000613d0000001e542000b90000001e654000fa000000000225004b000041ad0000c13d000131d30000003d00004a7f0000013d001f00000005001d000000000423004b0000000003028019000000000203004b000032b50000613d000131da0000003d00004a8b0000013d00000022050000290000000005050433000000260550006b00001b020000813d00000000010104330000000001010433000000000504043300000000560504340000131706600197000013640760009c000032020000c13d000000000205043300000000450204340000003f0650008c0000130808000041000000000600001900000000060820190000130805500197000131ee0000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000004040433001d13090040019b0000130a0440009c0000006d0000813d000000010330008c000042340000c13d000131fa0000003d000045300000013d0000130901100197000131fd0000003d000046a50000013d000032440000c13d0000137807000041000132010000003d000044870000013d000032680000013d0000134a0760009c0000324a0000c13d000000000205043300000000240204340000001f0540008c00001308070000410000000005000019000000000507201900001308044001970001320d0000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000002020433001d13090020019b0000130a0220009c0000006d0000813d000132170000003d000049ca0000013d00001309011001970000001a06000029000000230560006b0000327b0000c13d00001375050000410001321e0000003d0000490a0000013d002f001d0000002d000132210000003d0000441d0000013d0000002f0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c000032310000613d0000001c030000290001322e0000003d000045ec0000013d000001560000613d000000400100043d001c00000001001d00000001010000310000001f0210008c0000130805000041000000000200001900000000020520190000130803100197000132390000003d000047250000013d000013080330009c0001323c0000003d000044d40000013d0000006d0000613d0000001c01000029000132400000003d0000445d0000013d0000006d0000c13d000000000101004b000032b50000c13d0000361e0000013d000013770700004100000000007304350000001d07000029000132490000003d000045f30000013d0000329f0000013d0000135f0760009c000032900000c13d000000000205043300000000450204340000003f0650008c0000130808000041000000000600001900000000060820190000130805500197000132550000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000004040433001d13090040019b0000130a0440009c0000006d0000813d000000400500043d001c00c40050003d000132610000003d000045890000013d000013090a100197000132640000003d000045b90000013d0000329c0000c13d0000137302000041000132680000003d000044c30000013d000000400100043d001700000001001d0089001d0000002d0001326d0000003d0000441d0000013d000000890440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c000032b50000613d00000017030000290000001c043000690000001d02000029000032b20000013d00001374050000410000001c060000290001327f0000003d000044b70000013d006100190000002d000132820000003d0000441d0000013d000000610440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000032b50000613d0000001d030000290000001c023000690000008404200039000032b10000013d0000134b0560009c000032ba0000c13d0000130904100197000000230140006b000032b50000613d000000400200043d0000000001000414000000040540008c000032e10000c13d00000001020000390000000101000031000032ee0000013d00001372020000410001329f0000003d0000478b0000013d000000400100043d001d00000001001d007500190000002d000132a40000003d0000441d0000013d000000750440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000032b50000613d0000001c020000290000001d0300002900000000043200490000001902000029000132b40000003d0000452b0000013d000001560000613d000000220100002900000000010104330000002602000029002600010020003d000031c20000013d000000400300043d0000137105000041000132be0000003d0000444d0000013d0000131704400197000132c10000003d0000461e0000013d0000001d0650006c000032c70000813d0000001c06500029000132c60000003d000045260000013d000032c10000013d0000001d0450006c000032cc0000a13d0000001d050000290000001c04500029000000000004043500000000020204330000130901100197000132d00000003d000044430000013d004b00190000002d000132d30000003d0000441d0000013d0000004b0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000032b50000613d0000001d02000029000132e00000003d000045a50000013d000032b00000013d000013000510009c00001300060000410000000001068019000013000520009c0000000002068019000132e80000003d0000460e0000013d0000130b011001c70000800902000039000132ec0000003d000044570000013d000113000010019d0000130001100197000000000301004b000032fb0000613d000132f20000003d000044290000013d000032f70000613d0000000006000019000132f60000003d000044210000013d000032f40000413d0000001f01100190000032fb0000613d000132fb0000003d0000440f0000013d000000000102004b000032b50000c13d0000435d0000013d0000002501000029000013890110008c002200000003001d000037620000813d0000000a010000290000000001010433001e00000001001d0000000021010434001b00000002001d000000010210008c0000361f0000c13d000000090200002900000000020204330000000023020434000000010330008c0000361f0000c13d000133100000003d00004b950000013d00001309022001980000361f0000c13d000133140000003d0000477d0000013d000000090200002900000000020204330000000023020434000000000303004b00001b020000613d0000001e030000290000000003030433000000000303004b00001b020000613d00000000020204330000000002020433000013090220019700000000002104350000000a0100002900000000010104330000000012010434000000000202004b00001b020000613d000000090200002900000000020204330000000023020434000000000303004b00001b020000613d0000001e030000290000000003030433000000000303004b00001b020000613d000133310000003d00004a930000013d00001370011001970000001b020000290000000002020433000000200220003900000000001204350000002301000029001613090010019b00000012010000290000000001010433001a13090010019b0000000f010000290000000001010433001913090010019b0000001301000029000133410000003d00004ae70000013d001f00220000002d0000001e010000290000000001010433000000260110006b00003b570000813d000133480000003d000045370000013d0000137002200197002500250020002e000041bf0000413d0000001d0300006b0000000003000019000033510000613d000133500000003d00004a6b0000013d000041ad0000c13d000027103230011a0000001f042000690000001f0340006c00000000030000190000000103002039000000000303004b000000000400c019002200000004001d0000001f0320006b00000000050200190000001f05004029000000000b050019000000000205004b000034380000613d000133610000003d000044dc0000013d00001b020000813d000133640000003d000048570000013d0000131705500197000013640650009c000033830000c13d000133690000003d000047a70000013d00001308070000410000000005000019000000000507201900001308044001970001336f0000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433001f13090030019b0000130a0330009c0000006d0000813d0000000103b0008c000042340000c13d0001337b0000003d000045300000013d00001309011001970001337e0000003d000046a50000013d000033c70000c13d0000137807000041000133820000003d000044870000013d000033ea0000013d0000134a0650009c000033cd0000c13d000133870000003d00004a870000013d00001308060000410000000004000019000000000406201900001308033001970001338d0000003d00004a530000013d000013080330009c000000000504c019000000000305004b0000006d0000613d0000000002020433001f13090020019b0000130a0220009c0000006d0000813d000133970000003d000046d50000013d00001309011001970000001a05000029000000230450006b000033fd0000c13d00001375040000410001339e0000003d000046030000013d0029001f0000002d000133a10000003d0000441d0000013d000000290440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001f02000029000000040220008c000033b40000613d0000001c03000029000000170430006900000020060000390000001f02000029000133b10000003d0000460a0000013d000001560000613d000000400100043d001c00000001001d00000001010000310000001f0210008c0000130805000041000000000200001900000000020520190000130803100197000133bc0000003d000047250000013d000013080330009c000133bf0000003d000044d40000013d0000006d0000613d0000001c01000029000133c30000003d0000445d0000013d0000006d0000c13d000000000101004b000034380000c13d000037610000013d000013770700004100000000007304350000001f07000029000133cc0000003d000045f30000013d000034220000013d0000135f0650009c000034110000c13d000133d10000003d000047a70000013d0000130807000041000000000500001900000000050720190000130804400197000133d70000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433001f13090030019b0000130a0330009c0000006d0000813d000000400400043d001c00c40040003d000133e30000003d000044cd0000013d0000130909100197000133e60000003d000045b90000013d0000341d0000c13d0000137302000041000133ea0000003d000045170000013d000000400100043d001700000001001d0083001f0000002d000133ef0000003d0000441d0000013d000000830440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001f02000029000000040220008c000034380000613d00000017030000290000001c043000690000001f02000029000034350000013d0000137404000041000134000000003d000048450000013d005b00190000002d000134030000003d0000441d0000013d0000005b0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000034380000613d0000001f030000290000001c023000690000008404200039000034340000013d0000134b0350009c0000343b0000c13d0000130904100197000000230140006b000034380000613d000000400200043d0000000001000414000000040340008c000034620000c13d00000001010000310000000802000029000034700000013d000013720200004100000000002404350000001f02000029000134220000003d000046120000013d000000400100043d001f00000001001d006f00190000002d000134270000003d0000441d0000013d0000006f0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000034380000613d0000001c020000290000001f0300002900000000043200490000001902000029000134370000003d0000452b0000013d000001560000613d0000002601000029002600010010003d000033410000013d000000400300043d00001371050000410001343f0000003d0000444d0000013d0000131704400197000134420000003d000048940000013d0000001f0650006c000034480000813d0000001c06500029000134470000003d000045260000013d000034420000013d0000001f0450006c0000344d0000a13d0000001f050000290000001c04500029000000000004043500000000020204330000130901100197000134510000003d000044430000013d004500190000002d000134540000003d0000441d0000013d000000450440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000034380000613d0000001f02000029000134610000003d000045a50000013d000034330000013d000013000310009c00001300050000410000000001058019000013000320009c0000000002058019000134690000003d0000460e0000013d0000130b011001c7000080090200003900000000030b00190001346e0000003d000044570000013d000113000010019d0000130001100197000000000301004b0000347d0000613d000134740000003d000044290000013d000034790000613d0000000006000019000134780000003d000044210000013d000034760000413d0000001f011001900000347d0000613d0001347d0000003d0000440f0000013d000000000102004b000034380000c13d0000435d0000013d0000422e0000013d000000260450006c000034850000a13d000134850000003d00004b1c0000013d00000000020204330000130901100197000134890000003d000049b30000013d002300000001001d005600180000002d0001348d0000003d0000441d0000013d000000560440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001802000029000000040220008c000042e80000613d000134990000003d00004b020000013d00000000043200490000001802000029000042e50000013d0000002501000029000013890110008c001f00000003001d000037620000813d00000009010000290000000001010433001e00000001001d0000000021010434001b00000002001d000000010210008c000037660000c13d0000000a0200002900000000020204330000000023020434000000010330008c000037660000c13d000134ae0000003d00004b950000013d0000130902200198000037660000c13d000134b20000003d0000477d0000013d0000000a0200002900000000020204330000000023020434000000000303004b00001b020000613d0000001e030000290000000003030433000000000303004b00001b020000613d0000000002020433000000000202043300001309022001970000000000210435000000090100002900000000010104330000000012010434000000000202004b00001b020000613d0000000a0200002900000000020204330000000023020434000000000303004b00001b020000613d0000001e030000290000000003030433000000000303004b00001b020000613d000134cf0000003d00004a930000013d00001370011001970000001b020000290000000002020433000000200220003900000000001204350000002301000029001613090010019b0000000d010000290000000001010433001a13090010019b0000000e010000290000000001010433001913090010019b0000001401000029000134df0000003d00004ae70000013d0022001f0000002d0000001e010000290000000001010433000000260110006b00003c9e0000813d000134e60000003d000045370000013d0000137002200197002500250020002e000041bf0000413d0000001d0300006b0000000003000019000034ef0000613d000134ee0000003d00004a6b0000013d000041ad0000c13d000027103230011a0000002204200069000000220340006c00000000030000190000000103002039000000000303004b000000000400c019001f00000004001d000000220320006b00000000050200190000002205004029000000000b050019000000000205004b000035d60000613d000134ff0000003d000044dc0000013d00001b020000813d000135020000003d000048570000013d0000131705500197000013640650009c000035210000c13d000135070000003d000047a70000013d00001308070000410000000005000019000000000507201900001308044001970001350d0000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433002213090030019b0000130a0330009c0000006d0000813d0000000103b0008c000042340000c13d000135190000003d000045300000013d00001309011001970001351c0000003d000046a50000013d000035650000c13d0000137807000041000135200000003d000044870000013d000035880000013d0000134a0650009c0000356b0000c13d000135250000003d00004a870000013d00001308060000410000000004000019000000000406201900001308033001970001352b0000003d00004a530000013d000013080330009c000000000504c019000000000305004b0000006d0000613d0000000002020433002213090020019b0000130a0220009c0000006d0000813d000135350000003d000046d50000013d00001309011001970000001a05000029000000230450006b0000359b0000c13d00001375040000410001353c0000003d000046030000013d003000220000002d0001353f0000003d0000441d0000013d000000300440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002202000029000000040220008c000035520000613d0000001c030000290000001704300069000000200600003900000022020000290001354f0000003d0000460a0000013d000001560000613d000000400100043d001c00000001001d00000001010000310000001f0210008c00001308050000410000000002000019000000000205201900001308031001970001355a0000003d000047250000013d000013080330009c0001355d0000003d000044d40000013d0000006d0000613d0000001c01000029000135610000003d0000445d0000013d0000006d0000c13d000000000101004b000035d60000c13d000038a80000013d0000137707000041000000000073043500000022070000290001356a0000003d000045f30000013d000035c00000013d0000135f0650009c000035af0000c13d0001356f0000003d000047a70000013d0000130807000041000000000500001900000000050720190000130804400197000135750000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433002213090030019b0000130a0330009c0000006d0000813d000000400400043d001c00c40040003d000135810000003d000044cd0000013d0000130909100197000135840000003d000045b90000013d000035bb0000c13d0000137302000041000135880000003d000045170000013d000000400100043d001700000001001d008a00220000002d0001358d0000003d0000441d0000013d0000008a0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002202000029000000040220008c000035d60000613d00000017030000290000001c043000690000002202000029000035d30000013d00001374040000410001359e0000003d0000482b0000013d006200190000002d000135a10000003d0000441d0000013d000000620440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000035d60000613d00000022030000290000001c023000690000008404200039000035d20000013d0000134b0350009c000035d90000c13d0000130904100197000000230140006b000035d60000613d000000400200043d0000000001000414000000040340008c000036000000c13d000000010100003100000008020000290000360e0000013d000013720200004100000000002404350000002202000029000135c00000003d000046120000013d000000400100043d002200000001001d007600190000002d000135c50000003d0000441d0000013d000000760440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000035d60000613d0000001c02000029000000220300002900000000043200490000001902000029000135d50000003d0000452b0000013d000001560000613d0000002601000029002600010010003d000034df0000013d000000400300043d0000137105000041000135dd0000003d0000444d0000013d0000131704400197000135e00000003d000048a00000013d000000220650006c000035e60000813d0000001c06500029000135e50000003d000045260000013d000035e00000013d000000220450006c000035eb0000a13d00000022050000290000001c04500029000000000004043500000000020204330000130901100197000135ef0000003d000044430000013d004c00190000002d000135f20000003d0000441d0000013d0000004c0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000035d60000613d0000002202000029000135ff0000003d000045a50000013d000035d10000013d000013000310009c00001300050000410000000001058019000013000320009c0000000002058019000136070000003d0000460e0000013d0000130b011001c7000080090200003900000000030b00190001360c0000003d000044570000013d000113000010019d0000130001100197000000000301004b0000361b0000613d000136120000003d000044290000013d000036170000613d0000000006000019000136160000003d000044210000013d000036140000413d0000001f011001900000361b0000613d0001361b0000003d0000440f0000013d000000000102004b000035d60000c13d0000435d0000013d0000422e0000013d0000002302000029001613090020019b00000012020000290000000002020433001a13090020019b0000000f020000290000000002020433001913090020019b000000130200002900000000020204330000000023020434001800000003001d0000000002020433001d00000002001d001f00000000001d002600000000001d002500220000002d000000260110006b000038a90000813d000136340000003d000045370000013d0000137002200197001f001f0020002e000041bf0000413d0000001d0300006b00000000030000190000363d0000613d0001363c0000003d00004a6b0000013d000041ad0000c13d0001363f0000003d00004a630000013d002200000004001d000000250320006b00000000050200190000002505004029000000000b050019000000000205004b000037090000613d000136480000003d000044dc0000013d00001b020000813d0001364b0000003d000048570000013d0000131705500197000013640650009c0000367c0000c13d000136500000003d000047a70000013d0000130807000041000000000500001900000000050720190000130804400197000136560000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433002513090030019b0000130a0330009c0000006d0000813d0000000103b0008c000042340000c13d000136620000003d000045300000013d0000130901100197000136650000003d000046a50000013d000036be0000c13d0000137807000041000136690000003d000044870000013d000000400100043d001700000001001d008400250000002d0001366e0000003d0000441d0000013d000000840440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002502000029000000040220008c000037090000613d00000017030000290000001c043000690000002502000029000037060000013d0000134a0650009c000036d40000c13d000136800000003d00004a870000013d0000130806000041000000000400001900000000040620190000130803300197000136860000003d00004a530000013d000013080330009c000000000504c019000000000305004b0000006d0000613d0000000002020433002513090020019b0000130a0220009c0000006d0000813d000136900000003d000046d50000013d00001309011001970000001a05000029000000230450006b000036f20000c13d0000137504000041000136970000003d000046030000013d002a00250000002d0001369a0000003d0000441d0000013d0000002a0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002502000029000000040220008c000036ab0000613d0000001c030000290000001704300069000136a80000003d000045900000013d000001560000613d000000400100043d001c00000001001d00000001010000310000001f0210008c0000130805000041000000000200001900000000020520190000130803100197000136b30000003d000047250000013d000013080330009c000136b60000003d000044d40000013d0000006d0000613d0000001c01000029000136ba0000003d0000445d0000013d0000006d0000c13d000000000101004b000037090000c13d00003a040000013d0000137707000041000136c10000003d000049490000013d000000400100043d001c00000001001d007000190000002d000136c60000003d0000441d0000013d000000700440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000037090000613d00000025020000290000001c030000290000000004320049000037050000013d0000135f0650009c0000370c0000c13d000136d80000003d000047a70000013d0000130807000041000000000500001900000000050720190000130804400197000136de0000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433002513090030019b0000130a0330009c0000006d0000813d000000400400043d001c00c40040003d000136ea0000003d000044cd0000013d0000130909100197000136ed0000003d000045b90000013d000037180000c13d0000137302000041000136f10000003d000045170000013d000036690000013d0000137404000041000136f50000003d000048380000013d005c00190000002d000136f80000003d0000441d0000013d0000005c0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000037090000613d00000025030000290000001c0230006900000084042000390000001902000029000137080000003d0000452b0000013d000001560000613d0001370b0000003d000048520000013d0000362f0000013d0000134b0350009c0000371c0000c13d0000130904100197000000230140006b000037090000613d000000400200043d0000000001000414000000040340008c000037430000c13d00000001020000390000000101000031000037510000013d00001372020000410001371b0000003d000047b90000013d000036c10000013d000000400300043d0000137105000041000137200000003d0000444d0000013d0000131704400197000137230000003d000048880000013d000000250650006c000037290000813d0000001c06500029000137280000003d000045260000013d000037230000013d000000250450006c0000372e0000a13d00000025050000290000001c04500029000000000004043500000000020204330000130901100197000137320000003d000044430000013d004600190000002d000137350000003d0000441d0000013d000000460440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000037090000613d0000002502000029000137420000003d000045a50000013d000036d20000013d000013000310009c00001300050000410000000001058019000013000320009c00000000020580190001374a0000003d0000460e0000013d0000130b011001c7000080090200003900000000030b00190001374f0000003d000044570000013d000113000010019d0000130001100197000000000301004b0000375e0000613d000137550000003d000044290000013d0000375a0000613d0000000006000019000137590000003d000044210000013d000037570000413d0000001f011001900000375e0000613d0001375e0000003d0000440f0000013d000000000102004b000037090000c13d0000435d0000013d0000422e0000013d000000400200043d00000044012000390000137e03000041000025770000013d0000002302000029001613090020019b0000000d020000290000000002020433001a13090020019b0000000e020000290000000002020433001913090020019b000000140200002900000000020204330000000023020434001800000003001d0000000002020433001d00000002001d002200000000001d002600000000001d0025001f0000002d000000260110006b00003a050000813d0001377b0000003d000045370000013d0000137002200197002200220020002e000041bf0000413d0000001d0300006b0000000003000019000037840000613d000137830000003d00004a6b0000013d000041ad0000c13d000137860000003d00004a630000013d001f00000004001d000000250320006b00000000050200190000002505004029000000000b050019000000000205004b000038500000613d0001378f0000003d000044dc0000013d00001b020000813d000137920000003d000048570000013d0000131705500197000013640650009c000037c30000c13d000137970000003d000047a70000013d00001308070000410000000005000019000000000507201900001308044001970001379d0000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433002513090030019b0000130a0330009c0000006d0000813d0000000103b0008c000042340000c13d000137a90000003d000045300000013d0000130901100197000137ac0000003d000046a50000013d000038050000c13d0000137807000041000137b00000003d000044870000013d000000400100043d001700000001001d008b00250000002d000137b50000003d0000441d0000013d0000008b0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002502000029000000040220008c000038500000613d00000017030000290000001c0430006900000025020000290000384d0000013d0000134a0650009c0000381b0000c13d000137c70000003d00004a870000013d0000130806000041000000000400001900000000040620190000130803300197000137cd0000003d00004a530000013d000013080330009c000000000504c019000000000305004b0000006d0000613d0000000002020433002513090020019b0000130a0220009c0000006d0000813d000137d70000003d000046d50000013d00001309011001970000001a05000029000000230450006b000038390000c13d0000137504000041000137de0000003d000046030000013d003100250000002d000137e10000003d0000441d0000013d000000310440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002502000029000000040220008c000037f20000613d0000001c030000290000001704300069000137ef0000003d000045900000013d000001560000613d000000400100043d001c00000001001d00000001010000310000001f0210008c0000130805000041000000000200001900000000020520190000130803100197000137fa0000003d000047250000013d000013080330009c000137fd0000003d000044d40000013d0000006d0000613d0000001c01000029000138010000003d0000445d0000013d0000006d0000c13d000000000101004b000038500000c13d00003b560000013d0000137707000041000138080000003d000049490000013d000000400100043d001c00000001001d007700190000002d0001380d0000003d0000441d0000013d000000770440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000038500000613d00000025020000290000001c0300002900000000043200490000384c0000013d0000135f0650009c000038530000c13d0001381f0000003d000047a70000013d0000130807000041000000000500001900000000050720190000130804400197000138250000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433002513090030019b0000130a0330009c0000006d0000813d000000400400043d001c00c40040003d000138310000003d000044cd0000013d0000130909100197000138340000003d000045b90000013d0000385f0000c13d0000137302000041000138380000003d000045170000013d000037b00000013d00001374040000410001383c0000003d000048380000013d006300190000002d0001383f0000003d0000441d0000013d000000630440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000038500000613d00000025030000290000001c02300069000000840420003900000019020000290001384f0000003d0000452b0000013d000001560000613d000138520000003d000048520000013d000037760000013d0000134b0350009c000038630000c13d0000130904100197000000230140006b000038500000613d000000400200043d0000000001000414000000040340008c0000388a0000c13d00000001020000390000000101000031000038980000013d0000137202000041000138620000003d000047b90000013d000038080000013d000000400300043d0000137105000041000138670000003d0000444d0000013d00001317044001970001386a0000003d000048880000013d000000250650006c000038700000813d0000001c065000290001386f0000003d000045260000013d0000386a0000013d000000250450006c000038750000a13d00000025050000290000001c04500029000000000004043500000000020204330000130901100197000138790000003d000044430000013d004d00190000002d0001387c0000003d0000441d0000013d0000004d0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000038500000613d0000002502000029000138890000003d000045a50000013d000038190000013d000013000310009c00001300050000410000000001058019000013000320009c0000000002058019000138910000003d0000460e0000013d0000130b011001c7000080090200003900000000030b0019000138960000003d000044570000013d000113000010019d0000130001100197000000000301004b000038a50000613d0001389c0000003d000044290000013d000038a10000613d0000000006000019000138a00000003d000044210000013d0000389e0000413d0000001f01100190000038a50000613d000138a50000003d0000440f0000013d000000000102004b000038500000c13d0000435d0000013d0000422e0000013d00000012010000290000000001010433001a13090010019b0000000f010000290000000001010433001913090010019b00000009010000290000000001010433001e00000001001d001b00200010003d000000130100002900000000010104330000000012010434001800000002001d0000000001010433001d00000001001d002200000000001d002600000000001d001f00250000002d0000001e010000290000000001010433000000260110006b00003b570000813d000138c20000003d000045370000013d0000137002200197002200220020002e000041bf0000413d0000001d0300006b0000000003000019000038cb0000613d000138ca0000003d00004a6b0000013d000041ad0000c13d000027103230011a0000001f052000690000001f0350006c00000000030000190000000103002039000000000303004b000000000500c019002500000005001d0000001f0320006b00000000040200190000001f04004029000000000b040019000000000204004b000039bc0000613d000138db0000003d000044dc0000013d00001b020000813d000138de0000003d000048570000013d0000131705500197000013640650009c000038fd0000c13d000138e30000003d000047a70000013d0000130807000041000000000500001900000000050720190000130804400197000138e90000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433001f13090030019b0000130a0330009c0000006d0000813d0000000103b0008c000042340000c13d000138f50000003d000045300000013d0000130901100197000138f80000003d000046a50000013d000039410000c13d0000137807000041000138fc0000003d000044870000013d000039650000013d0000134a0650009c000039480000c13d000139010000003d00004a870000013d0000130806000041000000000400001900000000040620190000130803300197000139070000003d00004a530000013d000013080330009c000000000504c019000000000305004b0000006d0000613d0000000002020433001f13090020019b0000130a0220009c0000006d0000813d000139110000003d000046d50000013d00001309011001970000001a05000029000000230450006b000039780000c13d0000137504000041000139180000003d000046030000013d002b001f0000002d0001391b0000003d0000441d0000013d0000002b0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001f02000029000000040220008c0000392e0000613d0000001c03000029000000170430006900000020060000390000001f020000290001392b0000003d0000460a0000013d000001560000613d000000400100043d001c00000001001d00000001010000310000001f0210008c0000130805000041000000000200001900000000020520190000130803100197000139360000003d000047250000013d000013080330009c000139390000003d000044d40000013d0000006d0000613d0000001c010000290001393d0000003d0000445d0000013d0000006d0000c13d000000000101004b000039bc0000c13d00003c9d0000013d000013770700004100000000007304350000001f07000029000139460000003d00004b420000013d001f00840030003d000039a60000013d0000135f0650009c0000398c0000c13d0001394c0000003d000047a70000013d0000130807000041000000000500001900000000050720190000130804400197000139520000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433001f13090030019b0000130a0330009c0000006d0000813d000000400400043d001c00c40040003d0001395e0000003d000044cd0000013d0000130909100197000139610000003d000045b90000013d000039980000c13d0000137302000041000139650000003d000045170000013d000000400100043d001700000001001d0085001f0000002d0001396a0000003d0000441d0000013d000000850440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001f02000029000000040220008c000039bc0000613d00000017030000290000001c043000690000001f02000029000039b90000013d00001374040000410001397b0000003d000048450000013d005d00190000002d0001397e0000003d0000441d0000013d0000005d0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000039bc0000613d0000001f030000290000001c023000690000008404200039000039b80000013d0000134b0350009c000039bf0000c13d0000130904100197000000230140006b000039bc0000613d000000400200043d0000000001000414000000040340008c000039e60000c13d00000001020000390000000101000031000039f40000013d000013720200004100000000002404350000001f0200002900000000002a04350000001a020000290000000000280435000000000097043500000000001604350000000000b50435000000c00100003900000000001304350000001c010000290000000000010435001f00e40040003d000000400100043d001c00000001001d007100190000002d000139ab0000003d0000441d0000013d000000710440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000039bc0000613d0000001f020000290000001c0300002900000000043200490000001902000029000139bb0000003d0000452b0000013d000001560000613d0000002601000029002600010010003d000038bb0000013d000000400300043d0000137105000041000139c30000003d0000444d0000013d0000131704400197000139c60000003d000048940000013d0000001f0650006c000039cc0000813d0000001c06500029000139cb0000003d000045260000013d000039c60000013d0000001f0450006c000039d10000a13d0000001f050000290000001c04500029000000000004043500000000020204330000130901100197000139d50000003d000044430000013d004700190000002d000139d80000003d0000441d0000013d000000470440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000039bc0000613d0000001f02000029000139e50000003d000045a50000013d000039b70000013d000013000310009c00001300050000410000000001058019000013000320009c0000000002058019000139ed0000003d0000460e0000013d0000130b011001c7000080090200003900000000030b0019000139f20000003d000044570000013d000113000010019d0000130001100197000000000301004b00003a010000613d000139f80000003d000044290000013d000039fd0000613d0000000006000019000139fc0000003d000044210000013d000039fa0000413d0000001f0110019000003a010000613d00013a010000003d0000440f0000013d000000000102004b000039bc0000c13d0000435d0000013d0000422e0000013d0000000d010000290000000001010433001a13090010019b0000000e010000290000000001010433001913090010019b0000000a010000290000000001010433001e00000001001d001b00200010003d000000140100002900000000010104330000000012010434001800000002001d0000000001010433001d00000001001d001f00000000001d002600000000001d002200250000002d0000001e010000290000000001010433000000260110006b00003c9e0000813d00013a1e0000003d000045370000013d0000137002200197001f001f0020002e000041bf0000413d0000001d0300006b000000000300001900003a270000613d00013a260000003d00004a6b0000013d000041ad0000c13d000027103230011a0000002205200069000000220350006c00000000030000190000000103002039000000000303004b000000000500c019002500000005001d000000220320006b00000000040200190000002204004029000000000b040019000000000204004b00003b0e0000613d00013a370000003d000044dc0000013d00001b020000813d00013a3a0000003d000048570000013d0000131705500197000013640650009c00003a590000c13d00013a3f0000003d000047a70000013d000013080700004100000000050000190000000005072019000013080440019700013a450000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433002213090030019b0000130a0330009c0000006d0000813d0000000103b0008c000042340000c13d00013a510000003d000045300000013d000013090110019700013a540000003d000046a50000013d00003a9d0000c13d000013780700004100013a580000003d000044870000013d00003ac00000013d0000134a0650009c00003aa30000c13d00013a5d0000003d00004a870000013d000013080600004100000000040000190000000004062019000013080330019700013a630000003d00004a530000013d000013080330009c000000000504c019000000000305004b0000006d0000613d0000000002020433002213090020019b0000130a0220009c0000006d0000813d00013a6d0000003d000046d50000013d00001309011001970000001a05000029000000230450006b00003ad30000c13d000013750400004100013a740000003d000046030000013d003200220000002d00013a770000003d0000441d0000013d000000320440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002202000029000000040220008c00003a8a0000613d0000001c0300002900000017043000690000002006000039000000220200002900013a870000003d0000460a0000013d000001560000613d000000400100043d001c00000001001d00000001010000310000001f0210008c000013080500004100000000020000190000000002052019000013080310019700013a920000003d000047250000013d000013080330009c00013a950000003d000044d40000013d0000006d0000613d0000001c0100002900013a990000003d0000445d0000013d0000006d0000c13d000000000101004b00003b0e0000c13d00003de40000013d00001377070000410000000000730435000000220700002900013aa20000003d000045f30000013d00003af80000013d0000135f0650009c00003ae70000c13d00013aa70000003d000047a70000013d000013080700004100000000050000190000000005072019000013080440019700013aad0000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000003030433002213090030019b0000130a0330009c0000006d0000813d000000400400043d001c00c40040003d00013ab90000003d000044cd0000013d000013090910019700013abc0000003d000045b90000013d00003af30000c13d000013730200004100013ac00000003d000045170000013d000000400100043d001700000001001d008c00220000002d00013ac50000003d0000441d0000013d0000008c0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002202000029000000040220008c00003b0e0000613d00000017030000290000001c04300069000000220200002900003b0b0000013d000013740400004100013ad60000003d0000482b0000013d006400190000002d00013ad90000003d0000441d0000013d000000640440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c00003b0e0000613d00000022030000290000001c02300069000000840420003900003b0a0000013d0000134b0350009c00003b110000c13d0000130904100197000000230140006b00003b0e0000613d000000400200043d0000000001000414000000040340008c00003b380000c13d0000000102000039000000010100003100003b460000013d00001372020000410000000000240435000000220200002900013af80000003d000046120000013d000000400100043d002200000001001d007800190000002d00013afd0000003d0000441d0000013d000000780440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c00003b0e0000613d0000001c0200002900000022030000290000000004320049000000190200002900013b0d0000003d0000452b0000013d000001560000613d0000002601000029002600010010003d00003a170000013d000000400300043d000013710500004100013b150000003d0000444d0000013d000013170440019700013b180000003d000048a00000013d000000220650006c00003b1e0000813d0000001c0650002900013b1d0000003d000045260000013d00003b180000013d000000220450006c00003b230000a13d00000022050000290000001c0450002900000000000404350000000002020433000013090110019700013b270000003d000044430000013d004e00190000002d00013b2a0000003d0000441d0000013d0000004e0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c00003b0e0000613d000000220200002900013b370000003d000045a50000013d00003b090000013d000013000310009c00001300050000410000000001058019000013000320009c000000000205801900013b3f0000003d0000460e0000013d0000130b011001c7000080090200003900000000030b001900013b440000003d000044570000013d000113000010019d0000130001100197000000000301004b00003b530000613d00013b4a0000003d000044290000013d00003b4f0000613d000000000600001900013b4e0000003d000044210000013d00003b4c0000413d0000001f0110019000003b530000613d00013b530000003d0000440f0000013d000000000102004b00003b0e0000c13d0000435d0000013d0000422e0000013d0000000c0100002900013b5a0000003d00004a310000013d0000405f0000613d000000130200002900000000020204330000000002020433001800000002001d0000002302000029001613090020019b00000012020000290000000002020433001a13090020019b0000000f020000290000000002020433001913090020019b002500000000001d0022001f0000002d002600000000001d000000010210008a000000260320006b00003de50000813d000000260110006b00001b020000813d00013b710000003d000049240000013d00001370022001970000001f0300006b000000000400001900003b790000613d0000001f342000b90000001f534000fa000000000323004b000041ad0000c13d002500250020002e000041bf0000413d000027100240008c00003c550000413d000027102340011a000000220230006b00001ccd0000413d00013b820000003d000045e20000013d00001b020000813d002200220030007100013b860000003d000049360000013d0000131707700197000013640870009c00003ba60000c13d00013b8b0000003d00004b510000013d000013080800004100000000060000190000000006082019000013080550019700013b910000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000003030433001d13090030019b0000130a0330009c0000006d0000813d000027100340008a000027100330008c000042340000813d00013b9e0000003d0000473f0000013d000013090110019700013ba10000003d000046a50000013d00003be70000c13d000013780700004100013ba50000003d000044870000013d00003c080000013d0000134a0470009c00003beb0000c13d00013baa0000003d00004b4d0000013d000013080700004100000000050000190000000005072019000013080440019700013bb00000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000002020433001d13090020019b0000130a0220009c0000006d0000813d00013bba0000003d000049d00000013d00001309011001970000001a06000029000000230560006b00003c1b0000c13d000013750500004100013bc10000003d0000470e0000013d002c001d0000002d00013bc40000003d0000441d0000013d0000002c0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c00003bd40000613d0000001b0300002900013bd10000003d000045ec0000013d000001560000613d000000400100043d001b00000001001d00000001010000310000001f0210008c000013080500004100000000020000190000000002052019000013080310019700013bdc0000003d000047250000013d000013080330009c00013bdf0000003d0000469d0000013d0000006d0000613d0000001b0100002900013be30000003d0000445d0000013d0000006d0000c13d000000000101004b00003c550000c13d00003e1c0000013d000013770700004100013bea0000003d000046e30000013d00003c3f0000013d0000135f0470009c00003c300000c13d00013bef0000003d00004b490000013d000013080800004100000000060000190000000006082019000013080550019700013bf50000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000004040433001d13090040019b0000130a0440009c0000006d0000813d000000400500043d001b00c40050003d00013c010000003d000045890000013d000013090a10019700013c040000003d000045b90000013d00003c3c0000c13d000013730200004100013c080000003d000044c30000013d000000400100043d001700000001001d0086001d0000002d00013c0d0000003d0000441d0000013d000000860440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c00003c550000613d00000017030000290000001b043000690000001d0200002900003c520000013d00001374050000410000001b0600002900013c1f0000003d000044b70000013d005e00190000002d00013c220000003d0000441d0000013d0000005e0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c00003c550000613d0000001d030000290000001b02300069000000840420003900003c510000013d0000134b0470009c00003c580000c13d0000130904100197000000230140006b00003c550000613d000000400200043d0000000001000414000000040540008c00003c800000c13d0000000102000039000000010100003100003c8d0000013d000013720200004100013c3f0000003d000045ab0000013d000000400100043d001d00000001001d007200190000002d00013c440000003d0000441d0000013d000000720440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c00003c550000613d0000001b020000290000001d030000290000000004320049000000190200002900013c540000003d0000452b0000013d000001560000613d00013c570000003d000048520000013d00003b6a0000013d000000400300043d000013710400004100013c5c0000003d00004bef0000013d00013c5e0000003d000045210000013d000013170440019700013c610000003d0000462a0000013d0000001d0650006c00003c670000813d0000001b0650002900013c660000003d000045260000013d00003c610000013d0000001d0450006c00003c6c0000a13d0000001d050000290000001b0450002900000000000404350000000002020433000013090110019700013c700000003d000044430000013d004800190000002d00013c730000003d0000441d0000013d000000480440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c00003c550000613d00013c7f0000003d000049160000013d00003c500000013d000013000510009c00001300060000410000000001068019000013000520009c000000000206801900013c870000003d0000460e0000013d0000130b011001c7000080090200003900013c8b0000003d000044570000013d000113000010019d0000130001100197000000000301004b00003c9a0000613d00013c910000003d000044290000013d00003c960000613d000000000600001900013c950000003d000044210000013d00003c930000413d0000001f0110019000003c9a0000613d00013c9a0000003d0000440f0000013d000000000102004b00003c550000c13d0000435d0000013d0000422e0000013d0000000b0100002900013ca10000003d00004a310000013d0000405f0000613d000000140200002900000000020204330000000002020433001800000002001d0000002302000029001613090020019b0000000d020000290000000002020433001a13090020019b0000000e020000290000000002020433001913090020019b002500000000001d001f00220000002d002600000000001d000000010210008a000000260320006b00003e1d0000813d000000260110006b00001b020000813d00013cb80000003d000049240000013d0000137002200197000000220300006b000000000400001900003cc00000613d00000022342000b900000022534000fa000000000323004b000041ad0000c13d002500250020002e000041bf0000413d000027100240008c00003d9c0000413d000027102340011a0000001f0230006b00001ccd0000413d00013cc90000003d000045e20000013d00001b020000813d001f001f0030007100013ccd0000003d000049360000013d0000131707700197000013640870009c00003ced0000c13d00013cd20000003d00004b510000013d000013080800004100000000060000190000000006082019000013080550019700013cd80000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000003030433001d13090030019b0000130a0330009c0000006d0000813d000027100340008a000027100330008c000042340000813d00013ce50000003d0000473f0000013d000013090110019700013ce80000003d000046a50000013d00003d2e0000c13d000013780700004100013cec0000003d000044870000013d00003d4f0000013d0000134a0470009c00003d320000c13d00013cf10000003d00004b4d0000013d000013080700004100000000050000190000000005072019000013080440019700013cf70000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000002020433001d13090020019b0000130a0220009c0000006d0000813d00013d010000003d000049d00000013d00001309011001970000001a06000029000000230560006b00003d620000c13d000013750500004100013d080000003d0000470e0000013d0033001d0000002d00013d0b0000003d0000441d0000013d000000330440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c00003d1b0000613d0000001b0300002900013d180000003d000045ec0000013d000001560000613d000000400100043d001b00000001001d00000001010000310000001f0210008c000013080500004100000000020000190000000002052019000013080310019700013d230000003d000047250000013d000013080330009c00013d260000003d0000469d0000013d0000006d0000613d0000001b0100002900013d2a0000003d0000445d0000013d0000006d0000c13d000000000101004b00003d9c0000c13d00003e4a0000013d000013770700004100013d310000003d000046e30000013d00003d860000013d0000135f0470009c00003d770000c13d00013d360000003d00004b490000013d000013080800004100000000060000190000000006082019000013080550019700013d3c0000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000004040433001d13090040019b0000130a0440009c0000006d0000813d000000400500043d001b00c40050003d00013d480000003d000045890000013d000013090a10019700013d4b0000003d000045b90000013d00003d830000c13d000013730200004100013d4f0000003d000044c30000013d000000400100043d001700000001001d008d001d0000002d00013d540000003d0000441d0000013d0000008d0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c00003d9c0000613d00000017030000290000001b043000690000001d0200002900003d990000013d00001374050000410000001b0600002900013d660000003d000044b70000013d006500190000002d00013d690000003d0000441d0000013d000000650440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c00003d9c0000613d0000001d030000290000001b02300069000000840420003900003d980000013d0000134b0470009c00003d9f0000c13d0000130904100197000000230140006b00003d9c0000613d000000400200043d0000000001000414000000040540008c00003dc70000c13d0000000102000039000000010100003100003dd40000013d000013720200004100013d860000003d000045ab0000013d000000400100043d001d00000001001d007900190000002d00013d8b0000003d0000441d0000013d000000790440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c00003d9c0000613d0000001b020000290000001d030000290000000004320049000000190200002900013d9b0000003d0000452b0000013d000001560000613d00013d9e0000003d000048520000013d00003cb10000013d000000400300043d000013710400004100013da30000003d00004bef0000013d00013da50000003d000045210000013d000013170440019700013da80000003d0000462a0000013d0000001d0650006c00003dae0000813d0000001b0650002900013dad0000003d000045260000013d00003da80000013d0000001d0450006c00003db30000a13d0000001d050000290000001b0450002900000000000404350000000002020433000013090110019700013db70000003d000044430000013d004f00190000002d00013dba0000003d0000441d0000013d0000004f0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c00003d9c0000613d00013dc60000003d000049160000013d00003d970000013d000013000510009c00001300060000410000000001068019000013000520009c000000000206801900013dce0000003d0000460e0000013d0000130b011001c7000080090200003900013dd20000003d000044570000013d000113000010019d0000130001100197000000000301004b00003de10000613d00013dd80000003d000044290000013d00003ddd0000613d000000000600001900013ddc0000003d000044210000013d00003dda0000413d0000001f0110019000003de10000613d00013de10000003d0000440f0000013d000000000102004b00003d9c0000c13d0000435d0000013d0000422e0000013d000000000101004b00001b020000613d00013de90000003d000049750000013d0000137002200197000000250220002a000041bf0000413d000027100220008c000041ea0000c13d000000220200006b00013df10000003d0000464a0000013d0000405b0000613d000000400400043d0000004002400039000000400020043f00000020024000390000002203000029000000000032043500000018030000290000000000340435000000000101043300000000350304340000131705500197000013640650009c00003e4b0000c13d00000000020304330000000034020434000013080500004100013e040000003d000048800000013d0000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d0000000003030433002613090030019b0000130a0330009c0000006d0000813d0000002203000029000000010330008c000042340000c13d00013e140000003d0000467b0000013d000013090110019700013e170000003d000046a50000013d00003e960000c13d000013780700004100013e1b0000003d000044870000013d00003f040000013d0000422e0000013d000000000101004b00001b020000613d00013e210000003d000049750000013d0000137002200197000000250220002a000041bf0000413d000027100220008c000041ea0000c13d0000001f0200006b0000405b0000613d00013e2a0000003d000046700000013d0000131705500197000013640650009c00003e9a0000c13d00000000020304330000000034020434000013080500004100013e320000003d000048800000013d0000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d0000000003030433002613090030019b0000130a0330009c0000006d0000813d0000001f03000029000000010330008c000042340000c13d00013e420000003d0000467b0000013d000013090110019700013e450000003d000046a50000013d00003edb0000c13d000013780700004100013e490000003d000044870000013d00003f520000013d0000422e0000013d0000134a0650009c00003edf0000c13d00000000020304330000000023020434000013080400004100013e520000003d000049aa0000013d0000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d0000000002020433002513090020019b0000130a0220009c0000006d0000813d000000400300043d001f00440030003d0000002402300039002600000003001d000000040330003900001309011001970000001a05000029000000230450006b00003f190000c13d000013750400004100000026050000290000000000450435000000000013043500000022010000290000000000120435000000400100043d002600000001001d002d00250000002d00013e710000003d0000441d0000013d0000002d0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002502000029000000040220008c00003e820000613d00000026030000290000001f0430006900013e7f0000003d000045900000013d000001560000613d000000400100043d002600000001001d0000000101000031000013080300004100013e860000003d0000499b0000013d0000130804100197000000000504004b0000000003008019000013080440009c00013e8c0000003d0000454b0000013d0000006d0000613d000000260100002900013e900000003d0000445d0000013d0000006d0000c13d000000000101004b00013e940000003d0000464a0000013d0000405b0000c13d0000422e0000013d000013770700004100013e990000003d000045ce0000013d00003f910000013d0000134a0650009c00003f350000c13d00000000020304330000000023020434000013080400004100013ea10000003d000049aa0000013d0000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d0000000002020433002513090020019b0000130a0220009c0000006d0000813d00013eae0000003d000049f90000013d00001309011001970000001a05000029000000230450006b00003f650000c13d000013750400004100013eb50000003d000047f90000013d003400250000002d00013eb80000003d0000441d0000013d000000340440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002502000029000000040220008c00003ec90000613d0000002603000029000000220430006900013ec60000003d000045900000013d000001560000613d000000400100043d002600000001001d0000000101000031000013080300004100013ecd0000003d0000499b0000013d0000130804100197000000000504004b0000000003008019000013080440009c00013ed30000003d0000454b0000013d0000006d0000613d000000260100002900013ed70000003d0000445d0000013d0000006d0000c13d000000000101004b0000405b0000c13d0000422e0000013d000013770700004100013ede0000003d000045ce0000013d00003fb40000013d0000135f0650009c00003f780000c13d00000000020304330000000034020434000013080500004100013ee60000003d000048800000013d0000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d0000000003030433002613090030019b0000130a0330009c0000006d0000813d000000400400043d002500c40040003d00013ef50000003d000044cd0000013d000013090910019700013ef80000003d0000499f0000013d00003f860000c13d00001373020000410000000000240435000000160200002900000000002a04350000000000980435000000000017043500000022010000290000000000160435000000a00100003900000000001504350000000000030435000000400100043d002200000001001d008700260000002d00013f090000003d0000441d0000013d000000870440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002602000029000000040220008c00013f140000003d0000464a0000013d0000405b0000613d000000220300002900000025043000690000002602000029000040390000013d000013740400004100013f1c0000003d00004b270000013d0000001f020000290000000000120435000000640150003900000022020000290000000000210435000000400100043d002500000001001d005f00190000002d00013f260000003d0000441d0000013d0000005f0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c00013f310000003d0000464a0000013d0000405b0000613d00013f340000003d00004b8a0000013d000040380000013d0000135f0650009c00003fa50000c13d00000000020304330000000034020434000013080500004100013f3c0000003d000048800000013d0000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d0000000003030433002613090030019b0000130a0330009c0000006d0000813d000000400400043d002500c40040003d00013f4b0000003d000044cd0000013d000013090910019700013f4e0000003d0000499f0000013d00003fb10000c13d000013730200004100013f520000003d0000464f0000013d000000400100043d002200000001001d008e00260000002d00013f570000003d0000441d0000013d0000008e0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002602000029000000040220008c0000405b0000613d000000220300002900000025043000690000002602000029000040580000013d000013740400004100013f680000003d0000476f0000013d006600190000002d00013f6b0000003d0000441d0000013d000000660440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c0000405b0000613d00013f770000003d00004b8a0000013d000040570000013d0000134b0350009c00003fc60000c13d0000130904100197000000230140006b00013f7e0000003d0000464a0000013d0000405b0000613d000000400200043d0000000001000414000000040340008c00003fd30000c13d0000000102000039000000010500003100003fe10000013d00001372020000410000000000240435000000260200002900000000002a04350000001a02000029000000000028043500000000009704350000000000160435000000220100002900013f910000003d000046430000013d000000400100043d002500000001001d007300190000002d00013f960000003d0000441d0000013d000000730440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c00013fa10000003d0000464a0000013d0000405b0000613d00000026020000290000002503000029000040370000013d0000134b0350009c00003ff30000c13d0000130904100197000000230140006b0000405b0000613d000000400200043d0000000001000414000000040340008c000040000000c13d000000010200003900000001050000310000400e0000013d000013720200004100013fb40000003d000045960000013d000000400100043d002500000001001d007a00190000002d00013fb90000003d0000441d0000013d0000007a0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c0000405b0000613d00000026020000290000002503000029000040560000013d000000400300043d000013710500004100013fca0000003d0000444d0000013d000013170440019700013fcd0000003d000044e70000013d000000260650006c0000401e0000813d000000250650002900013fd20000003d000045260000013d00003fcd0000013d0000130003000041000013000510009c0000000001038019000013000520009c000000000203801900013fda0000003d0000460e0000013d0000130b011001c70000800902000039000000220300002900013fdf0000003d000044570000013d000113000010019d0000130005100197000000000105004b00003fee0000613d00013fe50000003d000044ac0000013d00003fea0000613d000000000600001900013fe90000003d000044210000013d00003fe70000413d000000000601004b00003fee0000613d00013fee0000003d0000440f0000013d000000000102004b00013ff10000003d0000464a0000013d0000405b0000c13d0000435d0000013d000000400300043d000013710500004100013ff70000003d0000444d0000013d000013170440019700013ffa0000003d000044e70000013d000000260650006c0000403f0000813d000000250650002900013fff0000003d000045260000013d00003ffa0000013d0000130003000041000013000510009c0000000001038019000013000520009c0000000002038019000140070000003d0000460e0000013d0000130b011001c700008009020000390000001f030000290001400c0000003d000044570000013d000113000010019d0000130005100197000000000105004b0000401b0000613d000140120000003d000044ac0000013d000040170000613d0000000006000019000140160000003d000044210000013d000040140000413d000000000601004b0000401b0000613d0001401b0000003d0000440f0000013d000000000102004b0000405b0000c13d0000435d0000013d000000260450006c000040220000a13d000140220000003d00004b1c0000013d00000000020204330000130901100197000140260000003d000049530000013d004900190000002d000140290000003d0000441d0000013d000000490440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000140340000003d0000464a0000013d0000405b0000613d000140370000003d00004b090000013d000000000432004900000019020000290001403b0000003d0000452b0000013d0001403d0000003d0000464a0000013d0000405b0000c13d000001560000013d000000260450006c000040430000a13d000140430000003d00004b1c0000013d00000000020204330000130901100197000140470000003d000049530000013d005000190000002d0001404a0000003d0000441d0000013d000000500440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c0000405b0000613d000140560000003d00004b090000013d000000000432004900000019020000290001405a0000003d0000452b0000013d000001560000613d0000000c010000290001405e0000003d00004a310000013d000040690000c13d000000400200043d0000006401200039000013810300004100000000003104350000004401200039000013820300004100000000003104350000002401200039000000240300003900000ac90000013d000000130200002900000000020204330000000023020434001800000003001d00000000030204330000002302000029001613090020019b00000012020000290000000002020433001a13090020019b0000000f020000290000000002020433001913090020019b002500000000001d002200000003001d001f00000003001d002600000000001d000000010210008a000000260320006b000041b70000813d000000260110006b00001b020000813d000140810000003d000049240000013d0000137002200197000000220300006b0000000004000019000040890000613d00000022342000b900000022534000fa000000000323004b000041ad0000c13d002500250020002e000041bf0000413d000027100240008c000041650000413d000027102340011a0000001f0230006b00001ccd0000413d000140920000003d000045e20000013d00001b020000813d001f001f00300071000140960000003d000049360000013d0000131707700197000013640870009c000040b60000c13d0001409b0000003d00004b510000013d0000130808000041000000000600001900000000060820190000130805500197000140a10000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000003030433001d13090030019b0000130a0330009c0000006d0000813d000027100340008a000027100330008c000042340000813d000140ae0000003d0000473f0000013d0000130901100197000140b10000003d000046a50000013d000040f70000c13d0000137807000041000140b50000003d000044870000013d000041180000013d0000134a0470009c000040fb0000c13d000140ba0000003d00004b4d0000013d0000130807000041000000000500001900000000050720190000130804400197000140c00000003d0000463f0000013d000013080440009c000000000605c019000000000406004b0000006d0000613d0000000002020433001d13090020019b0000130a0220009c0000006d0000813d000140ca0000003d000049d00000013d00001309011001970000001a06000029000000230560006b0000412b0000c13d0000137505000041000140d10000003d0000470e0000013d0035001d0000002d000140d40000003d0000441d0000013d000000350440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c000040e40000613d0000001b03000029000140e10000003d000045ec0000013d000001560000613d000000400100043d001b00000001001d00000001010000310000001f0210008c0000130805000041000000000200001900000000020520190000130803100197000140ec0000003d000047250000013d000013080330009c000140ef0000003d0000469d0000013d0000006d0000613d0000001b01000029000140f30000003d0000445d0000013d0000006d0000c13d000000000101004b000041650000c13d000041c30000013d0000137707000041000140fa0000003d000046e30000013d0000414f0000013d0000135f0470009c000041400000c13d000140ff0000003d00004b490000013d0000130808000041000000000600001900000000060820190000130805500197000141050000003d000047010000013d000013080550009c000000000706c019000000000507004b0000006d0000613d0000000004040433001d13090040019b0000130a0440009c0000006d0000813d000000400500043d001b00c40050003d000141110000003d000045890000013d000013090a100197000141140000003d000045b90000013d0000414c0000c13d0000137302000041000141180000003d000044c30000013d000000400100043d001700000001001d008f001d0000002d0001411d0000003d0000441d0000013d0000008f0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001d02000029000000040220008c000041650000613d00000017030000290000001b043000690000001d02000029000041620000013d00001374050000410000001b060000290001412f0000003d000044b70000013d006700190000002d000141320000003d0000441d0000013d000000670440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000041650000613d0000001d030000290000001b023000690000008404200039000041610000013d0000134b0470009c000041680000c13d0000130904100197000000230140006b000041650000613d000000400200043d0000000001000414000000040540008c000041900000c13d000000010200003900000001010000310000419d0000013d00001372020000410001414f0000003d000045ab0000013d000000400100043d001d00000001001d007b00190000002d000141540000003d0000441d0000013d0000007b0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000041650000613d0000001b020000290000001d0300002900000000043200490000001902000029000141640000003d0000452b0000013d000001560000613d000141670000003d000048520000013d0000407a0000013d000000400300043d00001371040000410001416c0000003d00004bef0000013d0001416e0000003d000045210000013d0000131704400197000141710000003d0000462a0000013d0000001d0650006c000041770000813d0000001b06500029000141760000003d000045260000013d000041710000013d0000001d0450006c0000417c0000a13d0000001d050000290000001b04500029000000000004043500000000020204330000130901100197000141800000003d000044430000013d005100190000002d000141830000003d0000441d0000013d000000510440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000041650000613d0001418f0000003d000049160000013d000041600000013d000013000510009c00001300060000410000000001068019000013000520009c0000000002068019000141970000003d0000460e0000013d0000130b011001c700008009020000390001419b0000003d000044570000013d000113000010019d0000130001100197000000000301004b000041aa0000613d000141a10000003d000044290000013d000041a60000613d0000000006000019000141a50000003d000044210000013d000041a30000413d0000001f01100190000041aa0000613d000141aa0000003d0000440f0000013d000000000102004b000041650000c13d0000435d0000013d000000400200043d0000006401200039000013830300004100000000003104350000004401200039000013840300004100000000003104350000002401200039000000210300003900000ac90000013d000000000101004b00001b020000613d000141bb0000003d000049750000013d0000137002200197000000250220002a000041bf0000413d000041c40000013d000000400200043d000000440120003900001387030000410000257e0000013d0000422e0000013d000027100220008c000041ea0000c13d0000001f0200006b000042e80000613d000141ca0000003d000046700000013d0000131705500197000013640650009c000041ee0000c13d000000000203043300000000340204340000130805000041000141d20000003d000048800000013d0000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d0000000003030433002613090030019b0000130a0330009c0000006d0000813d0000001f03000029000000010330008c000042340000c13d000141e20000003d0000467b0000013d0000130901100197000141e50000003d000046a50000013d000042380000c13d0000137807000041000141e90000003d000044870000013d000042590000013d000000400200043d00000044012000390000137f0300004100001cd00000013d0000134a0650009c0000423c0000c13d000000000203043300000000230204340000130804000041000141f50000003d000049aa0000013d0000130803300197000000000603004b0000000004008019000013080330009c000000000405c019000000000304004b0000006d0000613d0000000002020433002513090020019b0000130a0220009c0000006d0000813d000142020000003d000049f90000013d00001309011001970000001a05000029000000230450006b0000426c0000c13d0000137504000041000142090000003d000047f90000013d003600250000002d0001420c0000003d0000441d0000013d000000360440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002502000029000000040220008c0000421d0000613d000000260300002900000022043000690001421a0000003d000045900000013d000001560000613d000000400100043d002600000001001d00000001010000310000130803000041000142210000003d0000499b0000013d0000130804100197000000000504004b0000000003008019000013080440009c000142270000003d0000454b0000013d0000006d0000613d00000026010000290001422b0000003d0000445d0000013d0000006d0000c13d000000000101004b000042e80000c13d00000044012000390000137603000041000000000031043500000024012000390000001503000039000025810000013d000000400200043d00000044012000390000138603000041000015570000013d00001377070000410001423b0000003d000045ce0000013d0000428e0000013d0000135f0650009c0000427f0000c13d000000000203043300000000340204340000130805000041000142430000003d000048800000013d0000130804400197000000000704004b0000000005008019000013080440009c000000000506c019000000000405004b0000006d0000613d0000000003030433002613090030019b0000130a0330009c0000006d0000813d000000400400043d002500c40040003d000142520000003d000044cd0000013d0000130909100197000142550000003d0000499f0000013d0000428b0000c13d0000137302000041000142590000003d0000464f0000013d000000400100043d002300000001001d009000260000002d0001425e0000003d0000441d0000013d000000900440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000002602000029000000040220008c000042e80000613d000000230300002900000025043000690000002602000029000042e50000013d00001374040000410001426f0000003d0000476f0000013d006800190000002d000142720000003d0000441d0000013d000000680440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000042e80000613d0001427e0000003d00004b8a0000013d000042e40000013d0000134b0350009c000042a00000c13d0000130904100197000000230140006b000042e80000613d000000400200043d0000000001000414000000040340008c000042ad0000c13d00000001020000390000000105000031000042bb0000013d00001372020000410001428e0000003d000045960000013d000000400100043d002500000001001d007c00190000002d000142930000003d0000441d0000013d0000007c0440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000042e80000613d00000026020000290000002503000029000042e30000013d000000400300043d0000137105000041000142a40000003d0000444d0000013d0000131704400197000142a70000003d000044e70000013d000000260650006c000042cb0000813d0000002506500029000142ac0000003d000045260000013d000042a70000013d0000130003000041000013000510009c0000000001038019000013000520009c0000000002038019000142b40000003d0000460e0000013d0000130b011001c700008009020000390000001f03000029000142b90000003d000044570000013d000113000010019d0000130005100197000000000105004b000042c80000613d000142bf0000003d000044ac0000013d000042c40000613d0000000006000019000142c30000003d000044210000013d000042c10000413d000000000601004b000042c80000613d000142c80000003d0000440f0000013d000000000102004b000042e80000c13d0000435d0000013d000000260450006c000042cf0000a13d000142cf0000003d00004b1c0000013d00000000020204330000130901100197000142d30000003d000049bc0000013d002300000001001d005200190000002d000142d70000003d0000441d0000013d000000520440008a00000020044000c900001320020000414bfc43ed0000040f000000000101004b0000006d0000613d00000000010004140000001902000029000000040220008c000042e80000613d000142e30000003d00004b020000013d00000000043200490000001902000029000142e70000003d0000452b0000013d000001560000613d0000002101000029000000000101043300001317011001970000002402000029000000000202043300001317022001970000134b0220009c000043080000c13d0000134b0110009c0000006d0000613d0000000001000416000000200110006c0000430d0000413d0000000001000416000000200110006c000002a90000a13d0000000005000416000000200150006c00001ccd0000413d0000000101000039000000400300043d000000000200041400000011040000290000130904400197000000040640008c000043060000613d000000200150006c000043110000c13d000143060000003d00004bb90000013d00000001050000310000431f0000013d0000134b0110009c000002a90000c13d0000000001000416000000100110006c0000432d0000813d000000400200043d0000004401200039000013800300004100001e610000013d000000200550006a0000130001000041000013000620009c0000000002018019000013000630009c00000000030180190000004001300210000000c002200210000000000112019f0000130b011001c70001431d0000003d0000493b0000013d000113000020019d0000130005200197000000000205004b0000435b0000613d000143230000003d0000492b0000013d000043280000613d0000000006000019000143270000003d000044210000013d000043250000413d000000000602004b0000435b0000613d0001432c0000003d000047d50000013d0000435b0000013d0000000001000416000000100110006c000002a90000a13d0000000005000416000000100150006c00001ccd0000413d0000000101000039000000400300043d000000000200041400000011040000290000130904400197000000040640008c0000433e0000613d000000100150006c000043400000c13d0001433e0000003d00004bb90000013d00000001050000310000434e0000013d000000100550006a0000130001000041000013000620009c0000000002018019000013000630009c00000000030180190000004001300210000000c002200210000000000112019f0000130b011001c70001434c0000003d0000493b0000013d000113000020019d0000130005200197000000000205004b0000435b0000613d000143520000003d0000492b0000013d000043570000613d0000000006000019000143560000003d000044210000013d000043540000413d000000000602004b0000435b0000613d0001435b0000003d000047d50000013d000000000101004b000002a90000c13d000000400200043d0000004401200039000013850300004100001ec80000013d00000000243200d900000000143100d90000139a0430009c000043680000813d00000000211200a900000000123100d9000043c10000013d00000000421200a9000000010100008a000000000534004b000043c10000813d0000139b0130009c000000c0010000390000008001004039000000000513022f0000139b0130009c00000040010000390000008001004039000000200610008a0000139c0750009c000000000106801900000020065002700000139c0750009c0000000005068019000000100610008a0000139d0750009c000000000106801900000010065002700000139d0750009c0000000005068019000000080610008a000001000750008c000000000106801900000008055082700000000406500270000000100750008c00000000060540190000000207600270000000040860008c0000000007064019000000020800008a0000000009700049000000020770008c0000000009088019000000040710008a000000100550008c0000000001078019000000020510008a000000040660008c0000000001058019000000000119001a000000000414c1cf000001000510c089000000000552c22f000000000454c19f000000000212c1cf000000000313c1cf000000800530027000000000985400d900000080072002700000139e063001970000139f0a80009c000043a50000213d00000000ba6800a9000000800b900210000000000b7b019f000000000aba004b000043a90000a13d0000000009590019000000010880008a0000139e0a90009c0000439e0000413d0000139e0880019700000000983800a90000008004400210000000000447019f000000000484004900000000875400d90000139e022001970000139f0970009c000043b70000213d00000000a96700a9000000800a800210000000000a2a019f0000000009a9004b000043bb0000a13d0000000008580019000000010770008a0000139e0980009c000043b00000413d0000139e0570019700000000533500a90000008004400210000000000224019f0000000002320049000000000112022f000000000001042d000000000001042f0000130003000041000013000420009c0000000002038019000013000410009c000000000103801900000040011002100000006002200210000000000112019f00004bfe000104300000130004000041000013000520009c0000000002048019000013000510009c000000000104801900000040011002100000006002200210000000000112019f000000e002300210000000000121019f00004bfd0001042e00010000000000020000130003000041000013000410009c00000000010380190000004001100210000013000420009c000143df0000003d000049450000013d0000000002000414000013000420009c0000000002038019000000c002200210000000000112019f0000130b011001c700008010020000394bfc440a0000040f0000000102200190000043eb0000613d000000000101043b000000000001042d000000000100001900004bfe0001043000000000050100190000000000200439000000040130008c000043f40000a13d00000005014002700000000001010031000000040010044300001300010000410000000002000414000013000420009c0000000002018019000013000430009c00000000030180190000006001300210000000c002200210000000000112019f000013a0011001c700000000020500194bfc440a0000040f0000000102200190000044040000613d000000000101043b000000000001042d000000000001042f00004408002104210000000102000039000000000001042d0000000002000019000000000001042d0000440d002104230000000102000039000000000001042d0000000002000019000000000001042d0000000505500210000000000454034f00000000035300190000000301100210000000000503043300000000051501cf000000000515022f000000000404043b0000010001100089000000000414022f00000000011401cf000000000151019f0000000000130435000000010000013b000080020100003900000024030000390000000004000415000000010000013b00000005076002100000000008730019000000000774034f000000000707043b00000000007804350000000106600039000000000756004b000000010000013b0000003f03100039000000200400008a000000000343016f000000400400043d0000000003340019000000400030043f000000000314043600000003040003670000000505100272000000010000013b00000021040000290000000504400210000000220540035f000000000443001900000020060000290000000306600210000000000704043300000000076701cf000000000767022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000575019f0000000000540435000000010000013b0000004404300039000000000014043500000024013000390000001a04000029000000000041043500000084013000390000000000210435000000400100043d001700000001001d000000010000013b000000000053043500000004053000390000006006000039000000000065043500000000040404330000006405300039000000150700002900000000007504350000000054040434000000010000013b00000000050000194bfc44050000040f000000010220018f00030000000103550000006001100270000000010000013b0000000001010433000000000301004b0000000003000019000000010300c039000000000331004b000000010000013b000000a001100039000000000401043300000000043401cf000000000434022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000242019f0000000000210435000000010000013b0000000303300210000000000504043300000000053501cf000000000535022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000252019f0000000000240435000000010000013b0000000507700210000000000676034f00000000077400190000000305500210000000000807043300000000085801cf000000000858022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000585019f0000000000570435000000010000013b00000000007304350000001603000029000000000036043500000000001504350000000000240435000000010000013b0000002002400039000000000032043500000060024000390000000000120435000000400300043d000000000132004900000000011304360000008002400039000000400020043f00000000020304334bfc43d70000040f000000220200002900000000020204330000002604000029000000c0034000390000000000130435000000e0014000390000000000210435000000010000013b000000000065043500000000040404330000006405300039000000150700002900000000007504350000000054040434000000010000013b000000000707043b00000000007804350000000106600039000000000756004b000000010000013b0000003f01500039000000200300008a000000000131016f000000400300043d0000000001130019000000400010043f0000001f0150018f000000000353043600000003040003670000000505500272000000010000013b00000000005604350000001d0500002900000000005404350000001a0400002900000000004204350000001702000029000000000012043500000064016000390000000000310435000000400100043d001d00000001001d000000010000013b0000000000250435000000160200002900000000002b04350000000000a9043500000000001804350000000000370435000000a00100003900000000001604350000000000040435000000010000013b000000a4034000390000008405400039000000640640003900000044074000390000002408400039000000040a400039000000010000013b000000000402c0190000001f01100039000000200200008a000000000121016f0000001c02100029000000400020043f000000000104004b000000010000013b000000400400043d0000004002400039000000400020043f00000020024000390000000000b20435000000180300002900000000003404350000001e030000290000000003030433000000260330006b000000010000013b000000a40630003900000000004604350000000004050433000000c4053000390000000000750435000000e4053000390000000006040433002600000006001d0000000000650435002501040030003d0000000005000019000000010000013b0000000000020435000000400060043f000005020290003900000020030000290000000000320435000004e20290003900000021030000290000000000320435000004c20290003900000000007204350000000000160435000000400300043d00000000013900490000052204100039000000010000013b000000000032043500000160024000390000000000120435000000400300043d000000000132004900000000011304360000018002400039000000400020043f00000000020304334bfc43d70000040f000000200200002900000000020204330000002604000029000001a003400039000000010000013b0000800b01000039000000040300003900000000040004150000009f0440008a00000020044000c9000000010000013b0000000000240435000000160200002900000000002a0435000000000098043500000000001704350000000000b60435000000a00100003900000000001504350000000000030435000000010000013b0000006405300039000000150700002900000000007504350000000054040434000000010000013b0000002005500039000000000745001900000000070704330000000000760435000000010000013b000000000503001900000000060000194bfc000d0000040f000000000101004b000000010000013b00000040022000390000000002020433000000400300043d001c00640030003d00000044043000390000002405300039000000010000013b000000260100002900000005011002100000001b01100029000000000201043300000020022000390000000002020433000000010000013b0000000000530435000001c0034000390000000000130435000001e0014000390000000000210435000000400200043d000000000121004900000000011204360000020003400039000000400030043f00000000020204334bfc43d70000040f000000010000013b000000000302c0190000001f01100039000000200200008a000000000121016f0000002602100029000000400020043f000000000103004b000000010000013b00000000000204350000002605000029000004fe02500039000000400020043f0000055e03500039000000200400002900000000004304350000053e03500039000000210400002900000000004304350000051e035000390000001f0400002900000000004304350000000000120435000000400300043d00000000013500490000057e04100039000000010000013b00000026040000290000032003400039000000000023043500000300024000390000001d030000290000000000320435000002e0024000390000001f030000290000000000320435000002c00240003900000020030000290000000000320435000002a0024000390000001e0300002900000000003204350000002202000029000000010000013b0000000509800210000000000a940019000000000996034f000000000909043b00000000009a04350000000108800039000000000978004b000000010000013b000000200200008a000000240320017f000000400200043d0000000003320019000000400030043f000000260300002900000000033204360000002108000029000000000408004b000000220700035f000000010000013b000000a4045000390000008406500039000000640750003900000044085000390000002409500039000000040b500039000000010000013b0000002006000039000000250200002900000000050300194bfc000d0000040f000000000101004b000000010000013b0000000000240435000000260200002900000000002a04350000001a020000290000000000280435000000000097043500000000001604350000001f010000290000000000150435000000c001000039000000000013043500000025010000290000000000010435002600e40040003d000000010000013b0000001f02200039000000200300008a000000000232016f0000001c022000290000001703000029000000010000013b00000000002504350000001d0200002900000000002b04350000001a0200002900000000002904350000000000a8043500000000001704350000000000360435000000c00100003900000000001404350000001b010000290000000000010435001b00e40050003d000000010000013b000000400120003900000000010104330000001a0c0000290000002302c0006b000000010000013b000000000662034f000000000606043b00000000006704350000000105500039000000000645004b000000010000013b00000400024000390000000000120435000000400300043d000000000132004900000000011304360000042002400039000000400020043f00000000020304334bfc43d70000040f000000010000013b0000000000730435000000260700002900000000007604350000001a060000290000000000650435000000000014043500000025010000290000000000210435002600840030003d000000010000013b000000a0024000390000000000320435000000400200043d000000000121004900000000011204360000010003400039000000400030043f00000000020204334bfc43d70000040f000000010000013b000000400500043d0000004002500039000000400020043f0000001802000029000000000225043600000000003204350000001e060000290000000006060433000000260660006b000000010000013b000000170430006900000020060000390000001d0200002900000000050300194bfc000d0000040f000000000101004b000000010000013b00000000007604350000001a06000029000000000065043500000000001404350000001c010000290000000000210435001c00840030003d000000010000013b00000005054002100000000006530019000000000557034f000000000505043b00000000005604350000000104400039000000000584004b000000010000013b0000001c05000029000000000045043500000000001304350000000000b20435000000400100043d001c00000001001d000000010000013b00000000050300194bfc000d0000040f000000000101004b000000010000013b0000004002200210000000c001100210000000000121019f000000010000013b00000000002a04350000001a020000290000000000280435000000000097043500000000001604350000000000b50435000000c00100003900000000001304350000001c010000290000000000010435001c00e40040003d000000010000013b000000a40630003900000000004604350000000004050433000000c4053000390000000000750435000000e4053000390000000006040433001d00000006001d0000000000650435001c01040030003d0000000005000019000000010000013b000000a40630003900000000004604350000000004050433000000c4053000390000000000750435000000e4053000390000000006040433001d00000006001d0000000000650435001b01040030003d0000000005000019000000010000013b000000000603043300000064031000390000000000530435000000a4051000390000008403100039000000000406043300000000004304350000000007000019000000010000013b000000000604004b00000000060000190000000006074019000000010000013b0000000000150435000000c001000039000000000013043500000025010000290000000000010435002600e40040003d000000010000013b0012000d0000002d000f000e0000002d001300140000002d000c000b0000002d000000010000013b0000000000240435000000160200002900000000002a0435000000000098043500000000001704350000001f010000290000000000160435000000a00100003900000000001504350000000000030435000000010000013b000000000032043500000060024000390000000000120435000000400300043d000000000132004900000000011304360000008002400039000000400020043f00000000020304334bfc43d70000040f000000010000013b0000000000320435000000e0024000390000000000120435000000400300043d000000000132004900000000011304360000010002400039000000400020043f00000000020304334bfc43d70000040f000000010000013b000000400400043d0000004002400039000000400020043f00000020024000390000001f0300002900000000003204350000001803000029000000000034043500000000010104330000000035030434000000010000013b00000040022000390000000002020433000000400300043d002500640030003d00000044043000390000002405300039000000010000013b000000030aa00210000000000d0c0433000000000dad01cf000000000dad022f000000000b0b043b000001000aa00089000000000bab022f000000000aab01cf000000000ada019f0000000000ac0435000000010000013b000000210200006b0000002603000029000004c605300039000004a60430003900000486023000390000000009030019000004e603300039000000010000013b0000000502100210000000000329034f000000000303043b000000a002200039000000000032043500000001011000390000000002b1004b000000010000013b000000000402c0190000001f01100039000000200200008a000000000121016f0000001b02100029000000400020043f000000000104004b000000010000013b00000004063000390000001a08000029000000230780006b000000010000013b00000026040000290000044003400039000000000023043500000442024000390000000000120435000004620140003900000022020000290000000000210435000000400200043d000000000121004900000000011204360000048203400039002200000003001d000000400030043f00000000020204334bfc43d70000040f0000002402000029000000010000013b00000026040000290000044003400039000000000023043500000442024000390000000000120435000004620140003900000024020000290000000000210435000000400200043d000000000121004900000000011204360000048203400039002400000003001d000000400030043f00000000020204334bfc43d70000040f0000002202000029000000010000013b000000400300043d0000000004340019000000400040043f0000001f0520018f000000000423043600000002060003670000000507200272000000010000013b000000400300043d001700440030003d0000002402300039001c00000003001d0000000403300039000000010000013b000000200aa0003900000000020a0433000000000e6200190000003f02e00039000000000512004b00000000050000190000000005084019000000010000013b00000000007304350000001d0700002900000000007604350000001a06000029000000000065043500000000001404350000001b010000290000000000210435001b00840030003d000000010000013b0000002603300029000000000003043500000026022000290000000002020433000000010000013b000000000779001900000000000704350000006007500039000000000087043500000000066504360000002004400039000000220440035f000000000404043b0000000000460435000000010000013b00000000026100490000003f0b20008c000000000b000019000000000b082019000000010000013b000000000705004b00000000070000190000000007084019000000010000013b0000002602100069000000030110021000000100011000890000000043020434002600000004001d000000000313022f00000000011301cf0000000000120435000000010000013b0000001b06000029000000000056043500000000001404350000000000320435000000400100043d001b00000001001d000000010000013b000000200100008a000000240110017f000000400010043f0000002601000029000000800010043f00000000010b004b000000010000013b4bfc43ed0000040f0000002604000029000003c0024000390000001f030000290000000000320435000003a00240003900000020030000290000000000320435000000010000013b000000000403004b00000000040000190000000004054019000000010000013b0000001c0100002900000000020104330000001e010000294bfc43d70000040f00000020020000290000000002020433002000000001001d00000021010000294bfc43d70000040f000000c9020000390000002003000029000000000032041b000000ca02000039000000000012041b000000010000013b000000400100043d0000004002100039000000400020043f000000200210003900000000000204350000000000010435000000010000013b00000040022000390000000002020433000000400300043d001b00640030003d00000044043000390000002405300039000000010000013b000000000042043500000060023000390000000005010433000000000052043500000080063000390000000002000019000000010000013b00000020099000390000000000dc04350000000000b90435000000010aa000390000004006600039000000010000013b0000000509900210000000000797034f00000000099600190000000308800210000000000b090433000000000b8b01cf000000000b8b022f000000000707043b0000010008800089000000000787022f00000000078701cf0000000007b7019f0000000000790435000000010000013b0000022003400039000000000023043500000340024000390000000000120435000000400300043d000000000132004900000000011304360000036002400039000000400020043f00000000020304334bfc43d70000040f00000017020000290000000002020433000000010000013b00000026050000290000000000450435000000250400002900000000004304350000001a0300002900000000003204350000002202000029000000000012043500000064015000390000001f020000290000000000210435000000400100043d002500000001001d000000010000013b000000400200043d0000000101000039000800000001001d00000000031204360000008001200039000000400010043f00000060012000390000000000010435001e00000002001d0000004001200039001b00000003001d00000000001304350000000000010435000000010000013b00000000002504350000001d0200002900000000002b04350000001a0200002900000000002904350000000000a8043500000000001704350000000000360435000000c00100003900000000001404350000001c010000290000000000010435001c00e40050003d000000010000013b000000400340003900000000002304350000000002040433000000260400002900000000002404350000000002050433000000200400002900000000002404350000000002030433000000000202004b0000000002000019000000010200c0390000000000210435000000010000013b000000000203043300000000340204340000003f0540008c000000010000013b0000004004500039000000000034043500000000030504330000001e05000029000000000035043500000000030604330000001b0500002900000000003504350000000003040433000000000303004b0000000003000019000000010300c0390000000000320435000000010000013b0000000000240435000000250200002900000000002a04350000001a020000290000000000280435000000000097043500000000001604350000000000b50435000000c00100003900000000001304350000001c010000290000000000010435002500e40040003d000000010000013b0000000002020433002200000002001d000000160200002900000000020204330000000032020434002000000003001d0000000023020434001f00000003001d0000000002020433002100000001001d00000000120204344bfc43d70000040f0000001f02000029000000010000013b0000000505500210000000000454034f00000000035300190000000302200210000000000503043300000000052501cf000000000525022f000000000404043b0000010002200089000000000424022f00000000022401cf000000000252019f0000000000230435000000010000013b0000000505500210000000000651034f00000000055900190000000304400210000000000705043300000000074701cf000000000747022f000000000606043b0000010004400089000000000646022f00000000044601cf000000000474019f0000000000450435000000010000013b0000016101000039002600000001001d000000000101041a000000400200043d000000200320003900000025040000290000000000430435000000010000013b0000002605000029000000000045043500000000001304350000001f010000290000000000120435000000400100043d002600000001001d000000010000013b000000400100043d0000004002100039000000400020043f0000002002100039000000220300002900000000003204350000000000010435000000010000013b0000000000560435000000260500002900000000005c043500000000001a04350000000000b9043500000000002804350000000000370435000000c001000039000000000014043500000025010000290000000000010435002600e40060003d000000010000013b00000005054002100000000006530019000000220550035f000000000505043b00000000005604350000000104400039000000210540006c000000010000013b000000240330017f000000400200043d0000000003230019000000400030043f00000026030000290000000003320436000000210400006b000000010000013b000000030200036700000001010000310000001f0310018f0000000504100272000000010000013b0000001c050000290000000000450435000000220400002900000000004304350000001a0300002900000000003204350000001702000029000000000012043500000064015000390000000000b10435000000400100043d002200000001001d000000010000013b0000001c050000290000000000450435000000250400002900000000004304350000001a0300002900000000003204350000001702000029000000000012043500000064015000390000000000b10435000000400100043d002500000001001d000000010000013b0000001c0500002900000000004504350000001f0400002900000000004304350000001a0300002900000000003204350000001702000029000000000012043500000064015000390000000000b10435000000400100043d001f00000001001d000000010000013b0000001e0100002900000000010104330000002602000029002600010020003d000000010000013b0000000001010433000000000101043300000000030404330000000035030434000000010000013b000000a40730003900000000005704350000000005060433000000c4063000390000000000860435000000e4063000390000000007050433002600000007001d0000000000760435002501040030003d0000000006000019000000010000013b0000006006700039000000000606043300000040077000390000000007070433002000000007001d000000010000013b00000380034000390000000000230435000003e00240003900000000001204350000002301000029000000010000013b0000022003400039000000000023043500000340024000390000000000120435000000400300043d000000000132004900000000011304360000036002400039000000400020043f00000000020304334bfc43d70000040f000000010000013b0000003f0640008c00000000060000190000000006052019000000010000013b0000001f0250008c00000000020000190000000002012019000000010000013b000000a40630003900000000004604350000000004050433000000c4053000390000000000750435000000e4053000390000000006040433002500000006001d0000000000650435001c01040030003d0000000005000019000000010000013b000000a40630003900000000004604350000000004050433000000c4053000390000000000750435000000e4053000390000000006040433001f00000006001d0000000000650435001c01040030003d0000000005000019000000010000013b000000a40630003900000000004604350000000004050433000000c4053000390000000000750435000000e4053000390000000006040433002200000006001d0000000000650435001c01040030003d0000000005000019000000010000013b0000000002038019000000c002200210000000000121019f000000010000013b000000200100008a000000240110017f000000400010043f0000002601000029000000800010043f000000010000013b0000000000020435000000400100043d0000002002100039000000400020043f0000000002010019000000010000013b00000000001004350000006501000039000000200010043f00000040020000390000000001000019000000010000013b0000000502500210000000400700043d00000000027200190000002002200039000000000872004b000000010000013b000000400080043f000000000057043500000006085002100000000008860019000000000881004b000000010000013b0000000508500210000000400700043d00000000087800190000002008800039000000000978004b000000010000013b00000000065100190000000007140019000000000707043300000000007604350000002001100039000000010000013b00000000036200190000002002200039000000000412001900000000040404330000000000430435000000010000013b000000400020043f000000000057043500000006025002100000000002260019000000000221004b000000010000013b00000000029a0019000000000ba80019000000000b0b04330000000000b20435000000200aa00039000000010000013b00000000085700190000002007700039000000000967001900000000090904330000000000980435000000010000013b00000020099000390000000000c204350000000000b90435000000010aa000390000004006600039000000010000013b000002800340003900000000002304350000026002400039000000210300002900000000003204350000002402000029000000010000013b000000a002200039000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000320435000000010000013b0000001c06000029000000000056043500000000001404350000000000320435000000400100043d001c00000001001d000000010000013b000000400400043d002600000004001d00000040034000390000000000230435000000010000013b0000001d020000290000001f02200039000000200300008a000000000232016f0000001b022000290000001703000029000000010000013b000000400100043d0000004002100039000000400020043f000000200210003900000000003204350000000000010435000000010000013b000000260100002900000005011002100000001c01100029000000000201043300000020022000390000000002020433000000010000013b0000003f02500039000000200300008a000000000232016f000000400300043d0000000002230019000000400020043f0000001f0250018f000000000353043600000003040003670000000505500272000000010000013b0000000001010433000000000101043300000000060504330000000067060434000000010000013b0000800902000039000000000305001900000000050000194bfc44050000040f000000000301034f000000010120018f000300000003035500000000020300190000006002200270000000010000013b00000000020380190000006002200210000000000112019f000000010000013b0000000000730435000000250700002900000000007604350000001a06000029000000000065043500000000001404350000001c010000290000000000210435002500840030003d000000010000013b0000004404300039000000000014043500000024013000390000001a04000029000000000041043500000084013000390000000000210435000000400100043d002200000001001d000000010000013b000000000c02004b000000000c000019000000000c084019000000010000013b0000000001020433000000000015043500000000010204330000000002000019000000010000013b0000002402100069000000030110021000000100011000890000000043020434002400000004001d000000000313022f00000000011301cf0000000000120435000000010000013b00000026020000290000001f02200039000000200300008a000000000232016f0000002502200029000000010000013b00000005012002100000001c01100029000000000101043300000020021000390000000002020433000000010000013b0000000000840435000000260800002900000000008704350000000000160435000000000025043500000025010000290000000000310435002600840040003d000000010000013b00210000000b001d00200000000a001d002200000009035300230000000f001d000000010000013b000000000503001900000000060000194bfc00340000040f000000000101004b000000010000013b0000001a04000029000000000046043500000040033000390000000003030433000000000403004b0000000004000019000000010400c039000000000443004b000000010000013b000000000a96004b000000000700a019000000000696013f000000010000013b0000001f0210008c00000000020000190000000002032019000000010000013b000000400120003900000000010104330000001a0b0000290000002302b0006b000000010000013b000000fc07700039000000ff0770018f001f00000007001d0000001b0770008a000000020770008c000000010000013b0000001f0530008c00000000050000190000000005042019000000010000013b0000002604000029000001400340003900000000002304350000012002400039000000010000013b0000004404300039000000000014043500000024013000390000001904000029000000000041043500000084013000390000000000210435000000400100043d000000010000013b0000004404300039000000000014043500000024013000390000001a04000029000000000041043500000084013000390000000000210435000000400100043d000000010000013b000000000dc2004b000000000d000019000000000d0820190000000002c2013f000000010000013b000000400400043d001700440040003d0000002402400039001c00000004001d0000000404400039000000010000013b000000400400043d001700440040003d0000002402400039001b00000004001d0000000404400039000000010000013b0000000002020433002400000002001d00000000120104344bfc43d70000040f0000002602000029000000010000013b000000400100043d0000004002100039000000400020043f00000020021000390000006003000039000000010000013b00000000007504350000002602000029000000400520003900000040064000390000000006060433000000000065043500000060054000390000000005050433000000010000013b000000400200003900000000010000194bfc43d70000040f000000000101041a000000010000013b00000000001004350000012f01000039000000200010043f000000400200003900000000010000194bfc43d70000040f0000001f02000029000000000021041b000000010000013b000000400300043d002200440030003d0000002402300039002600000003001d0000000403300039000000010000013b0000000000670435000000400600003900000000006404350000000000120435000000010000013b000000200aa000390000000000ed04350000000000ca0435000000010bb000390000004007700039000000010000013b000000400090043f0000000009780436000000200aa00039000000000b7a0019000000260bb0006c000000010000013b000000400500043d00000020065000390000000008860019000000400080043f000000220770035f00000000004504350000001f0840018f0000000509400272000000010000013b0000000004240019000000000004043500000000023200190000000002020433000000010000013b000000400050043f00000000053204360000000006340019000000000116004b000000010000013b000000400600043d002500c40060003d000000a404600039000000840760003900000064086000390000004409600039000000240a600039000000040c600039000000010000013b000000000101043300000020011000390000000001010433000000000101004b000000010000013b0000000001010433001e00000001001d0000000021010434001c00000002001d000000000201004b000000010000013b000003e8431000c900000000411300d9000003e80110008c000000010000013b000000050ba00210000000000cb60019000000000bb7034f000000000b0b043b0000000000bc0435000000010aa00039000000000b9a004b000000010000013b00000000001c04350000000000ba043500000000002904350000000000380435000000a00100003900000000001704350000000000040435000000010000013b000000260300002900000024043000690000002006000039000000220200002900000000050300194bfc00340000040f000000000101004b000000010000013b000000000503004b00000000050000190000000005064019000000010000013b000000260500002900000025035000690000004404300039000000000305001900000000060000194bfc000d0000040f000000000101004b000000010000013b000000000103801900000040011002100000004002200039000000010000013b000027103230011a0000002504200069000000250340006c00000000030000190000000103002039000000000303004b000000000400c019000000010000013b0000001d432000b90000001d543000fa000000000224004b000000010000013b0000000502100210000000000324034f000000000303043b000000a00220003900000000003204350000000101100039000000000251004b000000010000013b000000220300002900000026043000690000002006000039000000240200002900000000050300194bfc00340000040f000000000101004b000000010000013b000027104240011a0000000005230049000000000435004b00000000040000190000000104002039000000000404004b000000000500c019000000010000013b000000000203043300000000230204340000001f0430008c000000010000013b000000400400043d0000004002400039000000400020043f0000002002400039000000000032043500000018050000290000000000540435000000010000013b0000000002020433000000200220003900000000020204330000000001010433000000200110003900000000010104330000000001210019000000010000013b0000000000120435000000400100043d0000000002120049000000010000013b000000000085043500000040022000390000000002020433000000000302004b0000000003000019000000010300c039000000000332004b000000010000013b000000000982004b000000000600a019000000000282013f000000010000013b000000050ed00210000000000fe90019000000000eeb034f000000000e0e043b0000000000ef0435000000010dd00039000000000ecd004b000000010000013b000000000712004b00000000070000190000000007064019000000010000013b000000000763004b000000000400a019000000000363013f000000010000013b000000000513004b00000000050000190000000005044019000000010000013b0000003f0530008c00000000050000190000000005042019000000010000013b0000001f0310008c00000000030000190000000003022019000000010000013b000100000003001f00030000000103550000000001020019000000000001042d000000400500043d0000004004500039000000400040043f0000002004500039000000000034043500000000006504350000000067060434000000010000013b0000000003340019000000200430003900000000022400490000002401100039000000000021043500000026010000290000000001010433000000010000013b000000000816004b00000000080000190000000008074019000000010000013b00000000010104330000000021010434002200000002001d0000000012010434002600000002001d00000000010104330000001702000029000000010000013b00000000010104330000000012010434001800000002001d0000000001010433001d00000001001d002500000000001d002600000000001d000000010000013b0000004000a0043f0000001a09000029000000000079043500000006097002100000000009980019000000000994004b000000010000013b000000260b0000290000000009b7004b00000000090000190000000009084019000000010000013b0000000503200210000000000439034f000000000404043b000000a00330003900000000004304350000000102200039000000010000013b00000026020000290000001f02200039000000200300008a000000000232016f00000025022000290000002303000029000000010000013b00000026020000290000001f02200039000000200300008a000000000232016f00000025022000290000002203000029000000010000013b0000002602000029000000c003200039000000400030043f000000006304043400000000053204360000000003060433000000010000013b000000000c7300490000003f0dc0008c000000000d000019000000000d092019000000010000013b000000260500002900000025045000290000000000040435000000010000013b0000002605000029000000a002500039000000400020043f000000003204043400000000052504360000000002030433000000010000013b00000026050000290000000000450435000000250400002900000000004304350000001a030000290000000000320435000000010000013b000000400cb000390000004000c0043f00000000dc060434000000010000013b00000000030000194bfc43cc0000040f00000040034000390000000003030433000000400400043d002500640040003d00000044054000390000002406400039000000010000013b000000000076043500000000050504330000006406300039000000150800002900000000008604350000000065050434000000010000013b00000000007604350000001a06000029000000000065043500000000001404350000001c010000290000000000210435000000010000013b000000000206043300000000450204340000003f0650008c000000010000013b000000000206043300000000240204340000001f0540008c000000010000013b000000000206043300000000350204340000003f0650008c000000010000013b00000084022000394bfc43c30000040f00000001020000390000002006000039000000200530008a000000010000013b0000000000de04350000000009c90436000000010bb000390000004008800039000000010000013b000000000cb8004b000000000900a0190000000008b8013f000000010000013b0000000000140435002500000004001d00000004014000390000000000210435000000400100043d002600000001001d000000010000013b0000000502700210000000400400043d00000000024200190000002002200039002500000004001d000000000542004b000000010000013b000000000202043300000000030204330000001b0200002900000000020204330000000024020434000000000334013f000000010000013b0000000505700210000000400200043d00000000052500190000002005500039002500000002001d000000000825004b000000010000013b000000400100043d0000004002100039000000400020043f0000002002100039000000010000013b0000000000120435000000400300043d00000000013200490000000001130436000000010000013b000000250300002900000026023000690000008404200039000000010000013b0000002606000029000000000016043500000000002504350000000000340435000000400100043d002600000001001d000000010000013b0000001b030000290000000003030433000000000303043300000000020204330000000002020433000000000232013f000000010000013b0000000509700210000000400b00043d0000000009b90019000000200a900039001a0000000b001d0000000009ba004b000000010000013b0000003f02600039000000200300008a000000000232016f000000400700043d0000000002270019000000000972004b000000010000013b000000400800043d00000000098900190000002009900039000000000a89004b000000010000013b00000000008604350000002008700039000000220880035f000000000808043b000000010000013b0000000000ef0435000000000ada0436000000010cc000390000004009900039000000010000013b000000000102001900000000020400190000000004000019000000000503001900000000060000194bfc000d0000040f000000010000013b0000004006500039000000400060043f000000220740035f000000000707043b000000010000013b0000003f07600039000000200300008a000000000937016f000000400700043d0000000009970019000000000a79004b000000010000013b4bfc43ed0000040f000000c902000039000000000202041a002000000002001d000000ca02000039000000000202041a001f00000002001d002100000001001d000000010000013b0000000000260435000004be029000390000000000120435000000400300043d00000000013200490000000001130436000004de02900039002200000002001d000000400020043f00000000020304334bfc43d70000040f0000002202000029000000010000013b0000000000260435000004be029000390000000000120435000000400300043d00000000013200490000000001130436000004de02900039002400000002001d000000400020043f00000000020304334bfc43d70000040f0000002402000029000000010000013b00000000004304350000000404300039000000600600003900000000006404350000000004050433000000010000013b00000000002904350000000000a8043500000000001704350000000000360435000000c0010000390000000000140435000000010000013b00004bfc0000043200004bfd0001042e00004bfe00010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffff8da5cb5b00000000000000000000000000000000000000000000000000000000d6ca6ab70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d6ca6ab700000000000000000000000000000000000000000000000000000000e2864fe300000000000000000000000000000000000000000000000000000000e99a3f8000000000000000000000000000000000000000000000000000000000eae3ad6f00000000000000000000000000000000000000000000000000000000f2fde38b8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000001000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0ffffffffffffffffffffffff000000000000000000000000000000000000000064647265737300000000000000000000000000000000000000000000000000004f776e61626c653a206e6577206f776e657220697320746865207a65726f206108c379a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffff0000000000000000000000000000000000000000000000000001000000000000a8af9093caa9beb61d20432227c66258ceef926f21879b80f3adf22a4d19f131000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff0000000000000000000000000000000000000000000000010000000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffde0000000000000000000000000000000000000000000000000ffffffffffffffc0000000000000000000000000000000000000000000000000ffffffffffffff7f000000000000000000000000000000000000000000000000fffffffffffffee0796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d95539132452a0dc408cb0d27ffc3b3caff933a5208040a53a9dbecd8d89cad2c0d40e00cdb6f72e915676cfc289da13bc4ece054fd17b1df6d77ffc4a60510718c236b08477ed43b8020849b755512278536c3766a3b4ab547519949a75f483372493f8d1806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b839a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f19010000000000000000000000000000000000000000000000000000000000001626ba7e000000000000000000000000000000000000000000000000000000006174696f6e206572726f72000000000000000000000000000000000000000000636f6e7472616374206f72646572207369676e6174757265207665726966696345434453413a20696e76616c6964207369676e6174757265206c656e677468007fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1756500000000000000000000000000000000000000000000000000000000000045434453413a20696e76616c6964207369676e6174757265202773272076616c1f0000000000000000000000000000000000000000000000000000000000000019457468657265756d205369676e6564204d6573736167653a0a33320000000045434453413a20696e76616c6964207369676e6174757265202776272076616c6f720000000000000000000000000000000000000000000000000000000000006f72646572207369676e617475726520766572696669636174696f6e206572726e6f206d616b657200000000000000000000000000000000000000000000000045434453413a20696e76616c6964207369676e617475726500000000000000006c656400000000000000000000000000000000000000000000000000000000006c6566744f726465722e74616b657220766572696669636174696f6e20666169696c65640000000000000000000000000000000000000000000000000000000072696768744f726465722e74616b657220766572696669636174696f6e2066616e6f742061206d616b6572000000000000000000000000000000000000000000302073616c742063616e27742062652075736564000000000000000000000000fffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff4c23426600000000000000000000000000000000000000000000000000000000e8d9861dbc9c663ed3accd261bbe2fe01e0d3d9e5f51fa38523b265c7757a93a70bba4f904a93ba5c1af3a1bb602bc9c058551dbe963dfe0b6cb5bc11c5fea9effffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000008da5cb5b00000000000000000000000000000000000000000000000000000000b0e21e8a00000000000000000000000000000000000000000000000000000000b39deb4600000000000000000000000000000000000000000000000000000000b74c8e9a00000000000000000000000000000000000000000000000000000000bc158c2da4b009cc442411b602eaf94bc0579b6abdb8fd90b4ef5b9426e270038906bd03d2bf91075f105d0fd80328da28e20ebdad1c1261839711183bc29a44cbe6c72f30c642f1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030c642f1000000000000000000000000000000000000000000000000000000003be899220000000000000000000000000000000000000000000000000000000067d49a3b000000000000000000000000000000000000000000000000000000006d8f069400000000000000000000000000000000000000000000000000000000715018a68ae85d8400000000000000000000000000000000000000000000000000000000aaaebeba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffe04b5aced933c0c9a88aeac3f0b3b72c5aaf75df8ebaf53225773248c4c31535934f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572000000000000000000000000000000000000000000000000000000000c53c51c000000000000000000000000000000000000000000000000000000000d5f7d35000000000000000000000000000000000000000000000000000000001372a6250000000000000000000000000000000000000000000000000000000020158c44000000000000000000000000000000000000000000000000000000002d0335abffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff45786368616e6765000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000045786368616e67654d6574615632000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000036c25de3e541d5d970f66e4210d728721220fff5c077cc6cd008b3a0c62adab74532fa16f071d6234e30e1a1e69b9806f04095edf37a1ca7a25c8d6af7861cc030a684095c937b5aa064dcf94f9903a7d808e3efb22d8389dbd43080ad4ed3d5973bb640000000000000000000000000000000000000000000000000000000004b5822151ea34b7c8d9e37c3e466bcecb631efe6a9f26a4a4054110a93dd316f4f726465722073746172742076616c69646174696f6e206661696c65640000004f7264657220656e642076616c69646174696f6e206661696c656400000000006d616b6572206973206e6f742074782073656e6465720000000000000000000073ad2146000000000000000000000000000000000000000000000000000000006d3f7cb00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000006e6f7420666f756e64204941737365744d61746368657200000000000000000023d235ef000000000000000000000000000000000000000000000000000000004ade54ca00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffa00000000000000000000000000000000000000001000000000000000000000000556e6b6e6f776e204f726465722064617461207479706500000000000000000066696c6c52696768743a20756e61626c6520746f2066696c6c00000000000000726f756e64696e67206572726f72000000000000000000000000000000000000956cd63ee4cdcd81fda5f0ec7c6c36dceda99e1b412f4a650a5d26055dc3c4500000000000000000000000000000000000000000ffffffffffffffffffffffff54bc0cf1000000000000000000000000000000000000000000000000000000009c1c2ee900000000000000000000000000000000000000000000000000000000f242432a00000000000000000000000000000000000000000000000000000000776062c300000000000000000000000000000000000000000000000000000000a9059cbb000000000000000000000000000000000000000000000000000000006572633230207472616e73666572206661696c65640000000000000000000000f709b9060000000000000000000000000000000000000000000000000000000042842e0e000000000000000000000000000000000000000000000000000000001cdfaa4000000000000000000000000000000000000000000000000000000000d8f960c100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff60000000000000000000000000000000000000000000000000ffffffffffffff409ca7dc7a00000000000000000000000000000000000000000000000000000000526f79616c746965732061726520746f6f206869676820283e3530252900000053756d207061796f75747320427073206e6f7420657175616c203130302500006e6f7420656e6f7567682065746800000000000000000000000000000000000073666572000000000000000000000000000000000000000000000000000000007472616e736665725061796f7574733a206e6f7468696e6720746f207472616e7700000000000000000000000000000000000000000000000000000000000000536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7472616e73666572206661696c656400000000000000000000000000000000006572633732312076616c7565206572726f720000000000000000000000000000536166654d6174683a206164646974696f6e206f766572666c6f7700000000006f726967696e2066656520697320746f6f2062696700000000000000000000006e6f7468696e6720746f2066696c6c000000000000000000000000000000000066696c6c4c6566743a20756e61626c6520746f2066696c6c00000000000000006469766973696f6e206279207a65726f00000000000000000000000000000000536166654d6174683a207375627472616374696f6e206f766572666c6f77000061737365747320646f6e2774206d617463680000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff8000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff57726f6e672066756e6374696f6e5369676e6174757265000000000000000000726529000000000000000000000000000000000000000000000000000000000064726573732066726f6d2c62797465732066756e6374696f6e5369676e6174754d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616468000000000000000000000000000000000000000000000000000000000000005369676e657220616e64207369676e617475726520646f206e6f74206d6174635845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b46756e6374696f6e2063616c6c206e6f74207375636365737366756c00000000496e76616c6964207369676e61747572650000000000000000000000000000000000000200000000000000000000000000000040000001000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000fffffffffffffffffffffffffffffffe0200000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097c15ce2f27d6a0b37e7c1887c51e2f45cd21a5fe5796741a07cb62ec742793b
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.