Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Multichain Info
No addresses found
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
InitBipMiscImprovements
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 100 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.6; pragma experimental ABIEncoderV2; import "../../C.sol"; import "../../tokens/Fertilizer/Fertilizer.sol"; /** * @author deadmanwalking * @title InitBipMiscImprovements updates the Fertilizer implementation * to use a decentralized uri **/ contract InitBipMiscImprovements { function init() external { // deploy new Fertilizer implementation Fertilizer fertilizer = new Fertilizer(); // get the address of the new Fertilizer implementation address fertilizerImplementation = address(fertilizer); // upgrade to new Fertilizer implementation C.fertilizerAdmin().upgrade( C.fertilizerAddress(), fertilizerImplementation ); } }
// 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 "./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 "./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; /** * @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 "./IERC20Upgradeable.sol"; import "../../math/SafeMathUpgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using SafeMathUpgradeable for uint256; using AddressUpgradeable for address; function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// 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; import "../proxy/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal initializer { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal initializer { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } uint256[49] private __gap; }
// 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; /** * @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; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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.7.6; pragma experimental ABIEncoderV2; import "./interfaces/IBean.sol"; import "./interfaces/ICurve.sol"; import "./interfaces/IFertilizer.sol"; import "./interfaces/IProxyAdmin.sol"; import "./libraries/Decimal.sol"; /** * @title C * @author Publius * @notice Contains constants used throughout Beanstalk. */ library C { using Decimal for Decimal.D256; using SafeMath for uint256; //////////////////// Globals //////////////////// uint256 internal constant PRECISION = 1e18; uint256 private constant CHAIN_ID = 1; bytes constant BYTES_ZERO = new bytes(0); /// @dev The block time for the chain in seconds. uint256 internal constant BLOCK_LENGTH_SECONDS = 12; //////////////////// Season //////////////////// /// @dev The length of a Season meaured in seconds. uint256 private constant CURRENT_SEASON_PERIOD = 3600; // 1 hour uint256 internal constant SOP_PRECISION = 1e24; //////////////////// Silo //////////////////// uint256 internal constant SEEDS_PER_BEAN = 2; uint256 internal constant STALK_PER_BEAN = 10000; uint256 private constant ROOTS_BASE = 1e12; //////////////////// Exploit Migration //////////////////// uint256 private constant UNRIPE_LP_PER_DOLLAR = 1884592; // 145_113_507_403_282 / 77_000_000 uint256 private constant ADD_LP_RATIO = 866616; uint256 private constant INITIAL_HAIRCUT = 185564685220298701; //////////////////// Contracts //////////////////// address internal constant BEAN = 0xBEA0000029AD1c77D3d5D23Ba2D8893dB9d1Efab; address internal constant CURVE_BEAN_METAPOOL = 0xc9C32cd16Bf7eFB85Ff14e0c8603cc90F6F2eE49; address internal constant UNRIPE_BEAN = 0x1BEA0050E63e05FBb5D8BA2f10cf5800B6224449; address internal constant UNRIPE_LP = 0x1BEA3CcD22F4EBd3d37d731BA31Eeca95713716D; address private constant CURVE_3_POOL = 0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7; address private constant THREE_CRV = 0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490; address private constant FERTILIZER = 0x402c84De2Ce49aF88f5e2eF3710ff89bFED36cB6; address private constant FERTILIZER_ADMIN = 0xfECB01359263C12Aa9eD838F878A596F0064aa6e; address private constant TRI_CRYPTO = 0xc4AD29ba4B3c580e6D59105FFf484999997675Ff; address private constant TRI_CRYPTO_POOL = 0xD51a44d3FaE010294C616388b506AcdA1bfAAE46; address private constant CURVE_ZAP = 0xA79828DF1850E8a3A3064576f380D90aECDD3359; address private constant UNRIPE_CURVE_BEAN_LUSD_POOL = 0xD652c40fBb3f06d6B58Cb9aa9CFF063eE63d465D; address private constant UNRIPE_CURVE_BEAN_METAPOOL = 0x3a70DfA7d2262988064A2D051dd47521E43c9BdD; address internal constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address internal constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; address internal constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address internal constant WSTETH = 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0; // Use external contract for block.basefee as to avoid upgrading existing contracts to solidity v8 address private constant BASE_FEE_CONTRACT = 0x84292919cB64b590C0131550483707E43Ef223aC; //////////////////// Well //////////////////// uint256 internal constant WELL_MINIMUM_BEAN_BALANCE = 1000_000_000; // 1,000 Beans address internal constant BEAN_ETH_WELL = 0xBEA0e11282e2bB5893bEcE110cF199501e872bAd; address internal constant BEAN_WSTETH_WELL = 0xBeA0000113B0d182f4064C86B71c315389E4715D; // The index of the Bean and Weth token addresses in all BEAN/ETH Wells. uint256 internal constant BEAN_INDEX = 0; uint256 internal constant ETH_INDEX = 1; function getSeasonPeriod() internal pure returns (uint256) { return CURRENT_SEASON_PERIOD; } function getBlockLengthSeconds() internal pure returns (uint256) { return BLOCK_LENGTH_SECONDS; } function getChainId() internal pure returns (uint256) { return CHAIN_ID; } function getSeedsPerBean() internal pure returns (uint256) { return SEEDS_PER_BEAN; } function getStalkPerBean() internal pure returns (uint256) { return STALK_PER_BEAN; } function getRootsBase() internal pure returns (uint256) { return ROOTS_BASE; } /** * @dev The pre-exploit BEAN:3CRV Curve metapool address. */ function unripeLPPool1() internal pure returns (address) { return UNRIPE_CURVE_BEAN_METAPOOL; } /** * @dev The pre-exploit BEAN:LUSD Curve plain pool address. */ function unripeLPPool2() internal pure returns (address) { return UNRIPE_CURVE_BEAN_LUSD_POOL; } function unripeBean() internal pure returns (IERC20) { return IERC20(UNRIPE_BEAN); } function unripeLP() internal pure returns (IERC20) { return IERC20(UNRIPE_LP); } function bean() internal pure returns (IBean) { return IBean(BEAN); } function usdc() internal pure returns (IERC20) { return IERC20(USDC); } function curveMetapool() internal pure returns (ICurvePool) { return ICurvePool(CURVE_BEAN_METAPOOL); } function curve3Pool() internal pure returns (I3Curve) { return I3Curve(CURVE_3_POOL); } function curveZap() internal pure returns (ICurveZap) { return ICurveZap(CURVE_ZAP); } function curveZapAddress() internal pure returns (address) { return CURVE_ZAP; } function curve3PoolAddress() internal pure returns (address) { return CURVE_3_POOL; } function threeCrv() internal pure returns (IERC20) { return IERC20(THREE_CRV); } function fertilizer() internal pure returns (IFertilizer) { return IFertilizer(FERTILIZER); } function fertilizerAddress() internal pure returns (address) { return FERTILIZER; } function fertilizerAdmin() internal pure returns (IProxyAdmin) { return IProxyAdmin(FERTILIZER_ADMIN); } function triCryptoPoolAddress() internal pure returns (address) { return TRI_CRYPTO_POOL; } function triCrypto() internal pure returns (IERC20) { return IERC20(TRI_CRYPTO); } function unripeLPPerDollar() internal pure returns (uint256) { return UNRIPE_LP_PER_DOLLAR; } function dollarPerUnripeLP() internal pure returns (uint256) { return 1e12/UNRIPE_LP_PER_DOLLAR; } function exploitAddLPRatio() internal pure returns (uint256) { return ADD_LP_RATIO; } function precision() internal pure returns (uint256) { return PRECISION; } function initialRecap() internal pure returns (uint256) { return INITIAL_HAIRCUT; } }
// SPDX-License-Identifier: MIT pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @title IBean * @author Publius * @notice Bean Interface */ abstract contract IBean is IERC20 { function burn(uint256 amount) public virtual; function burnFrom(address account, uint256 amount) public virtual; function mint(address account, uint256 amount) public virtual; function symbol() public view virtual returns (string memory); }
// SPDX-License-Identifier: MIT pragma experimental ABIEncoderV2; pragma solidity =0.7.6; interface ICurvePool { function A_precise() external view returns (uint256); function get_balances() external view returns (uint256[2] memory); function totalSupply() external view returns (uint256); function add_liquidity(uint256[2] memory amounts, uint256 min_mint_amount) external returns (uint256); function remove_liquidity_one_coin(uint256 _token_amount, int128 i, uint256 min_amount) external returns (uint256); function balances(int128 i) external view returns (uint256); function fee() external view returns (uint256); function coins(uint256 i) external view returns (address); function get_virtual_price() external view returns (uint256); function calc_token_amount(uint256[2] calldata amounts, bool deposit) external view returns (uint256); function calc_withdraw_one_coin(uint256 _token_amount, int128 i) external view returns (uint256); function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external returns (uint256); function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); } interface ICurveZap { function add_liquidity(address _pool, uint256[4] memory _deposit_amounts, uint256 _min_mint_amount) external returns (uint256); function calc_token_amount(address _pool, uint256[4] memory _amounts, bool _is_deposit) external returns (uint256); } interface ICurvePoolR { function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy, address receiver) external returns (uint256); function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy, address receiver) external returns (uint256); function remove_liquidity_one_coin(uint256 _token_amount, int128 i, uint256 min_amount, address receiver) external returns (uint256); } interface ICurvePool2R { function add_liquidity(uint256[2] memory amounts, uint256 min_mint_amount, address reciever) external returns (uint256); function remove_liquidity(uint256 _burn_amount, uint256[2] memory _min_amounts, address reciever) external returns (uint256[2] calldata); function remove_liquidity_imbalance(uint256[2] memory _amounts, uint256 _max_burn_amount, address reciever) external returns (uint256); } interface ICurvePool3R { function add_liquidity(uint256[3] memory amounts, uint256 min_mint_amount, address reciever) external returns (uint256); function remove_liquidity(uint256 _burn_amount, uint256[3] memory _min_amounts, address reciever) external returns (uint256[3] calldata); function remove_liquidity_imbalance(uint256[3] memory _amounts, uint256 _max_burn_amount, address reciever) external returns (uint256); } interface ICurvePool4R { function add_liquidity(uint256[4] memory amounts, uint256 min_mint_amount, address reciever) external returns (uint256); function remove_liquidity(uint256 _burn_amount, uint256[4] memory _min_amounts, address reciever) external returns (uint256[4] calldata); function remove_liquidity_imbalance(uint256[4] memory _amounts, uint256 _max_burn_amount, address reciever) external returns (uint256); } interface I3Curve { function get_virtual_price() external view returns (uint256); } interface ICurveFactory { function get_coins(address _pool) external view returns (address[4] calldata); function get_underlying_coins(address _pool) external view returns (address[8] calldata); } interface ICurveCryptoFactory { function get_coins(address _pool) external view returns (address[8] calldata); } interface ICurvePoolC { function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external returns (uint256); } interface ICurvePoolNoReturn { function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external; function add_liquidity(uint256[3] memory amounts, uint256 min_mint_amount) external; function remove_liquidity(uint256 _burn_amount, uint256[3] memory _min_amounts) external; function remove_liquidity_imbalance(uint256[3] memory _amounts, uint256 _max_burn_amount) external; function remove_liquidity_one_coin(uint256 _token_amount, uint256 i, uint256 min_amount) external; } interface ICurvePoolNoReturn128 { function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external; function remove_liquidity_one_coin(uint256 _token_amount, int128 i, uint256 min_amount) external; }
// SPDX-License-Identifier: MIT pragma experimental ABIEncoderV2; pragma solidity =0.7.6; interface IFertilizer { struct Balance { uint128 amount; uint128 lastBpf; } function beanstalkUpdate( address account, uint256[] memory ids, uint128 bpf ) external returns (uint256); function beanstalkMint(address account, uint256 id, uint128 amount, uint128 bpf) external; function balanceOfFertilized(address account, uint256[] memory ids) external view returns (uint256); function balanceOfUnfertilized(address account, uint256[] memory ids) external view returns (uint256); function lastBalanceOf(address account, uint256 id) external view returns (Balance memory); function lastBalanceOfBatch(address[] memory account, uint256[] memory id) external view returns (Balance[] memory); }
// SPDX-License-Identifier: MIT pragma experimental ABIEncoderV2; pragma solidity =0.7.6; interface IProxyAdmin { function upgrade(address proxy, address implementation) external; }
/* SPDX-License-Identifier: MIT */ pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; /** * @title Decimal * @author dYdX * * Library that defines a fixed-point number with 18 decimal places. */ library Decimal { using SafeMath for uint256; // ============ Constants ============ uint256 constant BASE = 10**18; // ============ Structs ============ struct D256 { uint256 value; } // ============ Static Functions ============ function zero() internal pure returns (D256 memory) { return D256({ value: 0 }); } function one() internal pure returns (D256 memory) { return D256({ value: BASE }); } function from( uint256 a ) internal pure returns (D256 memory) { return D256({ value: a.mul(BASE) }); } function ratio( uint256 a, uint256 b ) internal pure returns (D256 memory) { return D256({ value: getPartial(a, BASE, b) }); } // ============ Self Functions ============ function add( D256 memory self, uint256 b ) internal pure returns (D256 memory) { return D256({ value: self.value.add(b.mul(BASE)) }); } function sub( D256 memory self, uint256 b ) internal pure returns (D256 memory) { return D256({ value: self.value.sub(b.mul(BASE)) }); } function sub( D256 memory self, uint256 b, string memory reason ) internal pure returns (D256 memory) { return D256({ value: self.value.sub(b.mul(BASE), reason) }); } function mul( D256 memory self, uint256 b ) internal pure returns (D256 memory) { return D256({ value: self.value.mul(b) }); } function div( D256 memory self, uint256 b ) internal pure returns (D256 memory) { return D256({ value: self.value.div(b) }); } function pow( D256 memory self, uint256 b ) internal pure returns (D256 memory) { if (b == 0) { return one(); } D256 memory temp = D256({ value: self.value }); for (uint256 i = 1; i < b; ++i) { temp = mul(temp, self); } return temp; } function add( D256 memory self, D256 memory b ) internal pure returns (D256 memory) { return D256({ value: self.value.add(b.value) }); } function sub( D256 memory self, D256 memory b ) internal pure returns (D256 memory) { return D256({ value: self.value.sub(b.value) }); } function sub( D256 memory self, D256 memory b, string memory reason ) internal pure returns (D256 memory) { return D256({ value: self.value.sub(b.value, reason) }); } function mul( D256 memory self, D256 memory b ) internal pure returns (D256 memory) { return D256({ value: getPartial(self.value, b.value, BASE) }); } function div( D256 memory self, D256 memory b ) internal pure returns (D256 memory) { return D256({ value: getPartial(self.value, BASE, b.value) }); } function equals(D256 memory self, D256 memory b) internal pure returns (bool) { return self.value == b.value; } function greaterThan(D256 memory self, D256 memory b) internal pure returns (bool) { return compareTo(self, b) == 2; } function lessThan(D256 memory self, D256 memory b) internal pure returns (bool) { return compareTo(self, b) == 0; } function greaterThanOrEqualTo(D256 memory self, D256 memory b) internal pure returns (bool) { return compareTo(self, b) > 0; } function lessThanOrEqualTo(D256 memory self, D256 memory b) internal pure returns (bool) { return compareTo(self, b) < 2; } function isZero(D256 memory self) internal pure returns (bool) { return self.value == 0; } function asUint256(D256 memory self) internal pure returns (uint256) { return self.value.div(BASE); } // ============ Core Methods ============ function getPartial( uint256 target, uint256 numerator, uint256 denominator ) private pure returns (uint256) { return target.mul(numerator).div(denominator); } function compareTo( D256 memory a, D256 memory b ) private pure returns (uint256) { if (a.value == b.value) { return 1; } return a.value > b.value ? 2 : 0; } }
// SPDX-License-Identifier: MIT pragma solidity =0.7.6; /** * @author Brean * @dev Provides a set of functions to operate with Base64 strings. * @title Base64 is a 0.7.6 variation of Open Zeppelin's Base64. * */ library LibBytes64 { /** * @dev Base64 Encoding/Decoding Table */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // Loads the table into memory string memory table = _TABLE; // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter // and split into 4 numbers of 6 bits. // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up // - `data.length + 2` -> Round up // - `/ 3` -> Number of 3-bytes chunks // - `4 *` -> 4 characters for each chunk string memory result = new string(4 * ((data.length + 2) / 3)); assembly { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 32) // Run over the input, 3 bytes at a time for { let dataPtr := data let endPtr := add(data, mload(data)) } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 bytes (18 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F which is the number of // the previous character in the ASCII table prior to the Base64 Table // The result is then added to the table to get the character to write, // and finally write it in the result pointer but with a left shift // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } return result; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @author Publius * @title LibSafeMath128 is a uint128 variation of Open Zeppelin's Safe Math library. **/ library LibSafeMath128 { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint128 a, uint128 b) internal pure returns (bool, uint128) { uint128 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(uint128 a, uint128 b) internal pure returns (bool, uint128) { 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(uint128 a, uint128 b) internal pure returns (bool, uint128) { // 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); uint128 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(uint128 a, uint128 b) internal pure returns (bool, uint128) { 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(uint128 a, uint128 b) internal pure returns (bool, uint128) { 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(uint128 a, uint128 b) internal pure returns (uint128) { uint128 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(uint128 a, uint128 b) internal pure returns (uint128) { 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(uint128 a, uint128 b) internal pure returns (uint128) { if (a == 0) return 0; uint128 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(uint128 a, uint128 b) internal pure returns (uint128) { 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(uint128 a, uint128 b) internal pure returns (uint128) { 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(uint128 a, uint128 b, string memory errorMessage) internal pure returns (uint128) { 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(uint128 a, uint128 b, string memory errorMessage) internal pure returns (uint128) { 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(uint128 a, uint128 b, string memory errorMessage) internal pure returns (uint128) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @author Publius * @title LibSafeMath32 is a uint32 variation of Open Zeppelin's Safe Math library. **/ library LibSafeMath32 { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint32 a, uint32 b) internal pure returns (bool, uint32) { uint32 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(uint32 a, uint32 b) internal pure returns (bool, uint32) { 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(uint32 a, uint32 b) internal pure returns (bool, uint32) { // 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); uint32 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(uint32 a, uint32 b) internal pure returns (bool, uint32) { 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(uint32 a, uint32 b) internal pure returns (bool, uint32) { 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(uint32 a, uint32 b) internal pure returns (uint32) { uint32 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(uint32 a, uint32 b) internal pure returns (uint32) { 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(uint32 a, uint32 b) internal pure returns (uint32) { if (a == 0) return 0; uint32 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(uint32 a, uint32 b) internal pure returns (uint32) { 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(uint32 a, uint32 b) internal pure returns (uint32) { 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(uint32 a, uint32 b, string memory errorMessage) internal pure returns (uint32) { 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(uint32 a, uint32 b, string memory errorMessage) internal pure returns (uint32) { 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(uint32 a, uint32 b, string memory errorMessage) internal pure returns (uint32) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev String operations. */ library LibStrings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @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); } function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Converts a `int256` to its ASCII `string` representation. */ function toString(int256 value) internal pure returns(string memory){ if(value > 0){ return toString(uint256(value)); } else { return string(abi.encodePacked("-", toString(uint256(-value)))); } } /** * @notice Returns a substring of a string starting from startIndex and ending at endIndex. * @param str - The string to extract from. * @param startIndex - The index to start at. * @param endIndex - The index to end at. * Inspired by: https://ethereum.stackexchange.com/questions/31457/substring-in-solidity */ function substring( string memory str, uint startIndex, uint endIndex ) internal pure returns (string memory) { bytes memory strBytes = bytes(str); bytes memory result = new bytes(endIndex - startIndex); for (uint i = startIndex; i < endIndex; i++) { result[i - startIndex] = strBytes[i]; } return string(result); } /** * @notice Formats a uint128 number with 6 decimals to a string with 2 decimals. * @param number - The number to format. * @return string - The formatted string. */ function formatUintWith6DecimalsTo2(uint128 number) internal pure returns (string memory) { // Cast to uint256 to be compatible with toString string memory numString = toString(uint256(number)); // If the number has fewer than 6 decimals, add trailing zeros while (bytes(numString).length < 7) { numString = string(abi.encodePacked("0", numString)); } // Extract the integer part and the first 2 decimal places string memory integerPart = substring(numString, 0, bytes(numString).length - 6); string memory decimalPart = substring(numString, bytes(numString).length - 6, bytes(numString).length - 4); // Concatenate the integer part and the decimal part with a dot in between return string(abi.encodePacked(integerPart, ".", decimalPart)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.6; pragma experimental ABIEncoderV2; import "./Internalizer.sol"; import {IBeanstalk} from "./Internalizer.sol"; /** * @author publius * @title Barn Raiser */ // Inherits Internalizer thus inherits ERC1155Upgradeable and the uri function // The end Fert Facet only gets the interface of this contract contract Fertilizer is Internalizer { event ClaimFertilizer(uint256[] ids, uint256 beans); using SafeERC20Upgradeable for IERC20; using SafeMathUpgradeable for uint256; using LibSafeMath128 for uint128; /** * @notice Calculates and updates the amount of beans a user should receive * given a set of fertilizer ids. Callable only by the Beanstalk contract. * @param account - the user to update * @param ids - an array of fertilizer ids * @param bpf - the current beans per fertilizer */ function beanstalkUpdate( address account, uint256[] memory ids, uint128 bpf ) external onlyOwner returns (uint256) { return __update(account, ids, uint256(bpf)); } /** * @notice Mints a fertilizer to an account using a users specified balance * Called from FertilizerFacet.mintFertilizer() * @param account - the account to mint to * @param id - the id of the fertilizer to mint * @param amount - the amount of fertilizer to mint * @param bpf - the current beans per fertilizer */ function beanstalkMint(address account, uint256 id, uint128 amount, uint128 bpf) external onlyOwner { if (_balances[id][account].amount > 0) { uint256[] memory ids = new uint256[](1); ids[0] = id; _update(account, ids, bpf); } _balances[id][account].lastBpf = bpf; _safeMint( account, id, amount, bytes('0') ); } /** * @notice hadles state updates before a fertilizer transfer * @param from - the account to transfer from * @param to - the account to transfer to * @param ids - an array of fertilizer ids */ function _beforeTokenTransfer( address, // operator, address from, address to, uint256[] memory ids, uint256[] memory, // amounts bytes memory // data ) internal virtual override { uint256 bpf = uint256(IBeanstalk(owner()).beansPerFertilizer()); if (from != address(0)) _update(from, ids, bpf); _update(to, ids, bpf); } /** * @notice Calculates and transfers the rewarded beans * from a set of fertilizer ids to an account's internal balance * @param account - the user to update * @param ids - an array of fertilizer ids * @param bpf - the beans per fertilizer */ function _update( address account, uint256[] memory ids, uint256 bpf ) internal { uint256 amount = __update(account, ids, bpf); if (amount > 0) IBeanstalk(owner()).payFertilizer(account, amount); } /** * @notice Calculates and updates the amount of beans a user should receive * given a set of fertilizer ids and the current outstanding total beans per fertilizer * @param account - the user to update * @param ids - the fertilizer ids * @param bpf - the current beans per fertilizer * @return beans - the amount of beans to reward the fertilizer owner */ function __update( address account, uint256[] memory ids, uint256 bpf ) internal returns (uint256 beans) { for (uint256 i; i < ids.length; ++i) { uint256 stopBpf = bpf < ids[i] ? bpf : ids[i]; uint256 deltaBpf = stopBpf - _balances[ids[i]][account].lastBpf; if (deltaBpf > 0) { beans = beans.add(deltaBpf.mul(_balances[ids[i]][account].amount)); _balances[ids[i]][account].lastBpf = uint128(stopBpf); } } emit ClaimFertilizer(ids, beans); } /** * @notice Returns the balance of fertilized beans of a fertilizer owner given a set of fertilizer ids * @param account - the fertilizer owner * @param ids - the fertilizer ids * @return beans - the amount of fertilized beans the fertilizer owner has */ function balanceOfFertilized(address account, uint256[] memory ids) external view returns (uint256 beans) { uint256 bpf = uint256(IBeanstalk(owner()).beansPerFertilizer()); for (uint256 i; i < ids.length; ++i) { uint256 stopBpf = bpf < ids[i] ? bpf : ids[i]; uint256 deltaBpf = stopBpf - _balances[ids[i]][account].lastBpf; beans = beans.add(deltaBpf.mul(_balances[ids[i]][account].amount)); } } /** * @notice Returns the balance of unfertilized beans of a fertilizer owner given a set of fertilizer ids * @param account - the fertilizer owner * @param ids - the fertilizer ids * @return beans - the amount of unfertilized beans the fertilizer owner has */ function balanceOfUnfertilized(address account, uint256[] memory ids) external view returns (uint256 beans) { uint256 bpf = uint256(IBeanstalk(owner()).beansPerFertilizer()); for (uint256 i; i < ids.length; ++i) { if (ids[i] > bpf) beans = beans.add(ids[i].sub(bpf).mul(_balances[ids[i]][account].amount)); } } /** @notice Returns the value remaining to recapitalize beanstalk */ function remaining() public view returns (uint256) { return IBeanstalk(owner()).remainingRecapitalization(); } /** @notice Returns the id a fertilizer will receive when minted */ function getMintId() public view returns (uint256) { return uint256(IBeanstalk(owner()).getEndBpf()); } }
/** * SPDX-License-Identifier: MIT **/ pragma solidity ^0.7.6; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; /** * @author Publius * @dev Fertilizer tailored implemetation of the ERC-1155 standard. * We rewrite transfer and mint functions to allow the balance transfer function be overwritten as well. */ contract Fertilizer1155 is ERC1155Upgradeable { using AddressUpgradeable for address; 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); _transfer(from, to, id, amount); emit TransferSingle(operator, from, to, id, amount); __doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); } 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; i < ids.length; ++i) { _transfer(from, to, ids[i], amounts[i]); } emit TransferBatch(operator, from, to, ids, amounts); __doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); } function _transfer( address from, address to, uint256 id, uint256 amount ) internal virtual { } function _safeMint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual { require(to != address(0), "ERC1155: mint to the zero address"); address operator = _msgSender(); _transfer(address(0), to, id, amount); emit TransferSingle(operator, address(0), to, id, amount); __doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); } // The 3 functions below are copied from: // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/ERC1155.sol) // as they are private functions. 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.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.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.7.6; pragma experimental ABIEncoderV2; import {LibStrings} from "contracts/libraries/LibStrings.sol"; import {LibBytes64} from "contracts/libraries/LibBytes64.sol"; import {IBeanstalk} from "./Internalizer.sol"; /** * @title FertilizerImage * @author deadmanwalking */ contract FertilizerImage { address internal constant BEANSTALK = 0xC1E088fC1323b20BCBee9bd1B9fC9546db5624C5; ////////////////////// CONSTANTS TO ASSEMBLE SVG //////////////////////////// string internal constant BASE_JSON_URI = "data:application/json;base64,"; // Start for all fert svgs string private constant BASE_SVG_START = '<path d="M164.47 327.241 28.625 405.768l-.878-221.551 135.849-78.559.874 221.583Z" fill="#3DAA47"/><path d="m118.059 354.077-41.102 23.746-.874-221.551 41.101-23.778.875 221.583Z" fill="#3DAA47"/><path d="m26.825 184.242.87 221.567 93.367 54.339-.871-221.564-93.366-54.342Zm136.432-78.262.871 221.568 93.367 54.338-.871-221.564-93.367-54.342Z" fill="#3DB542"/>'; // End for all fert svgs string private constant BASE_SVG_END = '<path d="m256.898 381.609-135.846 78.527-.877-221.551 135.849-78.56.874 221.584Z" fill="#6DCB60"/><path d="m210.486 408.445-41.101 23.745-.875-221.551 41.102-23.778.874 221.584Z" fill="#3DAA47"/><path d="m240.901 364.949-104.407 60.387-.323-157.477 104.408-60.351.322 157.441Z" fill="#fff"/><path d="M195.789 268.025c23.137-6.714 36.875 10.631 32.306 35.233-4.02 21.652-21.352 42.845-39.769 49.821-19.171 7.26-35.717-2.268-36.297-23.966-.665-24.922 19.413-54.021 43.76-61.088Z" fill="#46B955"/><path d="m206.417 275.615-28.08 73.577s-24.569-35.397 28.08-73.577Zm-23.027 68.362 19.561-50.916s23.831 17.189-19.561 50.916Z" fill="#fff"/>'; // Top for the available fert svg string private constant FERT_TOP_AVAILABLE = '<path d="M76.634 162.915 212 84.133l44.034 75.909-135.842 78.544-43.557-75.671Z" fill="#81D672"/><path d="m124.966 134.97 40.624-24.001 44.031 75.906-41.098 23.765-43.557-75.67Z" fill="#46B955"/><path d="m212.125 47.918-.116 36.228-135.394 78.766.116-36.17c0-2.032-1.39-4.413-3.13-5.457-.87-.523-1.68-.523-2.261-.233l135.394-78.766c.58-.349 1.332-.29 2.203.233 1.736.989 3.188 3.425 3.188 5.4Z" fill="#6DCB60"/><path d="m165.713 74.752-.116 36.228-40.65 23.988.116-36.17c0-2.032-1.39-4.413-3.129-5.457-.872-.523-1.681-.523-2.262-.232l40.65-23.989c.58-.349 1.332-.29 2.203.233 1.739.986 3.188 3.425 3.188 5.4Z" fill="#42A84C"/><path d="M73.579 121.298c1.739 1.005 3.162 3.422 3.159 5.425l-.104 36.193 43.557 75.667-93.366-54.339 43.521-25.018.103-36.141c.004-2 1.39-2.795 3.13-1.787Z" fill="#2C9A2C"/><path d="M107.879 226.766 36.62 185.565l35.742-20.395 11.428 19.794 24.089 41.802Z" fill="#6DCB60"/><path d="m81.348 180.731-44.728 4.834 35.742-20.395 8.986 15.561Z" fill="#81D672"/> <path d="M95.493 209.237c-9.447 2.966-17.845 10.637-21.62 21.552-.497 1.589-2.678 1.589-3.272 0-3.272-10.23-11.405-18.276-21.52-21.552-1.784-.598-1.784-2.782 0-3.377 10.115-3.312 18.174-11.506 21.52-21.552.594-1.689 2.778-1.689 3.272 0 3.768 10.689 11.563 18.195 21.62 21.552 1.687.595 1.687 2.779 0 3.377Z" fill="#fff"/>'; // Top for the active fert svg string private constant FERT_TOP_ACTIVE ='<ellipse cx="113.247" cy="220.688" rx="38.717" ry="38.774" fill="#7F5533"/><ellipse cx="113.247" cy="220.688" rx="38.717" ry="38.774" fill="#7F5533"/><ellipse cx="70.013" cy="236.844" rx="38.717" ry="38.774" fill="#7F5533"/><path d="m26.825 184.242.87 221.567 93.367 54.339-.871-221.564-93.366-54.342Zm136.432-78.262.871 221.568 93.367 54.338-.871-221.564-93.367-54.342Z" fill="#3DB542"/><ellipse cx="156.805" cy="198.715" rx="38.717" ry="38.774" fill="#7F5533"/><ellipse cx="198.103" cy="189.668" rx="38.717" ry="38.774" fill="#7F5533"/>'; /** * @dev imageURI returns the base64 encoded image URI representation of the Fertilizer * @param _id - the id of the Fertilizer * @param bpfRemaining - the bpfRemaining of the Fertilizer * @return imageUri - the image URI representation of the Fertilizer */ function imageURI(uint256 _id, uint128 bpfRemaining) public view returns (string memory) { return svgToImageURI(generateImageSvg(_id, bpfRemaining)); } /////////////// FERTILIZER SVG ORDER /////////////////// // SVG_HEADER // BASE_SVG_START // FERT_SVG_TOP (available, active) // BASE_SVG_END // SVG_PRE_NUMBER // BPF_REMAINING // END OF SVG /** * @dev generateImageSvg assembles the needed components for the Fertilizer svg * For use in the on-chain json fertilizer metadata * @param _id - the id of the Fertilizer * @param bpfRemaining - the bpfRemaining of the Fertilizer * @return imageUri - the image URI representation of the Fertilizer */ function generateImageSvg(uint256 _id, uint128 bpfRemaining) internal view returns (string memory) { return string( abi.encodePacked( '<svg width="294" height="512" viewBox="0 0 294 512" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">', // SVG HEADER BASE_SVG_START, getFertilizerStatusSvg(_id, bpfRemaining), // FERT_SVG_TOP (available, active) BASE_SVG_END, '<text font-family="sans-serif" font-size="20" x="20" y="490" fill="black" ><tspan dy="0" x="20">', // PRE NUMBER FOR BPF REMAINING LibStrings.formatUintWith6DecimalsTo2(bpfRemaining), // BPF_REMAINING with 2 decimal places " BPF Remaining </tspan></text></svg>" // END OF SVG ) ); } /** * @dev Returns the correct svg top for the Fertilizer status based on the bpfRemaining. * @param _id - the id of the Fertilizer * @param bpfRemaining - the bpfRemaining of the Fertilizer * @return fertilizerStatusSvg an svg top for the correct Fertilizer status */ function getFertilizerStatusSvg(uint256 _id, uint128 bpfRemaining) internal view returns (string memory) { uint256 fertilizerSupply = IBeanstalk(BEANSTALK).getFertilizer( uint128(_id) ); string memory fertilizerStatusSvg = FERT_TOP_AVAILABLE; if (fertilizerSupply > 0) { fertilizerStatusSvg = bpfRemaining > 0 ? FERT_TOP_ACTIVE : ''; // a used fert (bpfRemaining = 0) has no top } return fertilizerStatusSvg; } /// @dev Helper function that converts an svg to a bade64 encoded image URI. function svgToImageURI(string memory svg) internal pure returns (string memory) { return string( abi.encodePacked("data:image/svg+xml;base64,", LibBytes64.encode(bytes(string(abi.encodePacked(svg))))) ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.6; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./Fertilizer1155.sol"; import "contracts/libraries/LibSafeMath32.sol"; import "contracts/libraries/LibSafeMath128.sol"; import "./FertilizerImage.sol"; import {LibBytes64} from "contracts/libraries/LibBytes64.sol"; /** * @author publius, deadmanwalking * @title Fertilizer before the Unpause */ // interface to interact with the Beanstalk contract interface IBeanstalk { function payFertilizer(address account, uint256 amount) external; function beansPerFertilizer() external view returns (uint128); function getEndBpf() external view returns (uint128); function remainingRecapitalization() external view returns (uint256); function getFertilizer(uint128) external view returns (uint256); } contract Internalizer is OwnableUpgradeable, ReentrancyGuardUpgradeable, Fertilizer1155, FertilizerImage { using SafeERC20Upgradeable for IERC20; using LibSafeMath128 for uint128; using LibStrings for uint256; struct Balance { uint128 amount; uint128 lastBpf; } function __Internallize_init(string memory uri_) internal { __Ownable_init(); __ERC1155_init(uri_); __ReentrancyGuard_init(); } mapping(uint256 => mapping(address => Balance)) internal _balances; string private _uri; ///////////////////// NEW URI FUNCTION /////////////////////// /** * @notice Assembles and returns a base64 encoded json metadata * URI for a given fertilizer ID. * Need to override because the contract indirectly * inherits from ERC1155. * @param _id - the id of the fertilizer * @return - the json metadata URI */ function uri(uint256 _id) external view virtual override returns (string memory) { uint128 bpfRemaining = calculateBpfRemaining(_id); // generate the image URI string memory imageUri = imageURI(_id , bpfRemaining); // assemble and return the json URI return ( string( abi.encodePacked( BASE_JSON_URI, LibBytes64.encode( bytes( abi.encodePacked( '{"name": "Fertilizer - ', _id.toString(), '", "external_url": "https://fert.bean.money/', _id.toString(), '.html", ', '"description": "A trusty constituent of any Farmers toolbox, ERC-1155 FERT has been known to spur new growth on seemingly dead farms. Once purchased and deployed into fertile ground by Farmers, Fertilizer generates new Sprouts: future Beans yet to be repaid by Beanstalk in exchange for doing the work of Replanting the protocol.", "image": "', imageUri, '", "attributes": [{ "trait_type": "BPF Remaining","display_type": "boost_number","value": ', LibStrings.formatUintWith6DecimalsTo2(bpfRemaining), " }]}" ) ) ) ) ) ); } /** * @notice Returns the beans per fertilizer remaining for a given fertilizer Id. * @param id - the id of the fertilizer * Formula: bpfRemaining = id - s.bpf * Calculated here to avoid uint underflow * Solidity 0.8.0 has underflow protection and the tx would revert but we are using 0.7.6 */ function calculateBpfRemaining(uint256 id) internal view returns (uint128) { // make sure it does not underflow if (uint128(id) >= IBeanstalk(BEANSTALK).beansPerFertilizer()) { return uint128(id) - IBeanstalk(BEANSTALK).beansPerFertilizer() ; } else { return 0; } } function name() external pure returns (string memory) { return "Fertilizer"; } function symbol() external pure returns (string memory) { return "FERT"; } 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].amount; } function lastBalanceOf(address account, uint256 id) public view returns (Balance memory) { require(account != address(0), "ERC1155: balance query for the zero address"); return _balances[id][account]; } function lastBalanceOfBatch(address[] memory accounts, uint256[] memory ids) external view returns (Balance[] memory balances) { balances = new Balance[](accounts.length); for (uint256 i; i < accounts.length; ++i) { balances[i] = lastBalanceOf(accounts[i], ids[i]); } } function _transfer( address from, address to, uint256 id, uint256 amount ) internal virtual override { uint128 _amount = uint128(amount); if (from != address(0)) { uint128 fromBalance = _balances[id][from].amount; require(uint256(fromBalance) >= amount, "ERC1155: insufficient balance for transfer"); // Because we know fromBalance >= amount, we know amount < type(uint128).max _balances[id][from].amount = fromBalance - _amount; } _balances[id][to].amount = _balances[id][to].amount.add(_amount); } }
{ "optimizer": { "enabled": true, "runs": 100 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50613f8c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063e1c7392a14610030575b600080fd5b61003861003a565b005b60006040516100489061010a565b604051809103906000f080158015610064573d6000803e3d6000fd5b509050806100706100da565b6001600160a01b03166399a88ec46100866100f2565b836040518363ffffffff1660e01b81526004016100a4929190610117565b600060405180830381600087803b1580156100be57600080fd5b505af11580156100d2573d6000803e3d6000fd5b505050505050565b73fecb01359263c12aa9ed838f878a596f0064aa6e90565b73402c84de2ce49af88f5e2ef3710ff89bfed36cb690565b613e258061013283390190565b6001600160a01b039283168152911660208201526040019056fe608060405234801561001057600080fd5b50613e05806100206000396000f3fe608060405234801561001057600080fd5b50600436106101415760003560e01c80638da5cb5b116100b8578063a22cb4651161007c578063a22cb4651461028d578063b6f42085146102a0578063bf02d309146102b3578063e985e9c5146102d3578063f242432a146102e6578063f2fde38b146102f957610141565b80638da5cb5b1461022a57806391b7301f1461023f57806395d89b411461025f57806397e6e467146102675780639a9a18a21461027a57610141565b8063246c0d871161010a578063246c0d87146101ca5780632c12865b146101d25780632eb2c2d6146101e55780634e1273f4146101fa57806355234ec01461021a578063715018a61461022257610141565b8062fdd58e1461014657806301ffc9a71461016f57806306fdde031461018f5780630e89341c146101a45780631edb6be1146101b7575b600080fd5b610159610154366004612470565b61030c565b6040516101669190613065565b60405180910390f35b61018261017d36600461259c565b610371565b6040516101669190612d8b565b610197610394565b6040516101669190612d96565b6101976101b23660046125f0565b6103b9565b6101596101c536600461238c565b61047b565b6101596105dd565b6101976101e0366004612620565b610665565b6101f86101f3366004612285565b610680565b005b61020d6102083660046124e9565b6107df565b6040516101669190612d31565b6101596108ca565b6101f8610949565b6102326109f5565b6040516101669190612c2b565b61025261024d366004612470565b610a04565b6040516101669190613043565b610197610a7f565b6101596102753660046123d7565b610a9d565b6101f8610288366004612499565b610b1d565b6101f861029b366004612436565b610c6e565b6101596102ae36600461238c565b610d5d565b6102c66102c13660046124e9565b610f04565b6040516101669190612ce4565b6101826102e1366004612253565b610fbc565b6101f86102f436600461232a565b610fea565b6101f8610307366004612239565b6110f5565b60006001600160a01b03831661033d5760405162461bcd60e51b815260040161033490612e45565b60405180910390fd5b50600081815260fb602090815260408083206001600160a01b03861684529091529020546001600160801b03165b92915050565b6001600160e01b0319811660009081526097602052604090205460ff165b919050565b60408051808201909152600a8152692332b93a34b634bd32b960b11b60208201525b90565b606060006103c6836111f8565b905060006103d48483610665565b90506040518060400160405280601d81526020017f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152506104526104188661132d565b6104218761132d565b8461042b87611407565b60405160200161043e94939291906127e7565b60405160208183030381529060405261159b565b6040516020016104639291906127b8565b60405160208183030381529060405292505050919050565b6000806104866109f5565b6001600160a01b0316639bb4e35a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156104be57600080fd5b505afa1580156104d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f691906125d4565b6001600160801b0316905060005b83518110156105d5578184828151811061051a57fe5b602002602001015111156105cd576105ca6105c360fb600087858151811061053e57fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002060000160009054906101000a90046001600160801b03166001600160801b03166105bd858886815181106105a757fe5b60200260200101516116db90919063ffffffff16565b90611738565b8490611791565b92505b600101610504565b505092915050565b60006105e76109f5565b6001600160a01b031663c85951a16040518163ffffffff1660e01b815260040160206040518083038186803b15801561061f57600080fd5b505afa158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906125d4565b6001600160801b0316905090565b606061067961067484846117e9565b611860565b9392505050565b81518351146106a15760405162461bcd60e51b815260040161033490612fba565b6001600160a01b0384166106c75760405162461bcd60e51b815260040161033490612ed9565b6106cf61189c565b6001600160a01b0316856001600160a01b031614806106f557506106f5856102e161189c565b6107115760405162461bcd60e51b815260040161033490612f1e565b600061071b61189c565b905061072b8187878787876118a0565b60005b845181101561077157610769878787848151811061074857fe5b602002602001015187858151811061075c57fe5b6020026020010151611953565b60010161072e565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516107c1929190612d44565b60405180910390a46107d7818787878787611a70565b505050505050565b606081518351146108215760405162461bcd60e51b81526004018080602001828103825260298152602001806139c56029913960400191505060405180910390fd5b600083516001600160401b038111801561083a57600080fd5b50604051908082528060200260200182016040528015610864578160200160208202803683370190505b50905060005b84518110156108c2576108a385828151811061088257fe5b602002602001015185838151811061089657fe5b602002602001015161030c565b8282815181106108af57fe5b602090810291909101015260010161086a565b509392505050565b60006108d46109f5565b6001600160a01b0316634a16607c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561090c57600080fd5b505afa158015610920573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109449190612608565b905090565b61095161189c565b6001600160a01b03166109626109f5565b6001600160a01b0316146109ab576040805162461bcd60e51b81526020600482018190526024820152600080516020613762833981519152604482015290519081900360640190fd5b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b610a0c61213b565b6001600160a01b038316610a325760405162461bcd60e51b815260040161033490612e45565b50600081815260fb602090815260408083206001600160a01b03861684528252918290208251808401909352546001600160801b038082168452600160801b909104169082015292915050565b6040805180820190915260048152631191549560e21b602082015290565b6000610aa761189c565b6001600160a01b0316610ab86109f5565b6001600160a01b031614610b01576040805162461bcd60e51b81526020600482018190526024820152600080516020613762833981519152604482015290519081900360640190fd5b610b158484846001600160801b0316611b7e565b949350505050565b610b2561189c565b6001600160a01b0316610b366109f5565b6001600160a01b031614610b7f576040805162461bcd60e51b81526020600482018190526024820152600080516020613762833981519152604482015290519081900360640190fd5b600083815260fb602090815260408083206001600160a01b03881684529091529020546001600160801b031615610c0257604080516001808252818301909252600091602080830190803683370190505090508381600081518110610be057fe5b602002602001018181525050610c008582846001600160801b0316611ce8565b505b600083815260fb602090815260408083206001600160a01b038816845282529182902080546001600160801b03908116600160801b8683160217909155825180840190935260018352600360fc1b91830191909152610c68918691869190861690611d6a565b50505050565b816001600160a01b0316610c8061189c565b6001600160a01b03161415610cc65760405162461bcd60e51b815260040180806020018281038252602981526020018061399c6029913960400191505060405180910390fd5b8060ca6000610cd361189c565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610d1761189c565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600080610d686109f5565b6001600160a01b0316639bb4e35a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610da057600080fd5b505afa158015610db4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd891906125d4565b6001600160801b0316905060005b83518110156105d5576000848281518110610dfd57fe5b60200260200101518310610e2457848281518110610e1757fe5b6020026020010151610e26565b825b9050600060fb6000878581518110610e3a57fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002060000160109054906101000a90046001600160801b03166001600160801b031682039050610ef5610eee60fb6000898781518110610ead57fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038d16825290925290205483906001600160801b0316611738565b8690611791565b94505050806001019050610de6565b606082516001600160401b0381118015610f1d57600080fd5b50604051908082528060200260200182016040528015610f5757816020015b610f4461213b565b815260200190600190039081610f3c5790505b50905060005b8351811015610fb557610f96848281518110610f7557fe5b6020026020010151848381518110610f8957fe5b6020026020010151610a04565b828281518110610fa257fe5b6020908102919091010152600101610f5d565b5092915050565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205460ff1690565b6001600160a01b0384166110105760405162461bcd60e51b815260040161033490612ed9565b61101861189c565b6001600160a01b0316856001600160a01b0316148061103e575061103e856102e161189c565b61105a5760405162461bcd60e51b815260040161033490612e90565b600061106461189c565b905061108481878761107588611e17565b61107e88611e17565b876118a0565b61109086868686611953565b846001600160a01b0316866001600160a01b0316826001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6287876040516110df92919061306e565b60405180910390a46107d7818787878787611e5c565b6110fd61189c565b6001600160a01b031661110e6109f5565b6001600160a01b031614611157576040805162461bcd60e51b81526020600482018190526024820152600080516020613762833981519152604482015290519081900360640190fd5b6001600160a01b03811661119c5760405162461bcd60e51b81526004018080602001828103825260268152602001806131c16026913960400191505060405180910390fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b600073c1e088fc1323b20bcbee9bd1b9fc9546db5624c56001600160a01b0316639bb4e35a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561124757600080fd5b505afa15801561125b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127f91906125d4565b6001600160801b0316826001600160801b0316106113255773c1e088fc1323b20bcbee9bd1b9fc9546db5624c56001600160a01b0316639bb4e35a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156112e457600080fd5b505afa1580156112f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061131c91906125d4565b8203905061038f565b50600061038f565b60608161135257506040805180820190915260018152600360fc1b602082015261038f565b8160005b811561136a57600101600a82049150611356565b6000816001600160401b038111801561138257600080fd5b506040519080825280601f01601f1916602001820160405280156113ad576020820181803683370190505b50859350905060001982015b83156113fe57600a840660300160f81b828280600190039350815181106113dc57fe5b60200101906001600160f81b031916908160001a905350600a840493506113b9565b50949350505050565b6060600061141d836001600160801b031661132d565b90505b6007815110156114a457806040516020018080600360fc1b81525060010182805190602001908083835b602083106114695780518252601f19909201916020918201910161144a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040529050611420565b60006114b68260006006855103611f2d565b905060006114cd8360068551036004865103611f2d565b905081816040516020018083805190602001908083835b602083106115035780518252601f1990920191602091820191016114e4565b6001836020036101000a03801982511681845116808217855250505050505090500180601760f91b81525060010182805190602001908083835b6020831061155c5780518252601f19909201916020918201910161153d565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529350505050919050565b60608151600014156115bc575060408051602081019091526000815261038f565b6000604051806060016040528060408152602001613701604091399050600060038451600201816115e957fe5b046004026001600160401b038111801561160257600080fd5b506040519080825280601f01601f19166020018201604052801561162d576020820181803683370190505b509050600182016020820185865187015b80821015611699576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184535060018301925061163e565b50506003865106600181146116b557600281146116c8576116d0565b603d6001830353603d60028303536116d0565b603d60018303535b509195945050505050565b600082821115611732576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000826117475750600061036b565b8282028284828161175457fe5b04146106795760405162461bcd60e51b81526004018080602001828103825260218152602001806137416021913960400191505060405180910390fd5b600082820183811015610679576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b6060604051806101a0016040528061016881526020016139ee61016891396118118484611fd0565b604051806102a0016040528061027a8152602001613b5661027a913961183685611407565b6040516020016118499493929190612a54565b604051602081830303815290604052905092915050565b60606118768260405160200161043e919061279c565b6040516020016118869190612be6565b6040516020818303038152906040529050919050565b3390565b60006118aa6109f5565b6001600160a01b0316639bb4e35a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118e257600080fd5b505afa1580156118f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191a91906125d4565b6001600160801b031690506001600160a01b0386161561193f5761193f868583611ce8565b61194a858583611ce8565b50505050505050565b806001600160a01b038516156119f157600083815260fb602090815260408083206001600160a01b03891684529091529020546001600160801b0316828110156119af5760405162461bcd60e51b815260040161033490612f70565b600084815260fb602090815260408083206001600160a01b038a168452909152902080546001600160801b031916918390036001600160801b03169190911790555b600083815260fb602090815260408083206001600160a01b0388168452909152902054611a27906001600160801b0316826120d1565b600093845260fb602090815260408086206001600160a01b039790971686529590529390922080546001600160801b0319166001600160801b0390941693909317909255505050565b611a82846001600160a01b0316612135565b156107d75760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190611abb9089908990889088908890600401612c3f565b602060405180830381600087803b158015611ad557600080fd5b505af1925050508015611b05575060408051601f3d908101601f19168201909252611b02918101906125b8565b60015b611b4e57611b116130ee565b80611b1c5750611b36565b8060405162461bcd60e51b81526004016103349190612d96565b60405162461bcd60e51b815260040161033490612da9565b6001600160e01b0319811663bc197c8160e01b1461194a5760405162461bcd60e51b815260040161033490612dfd565b6000805b8351811015611ca7576000848281518110611b9957fe5b60200260200101518410611bc057848281518110611bb357fe5b6020026020010151611bc2565b835b9050600060fb6000878581518110611bd657fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038b168252909252902054600160801b90046001600160801b0316820390508015611c9d57611c3e611c3760fb6000898781518110610ead57fe5b8590611791565b93508160fb6000888681518110611c5157fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038c168252909252902080546001600160801b03928316600160801b0292169190911790555b5050600101611b82565b507f96f98c54750e4481bfa3aaac1e279e22f034f6bb3fbe5a79cb28d63ac2db367c8382604051611cd9929190612d69565b60405180910390a19392505050565b6000611cf5848484611b7e565b90508015610c6857611d056109f5565b6001600160a01b031663d47aee5985836040518363ffffffff1660e01b8152600401611d32929190612ccb565b600060405180830381600087803b158015611d4c57600080fd5b505af1158015611d60573d6000803e3d6000fd5b5050505050505050565b6001600160a01b038416611d905760405162461bcd60e51b815260040161033490613002565b6000611d9a61189c565b9050611da96000868686611953565b846001600160a01b031660006001600160a01b0316826001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628787604051611df992919061306e565b60405180910390a4611e1081600087878787611e5c565b5050505050565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110611e4b57fe5b602090810291909101015292915050565b611e6e846001600160a01b0316612135565b156107d75760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190611ea79089908990889088908890600401612c91565b602060405180830381600087803b158015611ec157600080fd5b505af1925050508015611ef1575060408051601f3d908101601f19168201909252611eee918101906125b8565b60015b611efd57611b116130ee565b6001600160e01b0319811663f23a6e6160e01b1461194a5760405162461bcd60e51b815260040161033490612dfd565b60608360008484036001600160401b0381118015611f4a57600080fd5b506040519080825280601f01601f191660200182016040528015611f75576020820181803683370190505b509050845b84811015611fc657828181518110611f8e57fe5b602001015160f81c60f81b8287830381518110611fa757fe5b60200101906001600160f81b031916908160001a905350600101611f7a565b5095945050505050565b604051639c45a1d560e01b815260609060009073c1e088fc1323b20bcbee9bd1b9fc9546db5624c590639c45a1d59061200d908790600401613051565b60206040518083038186803b15801561202557600080fd5b505afa158015612039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205d9190612608565b9050600060405180610540016040528061051a81526020016131e761051a913990508115610b15576000846001600160801b0316116120ab57604051806020016040528060008152506120c8565b60405180610240016040528061021a815260200161378261021a91395b95945050505050565b60008282016001600160801b038085169082161015610679576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b3b151590565b604080518082019091526000808252602082015290565b80356001600160a01b038116811461038f57600080fd5b600082601f830112612179578081fd5b8135602061218e6121898361309f565b61307c565b82815281810190858301838502870184018810156121aa578586fd5b855b858110156121c8578135845292840192908401906001016121ac565b5090979650505050505050565b600082601f8301126121e5578081fd5b81356001600160401b038111156121f857fe5b61220b601f8201601f191660200161307c565b81815284602083860101111561221f578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121561224a578081fd5b61067982612152565b60008060408385031215612265578081fd5b61226e83612152565b915061227c60208401612152565b90509250929050565b600080600080600060a0868803121561229c578081fd5b6122a586612152565b94506122b360208701612152565b935060408601356001600160401b03808211156122ce578283fd5b6122da89838a01612169565b945060608801359150808211156122ef578283fd5b6122fb89838a01612169565b93506080880135915080821115612310578283fd5b5061231d888289016121d5565b9150509295509295909350565b600080600080600060a08688031215612341578081fd5b61234a86612152565b945061235860208701612152565b9350604086013592506060860135915060808601356001600160401b03811115612380578182fd5b61231d888289016121d5565b6000806040838503121561239e578182fd5b6123a783612152565b915060208301356001600160401b038111156123c1578182fd5b6123cd85828601612169565b9150509250929050565b6000806000606084860312156123eb578283fd5b6123f484612152565b925060208401356001600160401b0381111561240e578283fd5b61241a86828701612169565b925050604084013561242b816131ab565b809150509250925092565b60008060408385031215612448578182fd5b61245183612152565b915060208301358015158114612465578182fd5b809150509250929050565b60008060408385031215612482578182fd5b61248b83612152565b946020939093013593505050565b600080600080608085870312156124ae578182fd5b6124b785612152565b93506020850135925060408501356124ce816131ab565b915060608501356124de816131ab565b939692955090935050565b600080604083850312156124fb578182fd5b82356001600160401b0380821115612511578384fd5b818501915085601f830112612524578384fd5b813560206125346121898361309f565b82815281810190858301838502870184018b1015612550578889fd5b8896505b848710156125795761256581612152565b835260019690960195918301918301612554565b509650508601359250508082111561258f578283fd5b506123cd85828601612169565b6000602082840312156125ad578081fd5b813561067981613192565b6000602082840312156125c9578081fd5b815161067981613192565b6000602082840312156125e5578081fd5b8151610679816131ab565b600060208284031215612601578081fd5b5035919050565b600060208284031215612619578081fd5b5051919050565b60008060408385031215612632578182fd5b823591506020830135612465816131ab565b6000815180845260208085019450808401835b8381101561267357815187529582019590820190600101612657565b509495945050505050565b600081518084526126968160208601602086016130bc565b601f01601f19169290920160200192915050565b600081516126bc8185602086016130bc565b9290920192915050565b63207d5d7d60e01b815260040190565b7f204250462052656d61696e696e67203c2f747370616e3e3c2f746578743e3c2f81526339bb339f60e11b602082015260240190565b7f222c202261747472696275746573223a205b7b202274726169745f747970652281527f3a20224250462052656d61696e696e67222c22646973706c61795f747970652260208201527f3a2022626f6f73745f6e756d626572222c2276616c7565223a200000000000006040820152605a0190565b80516001600160801b03908116835260209182015116910152565b600082516127ae8184602087016130bc565b9190910192915050565b600083516127ca8184602088016130bc565b8351908301906127de8183602088016130bc565b01949350505050565b7603d913730b6b2911d10112332b93a34b634bd32b910169604d1b8152845160009061281a816017850160208a016130bc565b7f222c202265787465726e616c5f75726c223a202268747470733a2f2f666572746017918401918201526b2e6265616e2e6d6f6e65792f60a01b6037820152855161286c816043840160208a016130bc565b67017343a36b61116160c51b604392909101918201527f226465736372697074696f6e223a2022412074727573747920636f6e73746974604b8201527f75656e74206f6620616e79204661726d65727320746f6f6c626f782c20455243606b8201527f2d31313535204645525420686173206265656e206b6e6f776e20746f20737075608b8201527f72206e65772067726f777468206f6e207365656d696e676c792064656164206660ab8201527f61726d732e204f6e63652070757263686173656420616e64206465706c6f796560cb8201527f6420696e746f2066657274696c652067726f756e64206279204661726d65727360eb8201527f2c2046657274696c697a65722067656e657261746573206e6577205370726f7561010b8201527f74733a20667574757265204265616e732079657420746f20626520726570616961012b8201527f64206279204265616e7374616c6b20696e2065786368616e676520666f72206461014b8201527f6f696e672074686520776f726b206f66205265706c616e74696e67207468652061016b82015275383937ba37b1b7b6171116101134b6b0b3b2911d101160511b61018b820152612a49612a44612a3e612a396101a18501896126aa565b61270c565b866126aa565b6126c6565b979650505050505050565b60007f3c7376672077696474683d2232393422206865696768743d223531322220766982527f6577426f783d223020302032393420353132222066696c6c3d226e6f6e65222060208301527f786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737660408301527f672220786d6c6e733a786c696e6b3d22687474703a2f2f7777772e77332e6f7260608301526d3397989c9c9c97bc3634b735911f60911b60808301528551612b1581608e850160208a016130bc565b855190830190612b2c81608e840160208a016130bc565b8551910190612b4281608e8401602089016130bc565b7f3c7465787420666f6e742d66616d696c793d2273616e732d7365726966222066608e92909101918201527f6f6e742d73697a653d2232302220783d2232302220793d22343930222066696c60ae8201527f6c3d22626c61636b22203e3c747370616e2064793d22302220783d223230223e60ce8201528351612bcc8160ee8401602088016130bc565b612bda60ee828401016126d6565b98975050505050505050565b60007f646174613a696d6167652f7376672b786d6c3b6261736536342c00000000000082528251612c1e81601a8501602087016130bc565b91909101601a0192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0386811682528516602082015260a060408201819052600090612c6b90830186612644565b8281036060840152612c7d8186612644565b90508281036080840152612bda818561267e565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090612a499083018461267e565b6001600160a01b03929092168252602082015260400190565b602080825282518282018190526000919060409081850190868401855b82811015612d2457612d14848351612781565b9284019290850190600101612d01565b5091979650505050505050565b6000602082526106796020830184612644565b600060408252612d576040830185612644565b82810360208401526120c88185612644565b600060408252612d7c6040830185612644565b90508260208301529392505050565b901515815260200190565b600060208252610679602083018461267e565b60208082526034908201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356040820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b606082015260800190565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b6020808252602b908201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60408201526a65726f206164647265737360a81b606082015260800190565b60208082526029908201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260408201526808185c1c1c9bdd995960ba1b606082015260800190565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526032908201527f455243313135353a207472616e736665722063616c6c6572206973206e6f74206040820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b6040810161036b8284612781565b6001600160801b0391909116815260200190565b90815260200190565b918252602082015260400190565b6040518181016001600160401b038111828210171561309757fe5b604052919050565b60006001600160401b038211156130b257fe5b5060209081020190565b60005b838110156130d75781810151838201526020016130bf565b83811115610c685750506000910152565b60e01c90565b600060443d10156130fe576103b6565b600481823e6308c379a061311282516130e8565b1461311c576103b6565b6040513d600319016004823e80513d6001600160401b03816024840111818411171561314b57505050506103b6565b8284019250825191508082111561316557505050506103b6565b503d8301602082840101111561317d575050506103b6565b601f01601f1916810160200160405291505090565b6001600160e01b0319811681146131a857600080fd5b50565b6001600160801b03811681146131a857600080fdfe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573733c7061746820643d224d37362e363334203136322e393135203231322038342e3133336c34342e3033342037352e3930392d3133352e3834322037382e3534342d34332e3535372d37352e3637315a222066696c6c3d2223383144363732222f3e3c7061746820643d226d3132342e393636203133342e39372034302e3632342d32342e3030312034342e3033312037352e3930362d34312e3039382032332e3736352d34332e3535372d37352e36375a222066696c6c3d2223343642393535222f3e3c7061746820643d226d3231322e3132352034372e3931382d2e3131362033362e3232382d3133352e3339342037382e3736362e3131362d33362e313763302d322e3033322d312e33392d342e3431332d332e31332d352e3435372d2e38372d2e3532332d312e36382d2e3532332d322e3236312d2e3233336c3133352e3339342d37382e373636632e35382d2e33343920312e3333322d2e323920322e3230332e32333320312e3733362e39383920332e31383820332e34323520332e31383820352e345a222066696c6c3d2223364443423630222f3e3c7061746820643d226d3136352e3731332037342e3735322d2e3131362033362e3232382d34302e36352032332e3938382e3131362d33362e313763302d322e3033322d312e33392d342e3431332d332e3132392d352e3435372d2e3837322d2e3532332d312e3638312d2e3532332d322e3236322d2e3233326c34302e36352d32332e393839632e35382d2e33343920312e3333322d2e323920322e3230332e32333320312e3733392e39383620332e31383820332e34323520332e31383820352e345a222066696c6c3d2223343241383443222f3e3c7061746820643d224d37332e353739203132312e32393863312e37333920312e30303520332e31363220332e34323220332e31353920352e3432356c2d2e3130342033362e3139332034332e3535372037352e3636372d39332e3336362d35342e3333392034332e3532312d32352e3031382e3130332d33362e313431632e3030342d3220312e33392d322e37393520332e31332d312e3738375a222066696c6c3d2223324339413243222f3e3c7061746820643d224d3130372e383739203232362e3736362033362e3632203138352e3536356c33352e3734322d32302e3339352031312e3432382031392e3739342032342e3038392034312e3830325a222066696c6c3d2223364443423630222f3e3c7061746820643d226d38312e333438203138302e3733312d34342e37323820342e3833342033352e3734322d32302e33393520382e3938362031352e3536315a222066696c6c3d2223383144363732222f3e20203c7061746820643d224d39352e343933203230392e323337632d392e34343720322e3936362d31372e3834352031302e3633372d32312e36322032312e3535322d2e34393720312e3538392d322e36373820312e3538392d332e32373220302d332e3237322d31302e32332d31312e3430352d31382e3237362d32312e35322d32312e3535322d312e3738342d2e3539382d312e3738342d322e37383220302d332e3337372031302e3131352d332e3331322031382e3137342d31312e3530362032312e35322d32312e3535322e3539342d312e36383920322e3737382d312e36383920332e323732203020332e3736382031302e3638392031312e3536332031382e3139352032312e36322032312e35353220312e3638372e35393520312e36383720322e373739203020332e3337375a222066696c6c3d2223666666222f3e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65723c656c6c697073652063783d223131332e323437222063793d223232302e363838222072783d2233382e373137222072793d2233382e373734222066696c6c3d2223374635353333222f3e3c656c6c697073652063783d223131332e323437222063793d223232302e363838222072783d2233382e373137222072793d2233382e373734222066696c6c3d2223374635353333222f3e3c656c6c697073652063783d2237302e303133222063793d223233362e383434222072783d2233382e373137222072793d2233382e373734222066696c6c3d2223374635353333222f3e3c7061746820643d226d32362e383235203138342e3234322e3837203232312e3536372039332e3336372035342e3333392d2e3837312d3232312e3536342d39332e3336362d35342e3334325a6d3133362e3433322d37382e3236322e383731203232312e3536382039332e3336372035342e3333382d2e3837312d3232312e3536342d39332e3336372d35342e3334325a222066696c6c3d2223334442353432222f3e3c656c6c697073652063783d223135362e383035222063793d223139382e373135222072783d2233382e373137222072793d2233382e373734222066696c6c3d2223374635353333222f3e3c656c6c697073652063783d223139382e313033222063793d223138392e363638222072783d2233382e373137222072793d2233382e373734222066696c6c3d2223374635353333222f3e455243313135353a2073657474696e6720617070726f76616c2073746174757320666f722073656c66455243313135353a206163636f756e747320616e6420696473206c656e677468206d69736d617463683c7061746820643d224d3136342e3437203332372e3234312032382e363235203430352e3736386c2d2e3837382d3232312e353531203133352e3834392d37382e3535392e383734203232312e3538335a222066696c6c3d2223334441413437222f3e3c7061746820643d226d3131382e303539203335342e3037372d34312e3130322032332e3734362d2e3837342d3232312e3535312034312e3130312d32332e3737382e383735203232312e3538335a222066696c6c3d2223334441413437222f3e3c7061746820643d226d32362e383235203138342e3234322e3837203232312e3536372039332e3336372035342e3333392d2e3837312d3232312e3536342d39332e3336362d35342e3334325a6d3133362e3433322d37382e3236322e383731203232312e3536382039332e3336372035342e3333382d2e3837312d3232312e3536342d39332e3336372d35342e3334325a222066696c6c3d2223334442353432222f3e3c7061746820643d226d3235362e383938203338312e3630392d3133352e3834362037382e3532372d2e3837372d3232312e353531203133352e3834392d37382e35362e383734203232312e3538345a222066696c6c3d2223364443423630222f3e3c7061746820643d226d3231302e343836203430382e3434352d34312e3130312032332e3734352d2e3837352d3232312e3535312034312e3130322d32332e3737382e383734203232312e3538345a222066696c6c3d2223334441413437222f3e3c7061746820643d226d3234302e393031203336342e3934392d3130342e3430372036302e3338372d2e3332332d3135372e343737203130342e3430382d36302e3335312e333232203135372e3434315a222066696c6c3d2223666666222f3e3c7061746820643d224d3139352e373839203236382e3032356332332e3133372d362e3731342033362e3837352031302e3633312033322e3330362033352e3233332d342e30322032312e3635322d32312e3335322034322e3834352d33392e3736392034392e3832312d31392e31373120372e32362d33352e3731372d322e3236382d33362e3239372d32332e3936362d2e3636352d32342e3932322031392e3431332d35342e3032312034332e37362d36312e3038385a222066696c6c3d2223343642393535222f3e3c7061746820643d226d3230362e343137203237352e3631352d32382e30382037332e353737732d32342e3536392d33352e3339372032382e30382d37332e3537375a6d2d32332e3032372036382e3336322031392e3536312d35302e3931367332332e3833312031372e3138392d31392e3536312035302e3931365a222066696c6c3d2223666666222f3ea2646970667358221220409327a28493a37e1ce83accae65d3ef58d92964eece3f826279358d4006686864736f6c63430007060033a264697066735822122036978c0eb1d9a57bacdc8b167f4fab5d6000c3bd13cf1a54f8fb8a0637bbc53864736f6c63430007060033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063e1c7392a14610030575b600080fd5b61003861003a565b005b60006040516100489061010a565b604051809103906000f080158015610064573d6000803e3d6000fd5b509050806100706100da565b6001600160a01b03166399a88ec46100866100f2565b836040518363ffffffff1660e01b81526004016100a4929190610117565b600060405180830381600087803b1580156100be57600080fd5b505af11580156100d2573d6000803e3d6000fd5b505050505050565b73fecb01359263c12aa9ed838f878a596f0064aa6e90565b73402c84de2ce49af88f5e2ef3710ff89bfed36cb690565b613e258061013283390190565b6001600160a01b039283168152911660208201526040019056fe608060405234801561001057600080fd5b50613e05806100206000396000f3fe608060405234801561001057600080fd5b50600436106101415760003560e01c80638da5cb5b116100b8578063a22cb4651161007c578063a22cb4651461028d578063b6f42085146102a0578063bf02d309146102b3578063e985e9c5146102d3578063f242432a146102e6578063f2fde38b146102f957610141565b80638da5cb5b1461022a57806391b7301f1461023f57806395d89b411461025f57806397e6e467146102675780639a9a18a21461027a57610141565b8063246c0d871161010a578063246c0d87146101ca5780632c12865b146101d25780632eb2c2d6146101e55780634e1273f4146101fa57806355234ec01461021a578063715018a61461022257610141565b8062fdd58e1461014657806301ffc9a71461016f57806306fdde031461018f5780630e89341c146101a45780631edb6be1146101b7575b600080fd5b610159610154366004612470565b61030c565b6040516101669190613065565b60405180910390f35b61018261017d36600461259c565b610371565b6040516101669190612d8b565b610197610394565b6040516101669190612d96565b6101976101b23660046125f0565b6103b9565b6101596101c536600461238c565b61047b565b6101596105dd565b6101976101e0366004612620565b610665565b6101f86101f3366004612285565b610680565b005b61020d6102083660046124e9565b6107df565b6040516101669190612d31565b6101596108ca565b6101f8610949565b6102326109f5565b6040516101669190612c2b565b61025261024d366004612470565b610a04565b6040516101669190613043565b610197610a7f565b6101596102753660046123d7565b610a9d565b6101f8610288366004612499565b610b1d565b6101f861029b366004612436565b610c6e565b6101596102ae36600461238c565b610d5d565b6102c66102c13660046124e9565b610f04565b6040516101669190612ce4565b6101826102e1366004612253565b610fbc565b6101f86102f436600461232a565b610fea565b6101f8610307366004612239565b6110f5565b60006001600160a01b03831661033d5760405162461bcd60e51b815260040161033490612e45565b60405180910390fd5b50600081815260fb602090815260408083206001600160a01b03861684529091529020546001600160801b03165b92915050565b6001600160e01b0319811660009081526097602052604090205460ff165b919050565b60408051808201909152600a8152692332b93a34b634bd32b960b11b60208201525b90565b606060006103c6836111f8565b905060006103d48483610665565b90506040518060400160405280601d81526020017f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152506104526104188661132d565b6104218761132d565b8461042b87611407565b60405160200161043e94939291906127e7565b60405160208183030381529060405261159b565b6040516020016104639291906127b8565b60405160208183030381529060405292505050919050565b6000806104866109f5565b6001600160a01b0316639bb4e35a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156104be57600080fd5b505afa1580156104d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f691906125d4565b6001600160801b0316905060005b83518110156105d5578184828151811061051a57fe5b602002602001015111156105cd576105ca6105c360fb600087858151811061053e57fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002060000160009054906101000a90046001600160801b03166001600160801b03166105bd858886815181106105a757fe5b60200260200101516116db90919063ffffffff16565b90611738565b8490611791565b92505b600101610504565b505092915050565b60006105e76109f5565b6001600160a01b031663c85951a16040518163ffffffff1660e01b815260040160206040518083038186803b15801561061f57600080fd5b505afa158015610633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065791906125d4565b6001600160801b0316905090565b606061067961067484846117e9565b611860565b9392505050565b81518351146106a15760405162461bcd60e51b815260040161033490612fba565b6001600160a01b0384166106c75760405162461bcd60e51b815260040161033490612ed9565b6106cf61189c565b6001600160a01b0316856001600160a01b031614806106f557506106f5856102e161189c565b6107115760405162461bcd60e51b815260040161033490612f1e565b600061071b61189c565b905061072b8187878787876118a0565b60005b845181101561077157610769878787848151811061074857fe5b602002602001015187858151811061075c57fe5b6020026020010151611953565b60010161072e565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516107c1929190612d44565b60405180910390a46107d7818787878787611a70565b505050505050565b606081518351146108215760405162461bcd60e51b81526004018080602001828103825260298152602001806139c56029913960400191505060405180910390fd5b600083516001600160401b038111801561083a57600080fd5b50604051908082528060200260200182016040528015610864578160200160208202803683370190505b50905060005b84518110156108c2576108a385828151811061088257fe5b602002602001015185838151811061089657fe5b602002602001015161030c565b8282815181106108af57fe5b602090810291909101015260010161086a565b509392505050565b60006108d46109f5565b6001600160a01b0316634a16607c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561090c57600080fd5b505afa158015610920573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109449190612608565b905090565b61095161189c565b6001600160a01b03166109626109f5565b6001600160a01b0316146109ab576040805162461bcd60e51b81526020600482018190526024820152600080516020613762833981519152604482015290519081900360640190fd5b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b6033546001600160a01b031690565b610a0c61213b565b6001600160a01b038316610a325760405162461bcd60e51b815260040161033490612e45565b50600081815260fb602090815260408083206001600160a01b03861684528252918290208251808401909352546001600160801b038082168452600160801b909104169082015292915050565b6040805180820190915260048152631191549560e21b602082015290565b6000610aa761189c565b6001600160a01b0316610ab86109f5565b6001600160a01b031614610b01576040805162461bcd60e51b81526020600482018190526024820152600080516020613762833981519152604482015290519081900360640190fd5b610b158484846001600160801b0316611b7e565b949350505050565b610b2561189c565b6001600160a01b0316610b366109f5565b6001600160a01b031614610b7f576040805162461bcd60e51b81526020600482018190526024820152600080516020613762833981519152604482015290519081900360640190fd5b600083815260fb602090815260408083206001600160a01b03881684529091529020546001600160801b031615610c0257604080516001808252818301909252600091602080830190803683370190505090508381600081518110610be057fe5b602002602001018181525050610c008582846001600160801b0316611ce8565b505b600083815260fb602090815260408083206001600160a01b038816845282529182902080546001600160801b03908116600160801b8683160217909155825180840190935260018352600360fc1b91830191909152610c68918691869190861690611d6a565b50505050565b816001600160a01b0316610c8061189c565b6001600160a01b03161415610cc65760405162461bcd60e51b815260040180806020018281038252602981526020018061399c6029913960400191505060405180910390fd5b8060ca6000610cd361189c565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610d1761189c565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600080610d686109f5565b6001600160a01b0316639bb4e35a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610da057600080fd5b505afa158015610db4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd891906125d4565b6001600160801b0316905060005b83518110156105d5576000848281518110610dfd57fe5b60200260200101518310610e2457848281518110610e1757fe5b6020026020010151610e26565b825b9050600060fb6000878581518110610e3a57fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002060000160109054906101000a90046001600160801b03166001600160801b031682039050610ef5610eee60fb6000898781518110610ead57fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038d16825290925290205483906001600160801b0316611738565b8690611791565b94505050806001019050610de6565b606082516001600160401b0381118015610f1d57600080fd5b50604051908082528060200260200182016040528015610f5757816020015b610f4461213b565b815260200190600190039081610f3c5790505b50905060005b8351811015610fb557610f96848281518110610f7557fe5b6020026020010151848381518110610f8957fe5b6020026020010151610a04565b828281518110610fa257fe5b6020908102919091010152600101610f5d565b5092915050565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205460ff1690565b6001600160a01b0384166110105760405162461bcd60e51b815260040161033490612ed9565b61101861189c565b6001600160a01b0316856001600160a01b0316148061103e575061103e856102e161189c565b61105a5760405162461bcd60e51b815260040161033490612e90565b600061106461189c565b905061108481878761107588611e17565b61107e88611e17565b876118a0565b61109086868686611953565b846001600160a01b0316866001600160a01b0316826001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6287876040516110df92919061306e565b60405180910390a46107d7818787878787611e5c565b6110fd61189c565b6001600160a01b031661110e6109f5565b6001600160a01b031614611157576040805162461bcd60e51b81526020600482018190526024820152600080516020613762833981519152604482015290519081900360640190fd5b6001600160a01b03811661119c5760405162461bcd60e51b81526004018080602001828103825260268152602001806131c16026913960400191505060405180910390fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b600073c1e088fc1323b20bcbee9bd1b9fc9546db5624c56001600160a01b0316639bb4e35a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561124757600080fd5b505afa15801561125b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127f91906125d4565b6001600160801b0316826001600160801b0316106113255773c1e088fc1323b20bcbee9bd1b9fc9546db5624c56001600160a01b0316639bb4e35a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156112e457600080fd5b505afa1580156112f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061131c91906125d4565b8203905061038f565b50600061038f565b60608161135257506040805180820190915260018152600360fc1b602082015261038f565b8160005b811561136a57600101600a82049150611356565b6000816001600160401b038111801561138257600080fd5b506040519080825280601f01601f1916602001820160405280156113ad576020820181803683370190505b50859350905060001982015b83156113fe57600a840660300160f81b828280600190039350815181106113dc57fe5b60200101906001600160f81b031916908160001a905350600a840493506113b9565b50949350505050565b6060600061141d836001600160801b031661132d565b90505b6007815110156114a457806040516020018080600360fc1b81525060010182805190602001908083835b602083106114695780518252601f19909201916020918201910161144a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040529050611420565b60006114b68260006006855103611f2d565b905060006114cd8360068551036004865103611f2d565b905081816040516020018083805190602001908083835b602083106115035780518252601f1990920191602091820191016114e4565b6001836020036101000a03801982511681845116808217855250505050505090500180601760f91b81525060010182805190602001908083835b6020831061155c5780518252601f19909201916020918201910161153d565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529350505050919050565b60608151600014156115bc575060408051602081019091526000815261038f565b6000604051806060016040528060408152602001613701604091399050600060038451600201816115e957fe5b046004026001600160401b038111801561160257600080fd5b506040519080825280601f01601f19166020018201604052801561162d576020820181803683370190505b509050600182016020820185865187015b80821015611699576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f811685015184535060018301925061163e565b50506003865106600181146116b557600281146116c8576116d0565b603d6001830353603d60028303536116d0565b603d60018303535b509195945050505050565b600082821115611732576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000826117475750600061036b565b8282028284828161175457fe5b04146106795760405162461bcd60e51b81526004018080602001828103825260218152602001806137416021913960400191505060405180910390fd5b600082820183811015610679576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b6060604051806101a0016040528061016881526020016139ee61016891396118118484611fd0565b604051806102a0016040528061027a8152602001613b5661027a913961183685611407565b6040516020016118499493929190612a54565b604051602081830303815290604052905092915050565b60606118768260405160200161043e919061279c565b6040516020016118869190612be6565b6040516020818303038152906040529050919050565b3390565b60006118aa6109f5565b6001600160a01b0316639bb4e35a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118e257600080fd5b505afa1580156118f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191a91906125d4565b6001600160801b031690506001600160a01b0386161561193f5761193f868583611ce8565b61194a858583611ce8565b50505050505050565b806001600160a01b038516156119f157600083815260fb602090815260408083206001600160a01b03891684529091529020546001600160801b0316828110156119af5760405162461bcd60e51b815260040161033490612f70565b600084815260fb602090815260408083206001600160a01b038a168452909152902080546001600160801b031916918390036001600160801b03169190911790555b600083815260fb602090815260408083206001600160a01b0388168452909152902054611a27906001600160801b0316826120d1565b600093845260fb602090815260408086206001600160a01b039790971686529590529390922080546001600160801b0319166001600160801b0390941693909317909255505050565b611a82846001600160a01b0316612135565b156107d75760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190611abb9089908990889088908890600401612c3f565b602060405180830381600087803b158015611ad557600080fd5b505af1925050508015611b05575060408051601f3d908101601f19168201909252611b02918101906125b8565b60015b611b4e57611b116130ee565b80611b1c5750611b36565b8060405162461bcd60e51b81526004016103349190612d96565b60405162461bcd60e51b815260040161033490612da9565b6001600160e01b0319811663bc197c8160e01b1461194a5760405162461bcd60e51b815260040161033490612dfd565b6000805b8351811015611ca7576000848281518110611b9957fe5b60200260200101518410611bc057848281518110611bb357fe5b6020026020010151611bc2565b835b9050600060fb6000878581518110611bd657fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038b168252909252902054600160801b90046001600160801b0316820390508015611c9d57611c3e611c3760fb6000898781518110610ead57fe5b8590611791565b93508160fb6000888681518110611c5157fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038c168252909252902080546001600160801b03928316600160801b0292169190911790555b5050600101611b82565b507f96f98c54750e4481bfa3aaac1e279e22f034f6bb3fbe5a79cb28d63ac2db367c8382604051611cd9929190612d69565b60405180910390a19392505050565b6000611cf5848484611b7e565b90508015610c6857611d056109f5565b6001600160a01b031663d47aee5985836040518363ffffffff1660e01b8152600401611d32929190612ccb565b600060405180830381600087803b158015611d4c57600080fd5b505af1158015611d60573d6000803e3d6000fd5b5050505050505050565b6001600160a01b038416611d905760405162461bcd60e51b815260040161033490613002565b6000611d9a61189c565b9050611da96000868686611953565b846001600160a01b031660006001600160a01b0316826001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628787604051611df992919061306e565b60405180910390a4611e1081600087878787611e5c565b5050505050565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110611e4b57fe5b602090810291909101015292915050565b611e6e846001600160a01b0316612135565b156107d75760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190611ea79089908990889088908890600401612c91565b602060405180830381600087803b158015611ec157600080fd5b505af1925050508015611ef1575060408051601f3d908101601f19168201909252611eee918101906125b8565b60015b611efd57611b116130ee565b6001600160e01b0319811663f23a6e6160e01b1461194a5760405162461bcd60e51b815260040161033490612dfd565b60608360008484036001600160401b0381118015611f4a57600080fd5b506040519080825280601f01601f191660200182016040528015611f75576020820181803683370190505b509050845b84811015611fc657828181518110611f8e57fe5b602001015160f81c60f81b8287830381518110611fa757fe5b60200101906001600160f81b031916908160001a905350600101611f7a565b5095945050505050565b604051639c45a1d560e01b815260609060009073c1e088fc1323b20bcbee9bd1b9fc9546db5624c590639c45a1d59061200d908790600401613051565b60206040518083038186803b15801561202557600080fd5b505afa158015612039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205d9190612608565b9050600060405180610540016040528061051a81526020016131e761051a913990508115610b15576000846001600160801b0316116120ab57604051806020016040528060008152506120c8565b60405180610240016040528061021a815260200161378261021a91395b95945050505050565b60008282016001600160801b038085169082161015610679576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b3b151590565b604080518082019091526000808252602082015290565b80356001600160a01b038116811461038f57600080fd5b600082601f830112612179578081fd5b8135602061218e6121898361309f565b61307c565b82815281810190858301838502870184018810156121aa578586fd5b855b858110156121c8578135845292840192908401906001016121ac565b5090979650505050505050565b600082601f8301126121e5578081fd5b81356001600160401b038111156121f857fe5b61220b601f8201601f191660200161307c565b81815284602083860101111561221f578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121561224a578081fd5b61067982612152565b60008060408385031215612265578081fd5b61226e83612152565b915061227c60208401612152565b90509250929050565b600080600080600060a0868803121561229c578081fd5b6122a586612152565b94506122b360208701612152565b935060408601356001600160401b03808211156122ce578283fd5b6122da89838a01612169565b945060608801359150808211156122ef578283fd5b6122fb89838a01612169565b93506080880135915080821115612310578283fd5b5061231d888289016121d5565b9150509295509295909350565b600080600080600060a08688031215612341578081fd5b61234a86612152565b945061235860208701612152565b9350604086013592506060860135915060808601356001600160401b03811115612380578182fd5b61231d888289016121d5565b6000806040838503121561239e578182fd5b6123a783612152565b915060208301356001600160401b038111156123c1578182fd5b6123cd85828601612169565b9150509250929050565b6000806000606084860312156123eb578283fd5b6123f484612152565b925060208401356001600160401b0381111561240e578283fd5b61241a86828701612169565b925050604084013561242b816131ab565b809150509250925092565b60008060408385031215612448578182fd5b61245183612152565b915060208301358015158114612465578182fd5b809150509250929050565b60008060408385031215612482578182fd5b61248b83612152565b946020939093013593505050565b600080600080608085870312156124ae578182fd5b6124b785612152565b93506020850135925060408501356124ce816131ab565b915060608501356124de816131ab565b939692955090935050565b600080604083850312156124fb578182fd5b82356001600160401b0380821115612511578384fd5b818501915085601f830112612524578384fd5b813560206125346121898361309f565b82815281810190858301838502870184018b1015612550578889fd5b8896505b848710156125795761256581612152565b835260019690960195918301918301612554565b509650508601359250508082111561258f578283fd5b506123cd85828601612169565b6000602082840312156125ad578081fd5b813561067981613192565b6000602082840312156125c9578081fd5b815161067981613192565b6000602082840312156125e5578081fd5b8151610679816131ab565b600060208284031215612601578081fd5b5035919050565b600060208284031215612619578081fd5b5051919050565b60008060408385031215612632578182fd5b823591506020830135612465816131ab565b6000815180845260208085019450808401835b8381101561267357815187529582019590820190600101612657565b509495945050505050565b600081518084526126968160208601602086016130bc565b601f01601f19169290920160200192915050565b600081516126bc8185602086016130bc565b9290920192915050565b63207d5d7d60e01b815260040190565b7f204250462052656d61696e696e67203c2f747370616e3e3c2f746578743e3c2f81526339bb339f60e11b602082015260240190565b7f222c202261747472696275746573223a205b7b202274726169745f747970652281527f3a20224250462052656d61696e696e67222c22646973706c61795f747970652260208201527f3a2022626f6f73745f6e756d626572222c2276616c7565223a200000000000006040820152605a0190565b80516001600160801b03908116835260209182015116910152565b600082516127ae8184602087016130bc565b9190910192915050565b600083516127ca8184602088016130bc565b8351908301906127de8183602088016130bc565b01949350505050565b7603d913730b6b2911d10112332b93a34b634bd32b910169604d1b8152845160009061281a816017850160208a016130bc565b7f222c202265787465726e616c5f75726c223a202268747470733a2f2f666572746017918401918201526b2e6265616e2e6d6f6e65792f60a01b6037820152855161286c816043840160208a016130bc565b67017343a36b61116160c51b604392909101918201527f226465736372697074696f6e223a2022412074727573747920636f6e73746974604b8201527f75656e74206f6620616e79204661726d65727320746f6f6c626f782c20455243606b8201527f2d31313535204645525420686173206265656e206b6e6f776e20746f20737075608b8201527f72206e65772067726f777468206f6e207365656d696e676c792064656164206660ab8201527f61726d732e204f6e63652070757263686173656420616e64206465706c6f796560cb8201527f6420696e746f2066657274696c652067726f756e64206279204661726d65727360eb8201527f2c2046657274696c697a65722067656e657261746573206e6577205370726f7561010b8201527f74733a20667574757265204265616e732079657420746f20626520726570616961012b8201527f64206279204265616e7374616c6b20696e2065786368616e676520666f72206461014b8201527f6f696e672074686520776f726b206f66205265706c616e74696e67207468652061016b82015275383937ba37b1b7b6171116101134b6b0b3b2911d101160511b61018b820152612a49612a44612a3e612a396101a18501896126aa565b61270c565b866126aa565b6126c6565b979650505050505050565b60007f3c7376672077696474683d2232393422206865696768743d223531322220766982527f6577426f783d223020302032393420353132222066696c6c3d226e6f6e65222060208301527f786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737660408301527f672220786d6c6e733a786c696e6b3d22687474703a2f2f7777772e77332e6f7260608301526d3397989c9c9c97bc3634b735911f60911b60808301528551612b1581608e850160208a016130bc565b855190830190612b2c81608e840160208a016130bc565b8551910190612b4281608e8401602089016130bc565b7f3c7465787420666f6e742d66616d696c793d2273616e732d7365726966222066608e92909101918201527f6f6e742d73697a653d2232302220783d2232302220793d22343930222066696c60ae8201527f6c3d22626c61636b22203e3c747370616e2064793d22302220783d223230223e60ce8201528351612bcc8160ee8401602088016130bc565b612bda60ee828401016126d6565b98975050505050505050565b60007f646174613a696d6167652f7376672b786d6c3b6261736536342c00000000000082528251612c1e81601a8501602087016130bc565b91909101601a0192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0386811682528516602082015260a060408201819052600090612c6b90830186612644565b8281036060840152612c7d8186612644565b90508281036080840152612bda818561267e565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090612a499083018461267e565b6001600160a01b03929092168252602082015260400190565b602080825282518282018190526000919060409081850190868401855b82811015612d2457612d14848351612781565b9284019290850190600101612d01565b5091979650505050505050565b6000602082526106796020830184612644565b600060408252612d576040830185612644565b82810360208401526120c88185612644565b600060408252612d7c6040830185612644565b90508260208301529392505050565b901515815260200190565b600060208252610679602083018461267e565b60208082526034908201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356040820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b606082015260800190565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b6020808252602b908201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60408201526a65726f206164647265737360a81b606082015260800190565b60208082526029908201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260408201526808185c1c1c9bdd995960ba1b606082015260800190565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526032908201527f455243313135353a207472616e736665722063616c6c6572206973206e6f74206040820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b6040810161036b8284612781565b6001600160801b0391909116815260200190565b90815260200190565b918252602082015260400190565b6040518181016001600160401b038111828210171561309757fe5b604052919050565b60006001600160401b038211156130b257fe5b5060209081020190565b60005b838110156130d75781810151838201526020016130bf565b83811115610c685750506000910152565b60e01c90565b600060443d10156130fe576103b6565b600481823e6308c379a061311282516130e8565b1461311c576103b6565b6040513d600319016004823e80513d6001600160401b03816024840111818411171561314b57505050506103b6565b8284019250825191508082111561316557505050506103b6565b503d8301602082840101111561317d575050506103b6565b601f01601f1916810160200160405291505090565b6001600160e01b0319811681146131a857600080fd5b50565b6001600160801b03811681146131a857600080fdfe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573733c7061746820643d224d37362e363334203136322e393135203231322038342e3133336c34342e3033342037352e3930392d3133352e3834322037382e3534342d34332e3535372d37352e3637315a222066696c6c3d2223383144363732222f3e3c7061746820643d226d3132342e393636203133342e39372034302e3632342d32342e3030312034342e3033312037352e3930362d34312e3039382032332e3736352d34332e3535372d37352e36375a222066696c6c3d2223343642393535222f3e3c7061746820643d226d3231322e3132352034372e3931382d2e3131362033362e3232382d3133352e3339342037382e3736362e3131362d33362e313763302d322e3033322d312e33392d342e3431332d332e31332d352e3435372d2e38372d2e3532332d312e36382d2e3532332d322e3236312d2e3233336c3133352e3339342d37382e373636632e35382d2e33343920312e3333322d2e323920322e3230332e32333320312e3733362e39383920332e31383820332e34323520332e31383820352e345a222066696c6c3d2223364443423630222f3e3c7061746820643d226d3136352e3731332037342e3735322d2e3131362033362e3232382d34302e36352032332e3938382e3131362d33362e313763302d322e3033322d312e33392d342e3431332d332e3132392d352e3435372d2e3837322d2e3532332d312e3638312d2e3532332d322e3236322d2e3233326c34302e36352d32332e393839632e35382d2e33343920312e3333322d2e323920322e3230332e32333320312e3733392e39383620332e31383820332e34323520332e31383820352e345a222066696c6c3d2223343241383443222f3e3c7061746820643d224d37332e353739203132312e32393863312e37333920312e30303520332e31363220332e34323220332e31353920352e3432356c2d2e3130342033362e3139332034332e3535372037352e3636372d39332e3336362d35342e3333392034332e3532312d32352e3031382e3130332d33362e313431632e3030342d3220312e33392d322e37393520332e31332d312e3738375a222066696c6c3d2223324339413243222f3e3c7061746820643d224d3130372e383739203232362e3736362033362e3632203138352e3536356c33352e3734322d32302e3339352031312e3432382031392e3739342032342e3038392034312e3830325a222066696c6c3d2223364443423630222f3e3c7061746820643d226d38312e333438203138302e3733312d34342e37323820342e3833342033352e3734322d32302e33393520382e3938362031352e3536315a222066696c6c3d2223383144363732222f3e20203c7061746820643d224d39352e343933203230392e323337632d392e34343720322e3936362d31372e3834352031302e3633372d32312e36322032312e3535322d2e34393720312e3538392d322e36373820312e3538392d332e32373220302d332e3237322d31302e32332d31312e3430352d31382e3237362d32312e35322d32312e3535322d312e3738342d2e3539382d312e3738342d322e37383220302d332e3337372031302e3131352d332e3331322031382e3137342d31312e3530362032312e35322d32312e3535322e3539342d312e36383920322e3737382d312e36383920332e323732203020332e3736382031302e3638392031312e3536332031382e3139352032312e36322032312e35353220312e3638372e35393520312e36383720322e373739203020332e3337375a222066696c6c3d2223666666222f3e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65723c656c6c697073652063783d223131332e323437222063793d223232302e363838222072783d2233382e373137222072793d2233382e373734222066696c6c3d2223374635353333222f3e3c656c6c697073652063783d223131332e323437222063793d223232302e363838222072783d2233382e373137222072793d2233382e373734222066696c6c3d2223374635353333222f3e3c656c6c697073652063783d2237302e303133222063793d223233362e383434222072783d2233382e373137222072793d2233382e373734222066696c6c3d2223374635353333222f3e3c7061746820643d226d32362e383235203138342e3234322e3837203232312e3536372039332e3336372035342e3333392d2e3837312d3232312e3536342d39332e3336362d35342e3334325a6d3133362e3433322d37382e3236322e383731203232312e3536382039332e3336372035342e3333382d2e3837312d3232312e3536342d39332e3336372d35342e3334325a222066696c6c3d2223334442353432222f3e3c656c6c697073652063783d223135362e383035222063793d223139382e373135222072783d2233382e373137222072793d2233382e373734222066696c6c3d2223374635353333222f3e3c656c6c697073652063783d223139382e313033222063793d223138392e363638222072783d2233382e373137222072793d2233382e373734222066696c6c3d2223374635353333222f3e455243313135353a2073657474696e6720617070726f76616c2073746174757320666f722073656c66455243313135353a206163636f756e747320616e6420696473206c656e677468206d69736d617463683c7061746820643d224d3136342e3437203332372e3234312032382e363235203430352e3736386c2d2e3837382d3232312e353531203133352e3834392d37382e3535392e383734203232312e3538335a222066696c6c3d2223334441413437222f3e3c7061746820643d226d3131382e303539203335342e3037372d34312e3130322032332e3734362d2e3837342d3232312e3535312034312e3130312d32332e3737382e383735203232312e3538335a222066696c6c3d2223334441413437222f3e3c7061746820643d226d32362e383235203138342e3234322e3837203232312e3536372039332e3336372035342e3333392d2e3837312d3232312e3536342d39332e3336362d35342e3334325a6d3133362e3433322d37382e3236322e383731203232312e3536382039332e3336372035342e3333382d2e3837312d3232312e3536342d39332e3336372d35342e3334325a222066696c6c3d2223334442353432222f3e3c7061746820643d226d3235362e383938203338312e3630392d3133352e3834362037382e3532372d2e3837372d3232312e353531203133352e3834392d37382e35362e383734203232312e3538345a222066696c6c3d2223364443423630222f3e3c7061746820643d226d3231302e343836203430382e3434352d34312e3130312032332e3734352d2e3837352d3232312e3535312034312e3130322d32332e3737382e383734203232312e3538345a222066696c6c3d2223334441413437222f3e3c7061746820643d226d3234302e393031203336342e3934392d3130342e3430372036302e3338372d2e3332332d3135372e343737203130342e3430382d36302e3335312e333232203135372e3434315a222066696c6c3d2223666666222f3e3c7061746820643d224d3139352e373839203236382e3032356332332e3133372d362e3731342033362e3837352031302e3633312033322e3330362033352e3233332d342e30322032312e3635322d32312e3335322034322e3834352d33392e3736392034392e3832312d31392e31373120372e32362d33352e3731372d322e3236382d33362e3239372d32332e3936362d2e3636352d32342e3932322031392e3431332d35342e3032312034332e37362d36312e3038385a222066696c6c3d2223343642393535222f3e3c7061746820643d226d3230362e343137203237352e3631352d32382e30382037332e353737732d32342e3536392d33352e3339372032382e30382d37332e3537375a6d2d32332e3032372036382e3336322031392e3536312d35302e3931367332332e3833312031372e3138392d31392e3536312035302e3931365a222066696c6c3d2223666666222f3ea2646970667358221220409327a28493a37e1ce83accae65d3ef58d92964eece3f826279358d4006686864736f6c63430007060033a264697066735822122036978c0eb1d9a57bacdc8b167f4fab5d6000c3bd13cf1a54f8fb8a0637bbc53864736f6c63430007060033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.