Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Latest 10 from a total of 10 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Redeem USDC | 23415367 | 56 days ago | IN | 0 ETH | 0.00004461 | ||||
| Redeem USDC | 23349557 | 66 days ago | IN | 0 ETH | 0.00024048 | ||||
| Redeem USDC | 23320787 | 70 days ago | IN | 0 ETH | 0.00011272 | ||||
| Redeem USDC | 23289921 | 74 days ago | IN | 0 ETH | 0.00034772 | ||||
| Redeem USDC | 23279125 | 75 days ago | IN | 0 ETH | 0.00050802 | ||||
| Redeem USDC | 23248948 | 80 days ago | IN | 0 ETH | 0.0005301 | ||||
| Redeem USDC | 23231016 | 82 days ago | IN | 0 ETH | 0.00052893 | ||||
| Redeem USDC | 23185512 | 88 days ago | IN | 0 ETH | 0.00009756 | ||||
| Redeem USDC | 23185261 | 88 days ago | IN | 0 ETH | 0.00016179 | ||||
| Redeem USDC | 23184931 | 89 days ago | IN | 0 ETH | 0.000924 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
OCR_Instant
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
No with 200 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "../../ZivoeLocker.sol";
import "../../../lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol";
// ERC-4626 Vault interface for zVLT
interface IERC4626 {
function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
function convertToAssets(uint256 shares) external view returns (uint256 assets);
}
// Interface for zSTT burning
interface IERC20Burnable_OCR {
function burn(uint256 amount) external;
}
// Interface for ZivoeGlobals
interface IZivoeGlobals_OCR {
function ZVL() external view returns (address);
}
// AAVE V3 Pool interface
interface IPool_OCR {
function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;
function withdraw(address asset, uint256 amount, address to) external returns (uint256);
}
/// @notice OCR stands for "On-Chain Redemption".
/// This locker is responsible for handling redemptions of zVLT for stablecoins.
/// Integrated with AAVE V3 USDC pool for yield generation.
contract OCR_Instant is ZivoeLocker, ReentrancyGuard {
using SafeERC20 for IERC20;
// ---------------------
// State Variables
// ---------------------
address public immutable GBL; /// @dev The ZivoeGlobals contract.
address public immutable USDC; /// @dev The USDC token contract.
address public immutable zVLT; /// @dev The zVLT ERC-4626 vault token contract.
address public immutable zSTT; /// @dev The zSTT underlying asset token contract.
address public immutable AAVE_V3_POOL; /// @dev The AAVE V3 Pool contract.
address public immutable aUSDC; /// @dev The AAVE V3 USDC aToken contract.
uint256 public redemptionFeeBIPS; /// @dev Fee for redemptions (in BIPS).
uint256 private constant BIPS = 10000;
// -----------------
// Constructor
// -----------------
/// @notice Initializes the OCR_Instant contract.
/// @param DAO The administrator of this contract (intended to be ZivoeDAO).
/// @param _USDC The USDC token contract.
/// @param _GBL The ZivoeGlobals contract.
/// @param _zVLT The zVLT ERC-4626 vault token contract.
/// @param _zSTT The zSTT underlying asset token contract.
/// @param _AAVE_V3_POOL The AAVE V3 Pool contract.
/// @param _aUSDC The AAVE V3 USDC aToken contract.
/// @param _redemptionFeeBIPS Fee for redemptions (in BIPS).
constructor(
address DAO,
address _USDC,
address _GBL,
address _zVLT,
address _zSTT,
address _AAVE_V3_POOL,
address _aUSDC,
uint16 _redemptionFeeBIPS
) {
require(_redemptionFeeBIPS <= 1000, "OCR_Instant::constructor() _redemptionFeeBIPS > 1000");
transferOwnershipAndLock(DAO);
USDC = _USDC;
GBL = _GBL;
zVLT = _zVLT;
zSTT = _zSTT;
AAVE_V3_POOL = _AAVE_V3_POOL;
aUSDC = _aUSDC;
redemptionFeeBIPS = _redemptionFeeBIPS;
}
// ------------
// Events
// ------------
/// @notice Emitted during updateRedemptionFee().
/// @param oldFee The old value of redemptionFeeBIPS.
/// @param newFee The new value of redemptionFeeBIPS.
event UpdatedRedemptionFeeBIPS(uint256 oldFee, uint256 newFee);
/// @notice Emitted when USDC is deposited to AAVE V3.
/// @param amount The amount of USDC deposited.
/// @param aTokenBalance The resulting aToken balance.
event USDCDepositedToAAVE(uint256 amount, uint256 aTokenBalance);
/// @notice Emitted when USDC is withdrawn from AAVE V3.
/// @param amount The amount of USDC withdrawn.
/// @param aTokenBalance The resulting aToken balance.
event USDCWithdrawnFromAAVE(uint256 amount, uint256 aTokenBalance);
/// @notice Emitted when zVLT tokens are burned for USDC redemption.
/// @param user The user burning zVLT tokens.
/// @param zVLTBurned The amount of zVLT tokens burned.
/// @param USDCRedeemed The amount of USDC sent to user.
/// @param fee The fee taken.
event zVLTBurnedForUSDC(address indexed user, uint256 zVLTBurned, uint256 USDCRedeemed, uint256 fee);
// ---------------
// Functions
// ---------------
/// @notice Permission for owner to call pushToLocker().
function canPush() public override pure returns (bool) { return true; }
/// @notice Permission for owner to call pullFromLocker().
function canPull() public override pure returns (bool) { return true; }
/// @notice Permission for owner to call pullFromLockerPartial().
function canPullPartial() public override pure returns (bool) { return true; }
/// @notice This pulls capital from the DAO and deposits it into AAVE V3 USDC pool.
/// @param asset The asset to pull from the DAO.
/// @param amount The amount of asset to pull from the DAO.
/// @param data Accompanying transaction data.
function pushToLocker(
address asset, uint256 amount, bytes calldata data
) external override onlyOwner nonReentrant {
require(asset == USDC, "OCR_Instant::pushToLocker() asset != USDC");
// Transfer USDC from DAO to this contract
IERC20(asset).safeTransferFrom(owner(), address(this), amount);
// Approve AAVE V3 Pool to spend USDC
IERC20(asset).safeApprove(AAVE_V3_POOL, amount);
// Deposit USDC into AAVE V3 pool
IPool_OCR(AAVE_V3_POOL).supply(asset, amount, address(this), 0);
emit USDCDepositedToAAVE(amount, IERC20(aUSDC).balanceOf(address(this)));
}
/// @notice Migrates entire ERC20 balance from locker to owner(), withdrawing from AAVE V3 if needed.
/// @param asset The asset to migrate.
/// @param data Accompanying transaction data.
function pullFromLocker(address asset, bytes calldata data) external override onlyOwner nonReentrant {
require(asset == aUSDC, "OCR_Instant::pullFromLocker() asset != aUSDC");
// Withdraw all USDC from AAVE V3 pool
uint256 aTokenBalance = IERC20(aUSDC).balanceOf(address(this));
IPool_OCR(AAVE_V3_POOL).withdraw(USDC, aTokenBalance, address(this));
emit USDCWithdrawnFromAAVE(IERC20(USDC).balanceOf(address(this)), 0);
IERC20(USDC).safeTransfer(owner(), IERC20(USDC).balanceOf(address(this)));
}
/// @notice Migrates specific amount of ERC20 from locker to owner(), withdrawing from AAVE V3 if needed.
/// @param asset The asset to migrate.
/// @param amount The amount of "asset" to migrate.
/// @param data Accompanying transaction data.
function pullFromLockerPartial(
address asset, uint256 amount, bytes calldata data
) external override onlyOwner nonReentrant {
require(asset == aUSDC, "OCR_Instant::pullFromLockerPartial() asset != aUSDC");
// Withdraw USDC from AAVE V3 pool for the requested aUSDC amount
IPool_OCR(AAVE_V3_POOL).withdraw(USDC, amount, address(this));
emit USDCWithdrawnFromAAVE(amount, IERC20(aUSDC).balanceOf(address(this)));
// Transfer all USDC in the locker to the owner
IERC20(USDC).safeTransfer(owner(), IERC20(USDC).balanceOf(address(this)));
}
/// @notice Helper view function to determine how much USDC a given amount of zVLT will redeem for.
/// @param zVLTAmount The amount of zVLT tokens to calculate redemption for.
/// @return usdcAmount The amount of USDC that would be received after fees.
/// @return fee The fee amount that would be taken.
function calculateRedemptionAmount(uint256 zVLTAmount) external view returns (uint256 usdcAmount, uint256 fee) {
require(zVLTAmount > 0, "OCR_Instant::calculateRedemptionAmount() zVLTAmount == 0");
// Calculate how much zSTT would be received from unwrapping zVLT
uint256 zSTTReceived = IERC4626(zVLT).convertToAssets(zVLTAmount);
// Calculate fee based on zSTT amount (same logic as redeemUSDC)
fee = ((zSTTReceived * redemptionFeeBIPS) / BIPS) / 10**12;
// Calculate net USDC amount after fees
usdcAmount = zSTTReceived / 10**12 - fee;
return (usdcAmount, fee);
}
/// @notice Allows users to burn their zVLT tokens to receive USDC.
/// @param zVLTAmount The amount of zVLT tokens to burn.
function redeemUSDC(uint256 zVLTAmount) external nonReentrant {
require(zVLTAmount > 0, "OCR_Instant::redeemUSDC() zVLTAmount == 0");
// Transfer zVLT tokens from user to this contract
IERC20(zVLT).safeTransferFrom(_msgSender(), address(this), zVLTAmount);
// Unwrap zVLT to get zSTT (underlying asset)
uint256 zSTTReceived = IERC4626(zVLT).redeem(zVLTAmount, address(this), address(this));
// Burn zSTT
IERC20Burnable_OCR(zSTT).burn(zSTTReceived);
// Calculate fee
uint256 fee = ((zSTTReceived * redemptionFeeBIPS) / BIPS) / 10**12;
uint256 netAmount = zSTTReceived / 10**12 - fee;
// Revert if aUSDC balance is less than zSTTReceived
uint256 aUSDCBalance = IERC20(aUSDC).balanceOf(address(this));
require(aUSDCBalance >= zSTTReceived / 10**12 - fee, "OCR_Instant::redeemUSDC() aUSDCBalance < zSTTReceived / 10**12 - fee");
// Calculate how much USDC to provide (1:1 ratio with zSTT burned, decimal precision rounded down 10**12)
IPool_OCR(AAVE_V3_POOL).withdraw(USDC, netAmount, address(this));
// Transfer USDC to user
IERC20(USDC).safeTransfer(_msgSender(), netAmount);
emit zVLTBurnedForUSDC(_msgSender(), zVLTAmount, netAmount, fee);
}
/// @notice Updates the state variable "redemptionFeeBIPS".
/// @param _redemptionFeeBIPS The new value for redemptionFeeBIPS (in BIPS).
function updateRedemptionFeeBIPS(uint256 _redemptionFeeBIPS) external {
require(
_msgSender() == IZivoeGlobals_OCR(GBL).ZVL(),
"OCR_Instant::updateRedemptionFeeBIPS() _msgSender() != ZVL()"
);
require(
_redemptionFeeBIPS <= 1000, "OCR_Instant::updateRedemptionFeeBIPS() _redemptionFeeBIPS > 1000"
);
emit UpdatedRedemptionFeeBIPS(redemptionFeeBIPS, _redemptionFeeBIPS);
redemptionFeeBIPS = _redemptionFeeBIPS;
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "./libraries/OwnableLocked.sol";
import "../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "../lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
import "../lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol";
import "../lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol";
import "../lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol";
import "../lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol";
/// @notice This contract standardizes communication between the DAO and lockers.
abstract contract ZivoeLocker is OwnableLocked, ERC1155Holder, ERC721Holder {
using SafeERC20 for IERC20;
// -----------------
// Constructor
// -----------------
/// @notice Initializes the ZivoeLocker contract.
constructor() {}
// ---------------
// Functions
// ---------------
/// @notice Permission for calling pushToLocker().
function canPush() public virtual view returns (bool) { return false; }
/// @notice Permission for calling pullFromLocker().
function canPull() public virtual view returns (bool) { return false; }
/// @notice Permission for calling pullFromLockerPartial().
function canPullPartial() public virtual view returns (bool) { return false; }
/// @notice Permission for calling pushToLockerMulti().
function canPushMulti() public virtual view returns (bool) { return false; }
/// @notice Permission for calling pullFromLockerMulti().
function canPullMulti() public virtual view returns (bool) { return false; }
/// @notice Permission for calling pullFromLockerMultiPartial().
function canPullMultiPartial() public virtual view returns (bool) { return false; }
/// @notice Permission for calling pushToLockerERC721().
function canPushERC721() public virtual view returns (bool) { return false; }
/// @notice Permission for calling pullFromLockerERC721().
function canPullERC721() public virtual view returns (bool) { return false; }
/// @notice Permission for calling pushToLockerMultiERC721().
function canPushMultiERC721() public virtual view returns (bool) { return false; }
/// @notice Permission for calling pullFromLockerMultiERC721().
function canPullMultiERC721() public virtual view returns (bool) { return false; }
/// @notice Permission for calling pushToLockerERC1155().
function canPushERC1155() public virtual view returns (bool) { return false; }
/// @notice Permission for calling pullFromLockerERC1155().
function canPullERC1155() public virtual view returns (bool) { return false; }
/// @notice Migrates specific amount of ERC20 from owner() to locker.
/// @param asset The asset to migrate.
/// @param amount The amount of "asset" to migrate.
/// @param data Accompanying transaction data.
function pushToLocker(address asset, uint256 amount, bytes calldata data) external virtual onlyOwner {
require(canPush(), "ZivoeLocker::pushToLocker() !canPush()");
IERC20(asset).safeTransferFrom(owner(), address(this), amount);
}
/// @notice Migrates entire ERC20 balance from locker to owner().
/// @param asset The asset to migrate.
/// @param data Accompanying transaction data.
function pullFromLocker(address asset, bytes calldata data) external virtual onlyOwner {
require(canPull(), "ZivoeLocker::pullFromLocker() !canPull()");
IERC20(asset).safeTransfer(owner(), IERC20(asset).balanceOf(address(this)));
}
/// @notice Migrates specific amount of ERC20 from locker to owner().
/// @param asset The asset to migrate.
/// @param amount The amount of "asset" to migrate.
/// @param data Accompanying transaction data.
function pullFromLockerPartial(address asset, uint256 amount, bytes calldata data) external virtual onlyOwner {
require(canPullPartial(), "ZivoeLocker::pullFromLockerPartial() !canPullPartial()");
IERC20(asset).safeTransfer(owner(), amount);
}
/// @notice Migrates specific amounts of ERC20s from owner() to locker.
/// @param assets The assets to migrate.
/// @param amounts The amounts of "assets" to migrate, corresponds to "assets" by position in array.
/// @param data Accompanying transaction data.
function pushToLockerMulti(
address[] calldata assets, uint256[] calldata amounts, bytes[] calldata data
) external virtual onlyOwner {
require(canPushMulti(), "ZivoeLocker::pushToLockerMulti() !canPushMulti()");
for (uint256 i = 0; i < assets.length; i++) {
IERC20(assets[i]).safeTransferFrom(owner(), address(this), amounts[i]);
}
}
/// @notice Migrates full amount of ERC20s from locker to owner().
/// @param assets The assets to migrate.
/// @param data Accompanying transaction data.
function pullFromLockerMulti(address[] calldata assets, bytes[] calldata data) external virtual onlyOwner {
require(canPullMulti(), "ZivoeLocker::pullFromLockerMulti() !canPullMulti()");
for (uint256 i = 0; i < assets.length; i++) {
IERC20(assets[i]).safeTransfer(owner(), IERC20(assets[i]).balanceOf(address(this)));
}
}
/// @notice Migrates specific amounts of ERC20s from locker to owner().
/// @param assets The assets to migrate.
/// @param amounts The amounts of "assets" to migrate, corresponds to "assets" by position in array.
/// @param data Accompanying transaction data.
function pullFromLockerMultiPartial(
address[] calldata assets, uint256[] calldata amounts, bytes[] calldata data
) external virtual onlyOwner {
require(canPullMultiPartial(), "ZivoeLocker::pullFromLockerMultiPartial() !canPullMultiPartial()");
for (uint256 i = 0; i < assets.length; i++) {
IERC20(assets[i]).safeTransfer(owner(), amounts[i]);
}
}
/// @notice Migrates an ERC721 from owner() to locker.
/// @param asset The NFT contract.
/// @param tokenId The ID of the NFT to migrate.
/// @param data Accompanying transaction data.
function pushToLockerERC721(address asset, uint256 tokenId, bytes calldata data) external virtual onlyOwner {
require(canPushERC721(), "ZivoeLocker::pushToLockerERC721() !canPushERC721()");
IERC721(asset).safeTransferFrom(owner(), address(this), tokenId, data);
}
/// @notice Migrates an ERC721 from locker to owner().
/// @param asset The NFT contract.
/// @param tokenId The ID of the NFT to migrate.
/// @param data Accompanying transaction data.
function pullFromLockerERC721(address asset, uint256 tokenId, bytes calldata data) external virtual onlyOwner {
require(canPullERC721(), "ZivoeLocker::pullFromLockerERC721() !canPullERC721()");
IERC721(asset).safeTransferFrom(address(this), owner(), tokenId, data);
}
/// @notice Migrates ERC721s from owner() to locker.
/// @param assets The NFT contracts.
/// @param tokenIds The IDs of the NFTs to migrate.
/// @param data Accompanying transaction data.
function pushToLockerMultiERC721(
address[] calldata assets, uint256[] calldata tokenIds, bytes[] calldata data
) external virtual onlyOwner {
require(canPushMultiERC721(), "ZivoeLocker::pushToLockerMultiERC721() !canPushMultiERC721()");
for (uint256 i = 0; i < assets.length; i++) {
IERC721(assets[i]).safeTransferFrom(owner(), address(this), tokenIds[i], data[i]);
}
}
/// @notice Migrates ERC721s from locker to owner().
/// @param assets The NFT contracts.
/// @param tokenIds The IDs of the NFTs to migrate.
/// @param data Accompanying transaction data.
function pullFromLockerMultiERC721(
address[] calldata assets, uint256[] calldata tokenIds, bytes[] calldata data
) external virtual onlyOwner {
require(canPullMultiERC721(), "ZivoeLocker::pullFromLockerMultiERC721() !canPullMultiERC721()");
for (uint256 i = 0; i < assets.length; i++) {
IERC721(assets[i]).safeTransferFrom(address(this), owner(), tokenIds[i], data[i]);
}
}
/// @notice Migrates ERC1155 assets from owner() to locker.
/// @param asset The ERC1155 contract.
/// @param ids The IDs of the assets within the ERC1155 to migrate.
/// @param amounts The amounts to migrate.
/// @param data Accompanying transaction data.
function pushToLockerERC1155(
address asset, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data
) external virtual onlyOwner {
require(canPushERC1155(), "ZivoeLocker::pushToLockerERC1155() !canPushERC1155()");
IERC1155(asset).safeBatchTransferFrom(owner(), address(this), ids, amounts, data);
}
/// @notice Migrates ERC1155 assets from locker to owner().
/// @param asset The ERC1155 contract.
/// @param ids The IDs of the assets within the ERC1155 to migrate.
/// @param amounts The amounts to migrate.
/// @param data Accompanying transaction data.
function pullFromLockerERC1155(
address asset, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data
) external virtual onlyOwner {
require(canPullERC1155(), "ZivoeLocker::pullFromLockerERC1155() !canPullERC1155()");
IERC1155(asset).safeBatchTransferFrom(address(this), owner(), ids, amounts, data);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @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 ReentrancyGuard {
// 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;
constructor() {
_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 making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "../../lib/openzeppelin-contracts/contracts/access/Ownable.sol";
abstract contract OwnableLocked is Ownable {
bool public locked; /// @dev A variable "locked" that prevents future ownership transfer.
/**
* @dev Throws if called by any account other than the owner.
*/
modifier unlocked() {
require(!locked, "OwnableLocked::unlocked() locked");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner and if !locked.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public override(Ownable) onlyOwner unlocked { _transferOwnership(address(0)); }
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner and if !locked.
*/
function transferOwnership(address newOwner) public override(Ownable) onlyOwner unlocked {
require(newOwner != address(0), "OwnableLocked::transferOwnership() newOwner == address(0)");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner and if !locked.
*/
function transferOwnershipAndLock(address newOwner) public onlyOwner unlocked {
require(newOwner != address(0), "OwnableLocked::transferOwnershipAndLock() newOwner == address(0)");
locked = true;
_transferOwnership(newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.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 SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @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(
IERC20 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'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @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(IERC20 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
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)
pragma solidity ^0.8.0;
import "../IERC721Receiver.sol";
/**
* @dev Implementation of the {IERC721Receiver} interface.
*
* Accepts all token transfers.
* Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
*/
contract ERC721Holder is IERC721Receiver {
/**
* @dev See {IERC721Receiver-onERC721Received}.
*
* Always returns `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address,
address,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must 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
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol)
pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol";
/**
* Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens.
*
* IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be
* stuck.
*
* @dev _Available since v3.1._
*/
contract ERC1155Holder is ERC1155Receiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
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 {
_transferOwnership(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");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 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");
(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 functionCallWithValue(target, data, 0, "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");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// 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
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";
/**
* @dev _Available since v3.1._
*/
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev _Available since v3.1._
*/
interface IERC1155Receiver is IERC165 {
/**
* @dev Handles the receipt of a single ERC1155 token type. This function is
* called at the end of a `safeTransferFrom` after the balance has been updated.
*
* NOTE: 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.
*
* NOTE: 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
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}{
"remappings": [
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": false,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"DAO","type":"address"},{"internalType":"address","name":"_USDC","type":"address"},{"internalType":"address","name":"_GBL","type":"address"},{"internalType":"address","name":"_zVLT","type":"address"},{"internalType":"address","name":"_zSTT","type":"address"},{"internalType":"address","name":"_AAVE_V3_POOL","type":"address"},{"internalType":"address","name":"_aUSDC","type":"address"},{"internalType":"uint16","name":"_redemptionFeeBIPS","type":"uint16"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"aTokenBalance","type":"uint256"}],"name":"USDCDepositedToAAVE","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"aTokenBalance","type":"uint256"}],"name":"USDCWithdrawnFromAAVE","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedRedemptionFeeBIPS","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"zVLTBurned","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"USDCRedeemed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"zVLTBurnedForUSDC","type":"event"},{"inputs":[],"name":"AAVE_V3_POOL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GBL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aUSDC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"zVLTAmount","type":"uint256"}],"name":"calculateRedemptionAmount","outputs":[{"internalType":"uint256","name":"usdcAmount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canPull","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"canPullERC1155","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canPullERC721","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canPullMulti","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canPullMultiERC721","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canPullMultiPartial","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canPullPartial","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"canPush","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"canPushERC1155","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canPushERC721","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canPushMulti","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canPushMultiERC721","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"pullFromLocker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"pullFromLockerERC1155","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"pullFromLockerERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"pullFromLockerMulti","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"pullFromLockerMultiERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"pullFromLockerMultiPartial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"pullFromLockerPartial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"pushToLocker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"pushToLockerERC1155","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"pushToLockerERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"pushToLockerMulti","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"pushToLockerMultiERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"zVLTAmount","type":"uint256"}],"name":"redeemUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redemptionFeeBIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnershipAndLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_redemptionFeeBIPS","type":"uint256"}],"name":"updateRedemptionFeeBIPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"zSTT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"zVLT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6101406040523480156200001257600080fd5b50604051620056ac380380620056ac833981810160405281019062000038919062000542565b620000586200004c6200020f60201b60201c565b6200021760201b60201c565b600180819055506103e88161ffff161115620000ab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000a29062000692565b60405180910390fd5b620000bc88620002db60201b60201c565b8673ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250508573ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508473ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff16815250508373ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff16815250508273ffffffffffffffffffffffffffffffffffffffff166101008173ffffffffffffffffffffffffffffffffffffffff16815250508173ffffffffffffffffffffffffffffffffffffffff166101208173ffffffffffffffffffffffffffffffffffffffff16815250508061ffff16600281905550505050505050505062000830565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620002eb620003df60201b60201c565b600060149054906101000a900460ff16156200033e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003359062000704565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620003b0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003a7906200079c565b60405180910390fd5b6001600060146101000a81548160ff021916908315150217905550620003dc816200021760201b60201c565b50565b620003ef6200020f60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620004156200047060201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16146200046e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000465906200080e565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004cb826200049e565b9050919050565b620004dd81620004be565b8114620004e957600080fd5b50565b600081519050620004fd81620004d2565b92915050565b600061ffff82169050919050565b6200051c8162000503565b81146200052857600080fd5b50565b6000815190506200053c8162000511565b92915050565b600080600080600080600080610100898b03121562000566576200056562000499565b5b6000620005768b828c01620004ec565b9850506020620005898b828c01620004ec565b97505060406200059c8b828c01620004ec565b9650506060620005af8b828c01620004ec565b9550506080620005c28b828c01620004ec565b94505060a0620005d58b828c01620004ec565b93505060c0620005e88b828c01620004ec565b92505060e0620005fb8b828c016200052b565b9150509295985092959890939650565b600082825260208201905092915050565b7f4f43525f496e7374616e743a3a636f6e7374727563746f722829205f7265646560008201527f6d7074696f6e46656542495053203e2031303030000000000000000000000000602082015250565b60006200067a6034836200060b565b915062000687826200061c565b604082019050919050565b60006020820190508181036000830152620006ad816200066b565b9050919050565b7f4f776e61626c654c6f636b65643a3a756e6c6f636b65642829206c6f636b6564600082015250565b6000620006ec6020836200060b565b9150620006f982620006b4565b602082019050919050565b600060208201905081810360008301526200071f81620006dd565b9050919050565b7f4f776e61626c654c6f636b65643a3a7472616e736665724f776e65727368697060008201527f416e644c6f636b2829206e65774f776e6572203d3d2061646472657373283029602082015250565b6000620007846040836200060b565b9150620007918262000726565b604082019050919050565b60006020820190508181036000830152620007b78162000775565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000620007f66020836200060b565b91506200080382620007be565b602082019050919050565b600060208201905081810360008301526200082981620007e7565b9050919050565b60805160a05160c05160e0516101005161012051614d766200093660003960008181610fa1015281816110830152818161164301528181611c3f01528181611ccf015281816121110152612282015260008181610ca601528181610ea501528181610eed0152818161173d01528181611d6b015261219f0152600081816115670152611c0b01526000818161105f015281816113370152818161147c01526114c5015260008181610de0015281816117790152818161180a01528181611a4401528181611da701528181611e4d01528181611f0a01528181611fa4015281816121db0152818161233d01526123d7015260008181610ccf01526118b80152614d766000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c806376074b3511610151578063cd45e1fb116100c3578063d8f2a78b11610087578063d8f2a78b146106df578063dd913bdb146106fb578063e7f4462914610719578063f23a6e6114610737578063f2fde38b14610767578063fd76f59d1461078357610269565b8063cd45e1fb1461064d578063cf10b7ab14610669578063cf30901214610687578063d1f3a328146106a5578063d284af94146106c357610269565b80638da5cb5b116101155780638da5cb5b14610589578063a4a3e79d146105a7578063b0607cf8146105c5578063b892bcc0146105e3578063bc197c81146105ff578063c5f4f7b01461062f57610269565b806376074b35146104e457806379927ffa146105155780638903f9381461053157806389a302711461054d5780638b648ee21461056b57610269565b80633c117244116101ea57806351a00983116101ae57806351a0098314610448578063559fda331461046657806358289c7e1461048457806364c77735146104a05780636a7ab9af146104be578063715018a6146104da57610269565b80633c117244146103b65780633ce8d432146103d45780633eda81ad146103f2578063422b201814610410578063423156321461042c57610269565b8063191658741161023157806319165874146103245780631d9389e914610340578063215cccdd1461035c5780632f08d48b1461037a5780633b3037051461039857610269565b806301ffc9a71461026e578063120521761461029e578063150b7a02146102ba57806315e98744146102ea5780631852b38314610306575b600080fd5b61028860048036038101906102839190612d61565b61079f565b6040516102959190612da9565b60405180910390f35b6102b860048036038101906102b39190612ebd565b610819565b005b6102d460048036038101906102cf9190613072565b6108e8565b6040516102e19190613104565b60405180910390f35b61030460048036038101906102ff9190613221565b6108fc565b005b61030e610a52565b60405161031b9190612da9565b60405180910390f35b61033e600480360381019061033991906132d5565b610a57565b005b61035a60048036038101906103559190612ebd565b610bc7565b005b610364610c96565b6040516103719190612da9565b60405180910390f35b610382610c9f565b60405161038f9190612da9565b60405180910390f35b6103a0610ca4565b6040516103ad9190613365565b60405180910390f35b6103be610cc8565b6040516103cb9190612da9565b60405180910390f35b6103dc610ccd565b6040516103e99190613365565b60405180910390f35b6103fa610cf1565b6040516104079190612da9565b60405180910390f35b61042a60048036038101906104259190613380565b610cf6565b005b61044660048036038101906104419190612ebd565b610dce565b005b61045061105d565b60405161045d9190613365565b60405180910390f35b61046e611081565b60405161047b9190613365565b60405180910390f35b61049e60048036038101906104999190613449565b6110a5565b005b6104a8611193565b6040516104b59190612da9565b60405180910390f35b6104d860048036038101906104d39190613221565b61119c565b005b6104e2611289565b005b6104fe60048036038101906104f99190613476565b6112ed565b60405161050c9291906134b2565b60405180910390f35b61052f600480360381019061052a9190613476565b611422565b005b61054b60048036038101906105469190613476565b6118b6565b005b610555611a42565b6040516105629190613365565b60405180910390f35b610573611a66565b6040516105809190612da9565b60405180910390f35b610591611a6b565b60405161059e9190613365565b60405180910390f35b6105af611a94565b6040516105bc9190612da9565b60405180910390f35b6105cd611a99565b6040516105da9190612da9565b60405180910390f35b6105fd60048036038101906105f89190613221565b611a9e565b005b6106196004803603810190610614919061359e565b611bf4565b6040516106269190613104565b60405180910390f35b610637611c09565b6040516106449190613365565b60405180910390f35b6106676004803603810190610662919061366d565b611c2d565b005b610671611ff6565b60405161067e9190612da9565b60405180910390f35b61068f611ffb565b60405161069c9190612da9565b60405180910390f35b6106ad61200e565b6040516106ba91906136cd565b60405180910390f35b6106dd60048036038101906106d89190613221565b612014565b005b6106f960048036038101906106f49190612ebd565b6120ff565b005b610703612429565b6040516107109190612da9565b60405180910390f35b61072161242e565b60405161072e9190612da9565b60405180910390f35b610751600480360381019061074c91906136e8565b612437565b60405161075e9190613104565b60405180910390f35b610781600480360381019061077c9190613449565b61244c565b005b61079d60048036038101906107989190613380565b61251f565b005b60007f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806108125750610811826125f7565b5b9050919050565b610821612661565b610829610cc8565b610868576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085f90613802565b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1663b88d4fde3061088d611a6b565b8686866040518663ffffffff1660e01b81526004016108b0959493929190613860565b600060405180830381600087803b1580156108ca57600080fd5b505af11580156108de573d6000803e3d6000fd5b5050505050505050565b600063150b7a0260e01b9050949350505050565b610904612661565b61090c610a52565b61094b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161094290613920565b60405180910390fd5b60005b86869050811015610a495786868281811061096c5761096b613940565b5b90506020020160208101906109819190613449565b73ffffffffffffffffffffffffffffffffffffffff1663b88d4fde306109a5611a6b565b8888868181106109b8576109b7613940565b5b905060200201358787878181106109d2576109d1613940565b5b90506020028101906109e4919061397e565b6040518663ffffffff1660e01b8152600401610a04959493929190613860565b600060405180830381600087803b158015610a1e57600080fd5b505af1158015610a32573d6000803e3d6000fd5b505050508080610a4190613a10565b91505061094e565b50505050505050565b600090565b610a5f612661565b610a67610cf1565b610aa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9d90613aca565b60405180910390fd5b60005b84849050811015610bc057610bad610abf611a6b565b868684818110610ad257610ad1613940565b5b9050602002016020810190610ae79190613449565b73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610b1f9190613365565b602060405180830381865afa158015610b3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b609190613aff565b878785818110610b7357610b72613940565b5b9050602002016020810190610b889190613449565b73ffffffffffffffffffffffffffffffffffffffff166126df9092919063ffffffff16565b8080610bb890613a10565b915050610aa9565b5050505050565b610bcf612661565b610bd7611a66565b610c16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0d90613b9e565b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1663b88d4fde610c3a611a6b565b308686866040518663ffffffff1660e01b8152600401610c5e959493929190613860565b600060405180830381600087803b158015610c7857600080fd5b505af1158015610c8c573d6000803e3d6000fd5b5050505050505050565b60006001905090565b600090565b7f000000000000000000000000000000000000000000000000000000000000000081565b600090565b7f000000000000000000000000000000000000000000000000000000000000000081565b600090565b610cfe612661565b610d06611a99565b610d45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3c90613c30565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff16632eb2c2d630610d6a611a6b565b8989898989896040518963ffffffff1660e01b8152600401610d93989796959493929190613ccb565b600060405180830381600087803b158015610dad57600080fd5b505af1158015610dc1573d6000803e3d6000fd5b5050505050505050505050565b610dd6612661565b610dde612765565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610e6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6390613dab565b60405180910390fd5b610ea0610e77611a6b565b30858773ffffffffffffffffffffffffffffffffffffffff166127b4909392919063ffffffff16565b610eeb7f0000000000000000000000000000000000000000000000000000000000000000848673ffffffffffffffffffffffffffffffffffffffff1661283d9092919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663617ba03785853060006040518563ffffffff1660e01b8152600401610f4b9493929190613e1e565b600060405180830381600087803b158015610f6557600080fd5b505af1158015610f79573d6000803e3d6000fd5b505050507fdf625aa772ce2788204aad4e8fb64f6335d06c93dbb806389da4c5c6d366d94a837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ff89190613365565b602060405180830381865afa158015611015573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110399190613aff565b6040516110479291906134b2565b60405180910390a161105761298c565b50505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6110ad612661565b600060149054906101000a900460ff16156110fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f490613eaf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361116c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116390613f41565b60405180910390fd5b6001600060146101000a81548160ff02191690831515021790555061119081612995565b50565b60006001905090565b6111a4612661565b6111ac611a94565b6111eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e290613fd3565b60405180910390fd5b60005b868690508110156112805761126d611204611a6b565b3087878581811061121857611217613940565b5b905060200201358a8a8681811061123257611231613940565b5b90506020020160208101906112479190613449565b73ffffffffffffffffffffffffffffffffffffffff166127b4909392919063ffffffff16565b808061127890613a10565b9150506111ee565b50505050505050565b611291612661565b600060149054906101000a900460ff16156112e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d890613eaf565b60405180910390fd5b6112eb6000612995565b565b60008060008311611333576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132a90614065565b60405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166307a2d13a856040518263ffffffff1660e01b815260040161138e91906136cd565b602060405180830381865afa1580156113ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113cf9190613aff565b905064e8d4a51000612710600254836113e89190614085565b6113f291906140f6565b6113fc91906140f6565b91508164e8d4a510008261141091906140f6565b61141a9190614127565b925050915091565b61142a612765565b6000811161146d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611464906141cd565b60405180910390fd5b6114c1611478612a59565b30837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166127b4909392919063ffffffff16565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ba0876528330306040518463ffffffff1660e01b8152600401611520939291906141ed565b6020604051808303816000875af115801561153f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115639190613aff565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016115be91906136cd565b600060405180830381600087803b1580156115d857600080fd5b505af11580156115ec573d6000803e3d6000fd5b50505050600064e8d4a51000612710600254846116099190614085565b61161391906140f6565b61161d91906140f6565b905060008164e8d4a510008461163391906140f6565b61163d9190614127565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161169a9190613365565b602060405180830381865afa1580156116b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116db9190613aff565b90508264e8d4a51000856116ef91906140f6565b6116f99190614127565b81101561173b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611732906142bc565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166369328dec7f000000000000000000000000000000000000000000000000000000000000000084306040518463ffffffff1660e01b81526004016117b8939291906142dc565b6020604051808303816000875af11580156117d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117fb9190613aff565b5061184e611807612a59565b837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166126df9092919063ffffffff16565b611856612a59565b73ffffffffffffffffffffffffffffffffffffffff167f9753762b2f9166d2c5051c1d195b32262e9a1b2299b7adbcd8f918cbee35b50386848660405161189f93929190614313565b60405180910390a2505050506118b361298c565b50565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16620960456040518163ffffffff1660e01b8152600401602060405180830381865afa158015611920573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611944919061435f565b73ffffffffffffffffffffffffffffffffffffffff16611962612a59565b73ffffffffffffffffffffffffffffffffffffffff16146119b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119af906143fe565b60405180910390fd5b6103e88111156119fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f490614490565b60405180910390fd5b7ff63108a80862c66e8aecb49b35d0435bb8316150cea70f873de20089ddc6810760025482604051611a309291906134b2565b60405180910390a18060028190555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600090565b600090565b611aa6612661565b611aae612429565b611aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae490614522565b60405180910390fd5b60005b86869050811015611beb57868682818110611b0e57611b0d613940565b5b9050602002016020810190611b239190613449565b73ffffffffffffffffffffffffffffffffffffffff1663b88d4fde611b46611a6b565b30888886818110611b5a57611b59613940565b5b90506020020135878787818110611b7457611b73613940565b5b9050602002810190611b86919061397e565b6040518663ffffffff1660e01b8152600401611ba6959493929190613860565b600060405180830381600087803b158015611bc057600080fd5b505af1158015611bd4573d6000803e3d6000fd5b505050508080611be390613a10565b915050611af0565b50505050505050565b600063bc197c8160e01b905095945050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b611c35612661565b611c3d612765565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc2906145b4565b60405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611d269190613365565b602060405180830381865afa158015611d43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d679190613aff565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166369328dec7f000000000000000000000000000000000000000000000000000000000000000083306040518463ffffffff1660e01b8152600401611de6939291906142dc565b6020604051808303816000875af1158015611e05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e299190613aff565b507f69f6b9032974030b0d17a839a4f9d1c71b6df68355d4f5563d6e17c84d8576507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611ea49190613365565b602060405180830381865afa158015611ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee59190613aff565b6000604051611ef5929190614605565b60405180910390a1611fe8611f08611a6b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611f619190613365565b602060405180830381865afa158015611f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fa29190613aff565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166126df9092919063ffffffff16565b50611ff161298c565b505050565b600090565b600060149054906101000a900460ff1681565b60025481565b61201c612661565b612024610c9f565b612063576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205a906146a0565b60405180910390fd5b60005b868690508110156120f6576120e361207c611a6b565b86868481811061208f5761208e613940565b5b905060200201358989858181106120a9576120a8613940565b5b90506020020160208101906120be9190613449565b73ffffffffffffffffffffffffffffffffffffffff166126df9092919063ffffffff16565b80806120ee90613a10565b915050612066565b50505050505050565b612107612661565b61210f612765565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461219d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161219490614732565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166369328dec7f000000000000000000000000000000000000000000000000000000000000000085306040518463ffffffff1660e01b815260040161221a939291906142dc565b6020604051808303816000875af1158015612239573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225d9190613aff565b507f69f6b9032974030b0d17a839a4f9d1c71b6df68355d4f5563d6e17c84d857650837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016122d99190613365565b602060405180830381865afa1580156122f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231a9190613aff565b6040516123289291906134b2565b60405180910390a161241b61233b611a6b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016123949190613365565b602060405180830381865afa1580156123b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d59190613aff565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166126df9092919063ffffffff16565b61242361298c565b50505050565b600090565b60006001905090565b600063f23a6e6160e01b905095945050505050565b612454612661565b600060149054906101000a900460ff16156124a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249b90613eaf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612513576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250a906147c4565b60405180910390fd5b61251c81612995565b50565b612527612661565b61252f611ff6565b61256e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161256590614856565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff16632eb2c2d6612592611a6b565b308989898989896040518963ffffffff1660e01b81526004016125bc989796959493929190613ccb565b600060405180830381600087803b1580156125d657600080fd5b505af11580156125ea573d6000803e3d6000fd5b5050505050505050505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612669612a59565b73ffffffffffffffffffffffffffffffffffffffff16612687611a6b565b73ffffffffffffffffffffffffffffffffffffffff16146126dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126d4906148c2565b60405180910390fd5b565b6127608363a9059cbb60e01b84846040516024016126fe9291906148e2565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a61565b505050565b6002600154036127aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a190614957565b60405180910390fd5b6002600181905550565b612837846323b872dd60e01b8585856040516024016127d593929190614977565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a61565b50505050565b60008114806128c7575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b81526004016128849291906149ae565b602060405180830381865afa1580156128a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c59190613aff565b145b612906576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128fd90614a49565b60405180910390fd5b6129878363095ea7b360e01b84846040516024016129259291906148e2565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a61565b505050565b60018081905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000612ac3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612b289092919063ffffffff16565b9050600081511115612b235780806020019051810190612ae39190614a95565b612b22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1990614b34565b60405180910390fd5b5b505050565b6060612b378484600085612b40565b90509392505050565b606082471015612b85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b7c90614bc6565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612bae9190614c57565b60006040518083038185875af1925050503d8060008114612beb576040519150601f19603f3d011682016040523d82523d6000602084013e612bf0565b606091505b5091509150612c0187838387612c0d565b92505050949350505050565b60608315612c6f576000835103612c6757612c2785612c82565b612c66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5d90614cba565b60405180910390fd5b5b829050612c7a565b612c798383612ca5565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600082511115612cb85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cec9190614d1e565b60405180910390fd5b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612d3e81612d09565b8114612d4957600080fd5b50565b600081359050612d5b81612d35565b92915050565b600060208284031215612d7757612d76612cff565b5b6000612d8584828501612d4c565b91505092915050565b60008115159050919050565b612da381612d8e565b82525050565b6000602082019050612dbe6000830184612d9a565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612def82612dc4565b9050919050565b612dff81612de4565b8114612e0a57600080fd5b50565b600081359050612e1c81612df6565b92915050565b6000819050919050565b612e3581612e22565b8114612e4057600080fd5b50565b600081359050612e5281612e2c565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612e7d57612e7c612e58565b5b8235905067ffffffffffffffff811115612e9a57612e99612e5d565b5b602083019150836001820283011115612eb657612eb5612e62565b5b9250929050565b60008060008060608587031215612ed757612ed6612cff565b5b6000612ee587828801612e0d565b9450506020612ef687828801612e43565b935050604085013567ffffffffffffffff811115612f1757612f16612d04565b5b612f2387828801612e67565b925092505092959194509250565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612f7f82612f36565b810181811067ffffffffffffffff82111715612f9e57612f9d612f47565b5b80604052505050565b6000612fb1612cf5565b9050612fbd8282612f76565b919050565b600067ffffffffffffffff821115612fdd57612fdc612f47565b5b612fe682612f36565b9050602081019050919050565b82818337600083830152505050565b600061301561301084612fc2565b612fa7565b90508281526020810184848401111561303157613030612f31565b5b61303c848285612ff3565b509392505050565b600082601f83011261305957613058612e58565b5b8135613069848260208601613002565b91505092915050565b6000806000806080858703121561308c5761308b612cff565b5b600061309a87828801612e0d565b94505060206130ab87828801612e0d565b93505060406130bc87828801612e43565b925050606085013567ffffffffffffffff8111156130dd576130dc612d04565b5b6130e987828801613044565b91505092959194509250565b6130fe81612d09565b82525050565b600060208201905061311960008301846130f5565b92915050565b60008083601f84011261313557613134612e58565b5b8235905067ffffffffffffffff81111561315257613151612e5d565b5b60208301915083602082028301111561316e5761316d612e62565b5b9250929050565b60008083601f84011261318b5761318a612e58565b5b8235905067ffffffffffffffff8111156131a8576131a7612e5d565b5b6020830191508360208202830111156131c4576131c3612e62565b5b9250929050565b60008083601f8401126131e1576131e0612e58565b5b8235905067ffffffffffffffff8111156131fe576131fd612e5d565b5b60208301915083602082028301111561321a57613219612e62565b5b9250929050565b6000806000806000806060878903121561323e5761323d612cff565b5b600087013567ffffffffffffffff81111561325c5761325b612d04565b5b61326889828a0161311f565b9650965050602087013567ffffffffffffffff81111561328b5761328a612d04565b5b61329789828a01613175565b9450945050604087013567ffffffffffffffff8111156132ba576132b9612d04565b5b6132c689828a016131cb565b92509250509295509295509295565b600080600080604085870312156132ef576132ee612cff565b5b600085013567ffffffffffffffff81111561330d5761330c612d04565b5b6133198782880161311f565b9450945050602085013567ffffffffffffffff81111561333c5761333b612d04565b5b613348878288016131cb565b925092505092959194509250565b61335f81612de4565b82525050565b600060208201905061337a6000830184613356565b92915050565b60008060008060008060006080888a03121561339f5761339e612cff565b5b60006133ad8a828b01612e0d565b975050602088013567ffffffffffffffff8111156133ce576133cd612d04565b5b6133da8a828b01613175565b9650965050604088013567ffffffffffffffff8111156133fd576133fc612d04565b5b6134098a828b01613175565b9450945050606088013567ffffffffffffffff81111561342c5761342b612d04565b5b6134388a828b01612e67565b925092505092959891949750929550565b60006020828403121561345f5761345e612cff565b5b600061346d84828501612e0d565b91505092915050565b60006020828403121561348c5761348b612cff565b5b600061349a84828501612e43565b91505092915050565b6134ac81612e22565b82525050565b60006040820190506134c760008301856134a3565b6134d460208301846134a3565b9392505050565b600067ffffffffffffffff8211156134f6576134f5612f47565b5b602082029050602081019050919050565b600061351a613515846134db565b612fa7565b9050808382526020820190506020840283018581111561353d5761353c612e62565b5b835b8181101561356657806135528882612e43565b84526020840193505060208101905061353f565b5050509392505050565b600082601f83011261358557613584612e58565b5b8135613595848260208601613507565b91505092915050565b600080600080600060a086880312156135ba576135b9612cff565b5b60006135c888828901612e0d565b95505060206135d988828901612e0d565b945050604086013567ffffffffffffffff8111156135fa576135f9612d04565b5b61360688828901613570565b935050606086013567ffffffffffffffff81111561362757613626612d04565b5b61363388828901613570565b925050608086013567ffffffffffffffff81111561365457613653612d04565b5b61366088828901613044565b9150509295509295909350565b60008060006040848603121561368657613685612cff565b5b600061369486828701612e0d565b935050602084013567ffffffffffffffff8111156136b5576136b4612d04565b5b6136c186828701612e67565b92509250509250925092565b60006020820190506136e260008301846134a3565b92915050565b600080600080600060a0868803121561370457613703612cff565b5b600061371288828901612e0d565b955050602061372388828901612e0d565b945050604061373488828901612e43565b935050606061374588828901612e43565b925050608086013567ffffffffffffffff81111561376657613765612d04565b5b61377288828901613044565b9150509295509295909350565b600082825260208201905092915050565b7f5a69766f654c6f636b65723a3a70756c6c46726f6d4c6f636b6572455243373260008201527f312829202163616e50756c6c4552433732312829000000000000000000000000602082015250565b60006137ec60348361377f565b91506137f782613790565b604082019050919050565b6000602082019050818103600083015261381b816137df565b9050919050565b600082825260208201905092915050565b600061383f8385613822565b935061384c838584612ff3565b61385583612f36565b840190509392505050565b60006080820190506138756000830188613356565b6138826020830187613356565b61388f60408301866134a3565b81810360608301526138a2818486613833565b90509695505050505050565b7f5a69766f654c6f636b65723a3a70756c6c46726f6d4c6f636b65724d756c746960008201527f4552433732312829202163616e50756c6c4d756c746945524337323128290000602082015250565b600061390a603e8361377f565b9150613915826138ae565b604082019050919050565b60006020820190508181036000830152613939816138fd565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b6000808335600160200384360303811261399b5761399a61396f565b5b80840192508235915067ffffffffffffffff8211156139bd576139bc613974565b5b6020830192506001820236038313156139d9576139d8613979565b5b509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613a1b82612e22565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613a4d57613a4c6139e1565b5b600182019050919050565b7f5a69766f654c6f636b65723a3a70756c6c46726f6d4c6f636b65724d756c746960008201527f2829202163616e50756c6c4d756c746928290000000000000000000000000000602082015250565b6000613ab460328361377f565b9150613abf82613a58565b604082019050919050565b60006020820190508181036000830152613ae381613aa7565b9050919050565b600081519050613af981612e2c565b92915050565b600060208284031215613b1557613b14612cff565b5b6000613b2384828501613aea565b91505092915050565b7f5a69766f654c6f636b65723a3a70757368546f4c6f636b65724552433732312860008201527f29202163616e5075736845524337323128290000000000000000000000000000602082015250565b6000613b8860328361377f565b9150613b9382613b2c565b604082019050919050565b60006020820190508181036000830152613bb781613b7b565b9050919050565b7f5a69766f654c6f636b65723a3a70756c6c46726f6d4c6f636b6572455243313160008201527f35352829202163616e50756c6c45524331313535282900000000000000000000602082015250565b6000613c1a60368361377f565b9150613c2582613bbe565b604082019050919050565b60006020820190508181036000830152613c4981613c0d565b9050919050565b600082825260208201905092915050565b600080fd5b82818337505050565b6000613c7b8385613c50565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115613cae57613cad613c61565b5b602083029250613cbf838584613c66565b82840190509392505050565b600060a082019050613ce0600083018b613356565b613ced602083018a613356565b8181036040830152613d0081888a613c6f565b90508181036060830152613d15818688613c6f565b90508181036080830152613d2a818486613833565b90509998505050505050505050565b7f4f43525f496e7374616e743a3a70757368546f4c6f636b65722829206173736560008201527f7420213d20555344430000000000000000000000000000000000000000000000602082015250565b6000613d9560298361377f565b9150613da082613d39565b604082019050919050565b60006020820190508181036000830152613dc481613d88565b9050919050565b6000819050919050565b600061ffff82169050919050565b6000819050919050565b6000613e08613e03613dfe84613dcb565b613de3565b613dd5565b9050919050565b613e1881613ded565b82525050565b6000608082019050613e336000830187613356565b613e4060208301866134a3565b613e4d6040830185613356565b613e5a6060830184613e0f565b95945050505050565b7f4f776e61626c654c6f636b65643a3a756e6c6f636b65642829206c6f636b6564600082015250565b6000613e9960208361377f565b9150613ea482613e63565b602082019050919050565b60006020820190508181036000830152613ec881613e8c565b9050919050565b7f4f776e61626c654c6f636b65643a3a7472616e736665724f776e65727368697060008201527f416e644c6f636b2829206e65774f776e6572203d3d2061646472657373283029602082015250565b6000613f2b60408361377f565b9150613f3682613ecf565b604082019050919050565b60006020820190508181036000830152613f5a81613f1e565b9050919050565b7f5a69766f654c6f636b65723a3a70757368546f4c6f636b65724d756c7469282960008201527f202163616e507573684d756c7469282900000000000000000000000000000000602082015250565b6000613fbd60308361377f565b9150613fc882613f61565b604082019050919050565b60006020820190508181036000830152613fec81613fb0565b9050919050565b7f4f43525f496e7374616e743a3a63616c63756c617465526564656d7074696f6e60008201527f416d6f756e742829207a564c54416d6f756e74203d3d20300000000000000000602082015250565b600061404f60388361377f565b915061405a82613ff3565b604082019050919050565b6000602082019050818103600083015261407e81614042565b9050919050565b600061409082612e22565b915061409b83612e22565b92508282026140a981612e22565b915082820484148315176140c0576140bf6139e1565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061410182612e22565b915061410c83612e22565b92508261411c5761411b6140c7565b5b828204905092915050565b600061413282612e22565b915061413d83612e22565b9250828203905081811115614155576141546139e1565b5b92915050565b7f4f43525f496e7374616e743a3a72656465656d555344432829207a564c54416d60008201527f6f756e74203d3d20300000000000000000000000000000000000000000000000602082015250565b60006141b760298361377f565b91506141c28261415b565b604082019050919050565b600060208201905081810360008301526141e6816141aa565b9050919050565b600060608201905061420260008301866134a3565b61420f6020830185613356565b61421c6040830184613356565b949350505050565b7f4f43525f496e7374616e743a3a72656465656d5553444328292061555344434260008201527f616c616e6365203c207a5354545265636569766564202f2031302a2a3132202d60208201527f2066656500000000000000000000000000000000000000000000000000000000604082015250565b60006142a660448361377f565b91506142b182614224565b606082019050919050565b600060208201905081810360008301526142d581614299565b9050919050565b60006060820190506142f16000830186613356565b6142fe60208301856134a3565b61430b6040830184613356565b949350505050565b600060608201905061432860008301866134a3565b61433560208301856134a3565b61434260408301846134a3565b949350505050565b60008151905061435981612df6565b92915050565b60006020828403121561437557614374612cff565b5b60006143838482850161434a565b91505092915050565b7f4f43525f496e7374616e743a3a757064617465526564656d7074696f6e46656560008201527f424950532829205f6d736753656e646572282920213d205a564c282900000000602082015250565b60006143e8603c8361377f565b91506143f38261438c565b604082019050919050565b60006020820190508181036000830152614417816143db565b9050919050565b7f4f43525f496e7374616e743a3a757064617465526564656d7074696f6e46656560008201527f424950532829205f726564656d7074696f6e46656542495053203e2031303030602082015250565b600061447a60408361377f565b91506144858261441e565b604082019050919050565b600060208201905081810360008301526144a98161446d565b9050919050565b7f5a69766f654c6f636b65723a3a70757368546f4c6f636b65724d756c7469455260008201527f433732312829202163616e507573684d756c7469455243373231282900000000602082015250565b600061450c603c8361377f565b9150614517826144b0565b604082019050919050565b6000602082019050818103600083015261453b816144ff565b9050919050565b7f4f43525f496e7374616e743a3a70756c6c46726f6d4c6f636b6572282920617360008201527f73657420213d2061555344430000000000000000000000000000000000000000602082015250565b600061459e602c8361377f565b91506145a982614542565b604082019050919050565b600060208201905081810360008301526145cd81614591565b9050919050565b60006145ef6145ea6145e584613dcb565b613de3565b612e22565b9050919050565b6145ff816145d4565b82525050565b600060408201905061461a60008301856134a3565b61462760208301846145f6565b9392505050565b7f5a69766f654c6f636b65723a3a70756c6c46726f6d4c6f636b65724d756c746960008201527f5061727469616c2829202163616e50756c6c4d756c74695061727469616c2829602082015250565b600061468a60408361377f565b91506146958261462e565b604082019050919050565b600060208201905081810360008301526146b98161467d565b9050919050565b7f4f43525f496e7374616e743a3a70756c6c46726f6d4c6f636b6572506172746960008201527f616c282920617373657420213d20615553444300000000000000000000000000602082015250565b600061471c60338361377f565b9150614727826146c0565b604082019050919050565b6000602082019050818103600083015261474b8161470f565b9050919050565b7f4f776e61626c654c6f636b65643a3a7472616e736665724f776e65727368697060008201527f2829206e65774f776e6572203d3d206164647265737328302900000000000000602082015250565b60006147ae60398361377f565b91506147b982614752565b604082019050919050565b600060208201905081810360008301526147dd816147a1565b9050919050565b7f5a69766f654c6f636b65723a3a70757368546f4c6f636b65724552433131353560008201527f2829202163616e50757368455243313135352829000000000000000000000000602082015250565b600061484060348361377f565b915061484b826147e4565b604082019050919050565b6000602082019050818103600083015261486f81614833565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006148ac60208361377f565b91506148b782614876565b602082019050919050565b600060208201905081810360008301526148db8161489f565b9050919050565b60006040820190506148f76000830185613356565b61490460208301846134a3565b9392505050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614941601f8361377f565b915061494c8261490b565b602082019050919050565b6000602082019050818103600083015261497081614934565b9050919050565b600060608201905061498c6000830186613356565b6149996020830185613356565b6149a660408301846134a3565b949350505050565b60006040820190506149c36000830185613356565b6149d06020830184613356565b9392505050565b7f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000602082015250565b6000614a3360368361377f565b9150614a3e826149d7565b604082019050919050565b60006020820190508181036000830152614a6281614a26565b9050919050565b614a7281612d8e565b8114614a7d57600080fd5b50565b600081519050614a8f81614a69565b92915050565b600060208284031215614aab57614aaa612cff565b5b6000614ab984828501614a80565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000614b1e602a8361377f565b9150614b2982614ac2565b604082019050919050565b60006020820190508181036000830152614b4d81614b11565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000614bb060268361377f565b9150614bbb82614b54565b604082019050919050565b60006020820190508181036000830152614bdf81614ba3565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015614c1a578082015181840152602081019050614bff565b60008484015250505050565b6000614c3182614be6565b614c3b8185614bf1565b9350614c4b818560208601614bfc565b80840191505092915050565b6000614c638284614c26565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000614ca4601d8361377f565b9150614caf82614c6e565b602082019050919050565b60006020820190508181036000830152614cd381614c97565b9050919050565b600081519050919050565b6000614cf082614cda565b614cfa818561377f565b9350614d0a818560208601614bfc565b614d1381612f36565b840191505092915050565b60006020820190508181036000830152614d388184614ce5565b90509291505056fea2646970667358221220b1a8b62b0f79de5f019373cd220728ab12062cff0612628ae0ac9a43fac8604364736f6c63430008110033000000000000000000000000b65a66621d7de34afec9b9ac0755133051550dd7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da6600000000000000000000000094babe9ee75c38034920bc6ed42748e8eefbedd40000000000000000000000007aa5bf30042b2145b9f0629ea68de55b42ad3bb600000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e200000000000000000000000098c23e9d8f34fefb1b7bd6a91b7ff122f4e16f5c000000000000000000000000000000000000000000000000000000000000004b
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102695760003560e01c806376074b3511610151578063cd45e1fb116100c3578063d8f2a78b11610087578063d8f2a78b146106df578063dd913bdb146106fb578063e7f4462914610719578063f23a6e6114610737578063f2fde38b14610767578063fd76f59d1461078357610269565b8063cd45e1fb1461064d578063cf10b7ab14610669578063cf30901214610687578063d1f3a328146106a5578063d284af94146106c357610269565b80638da5cb5b116101155780638da5cb5b14610589578063a4a3e79d146105a7578063b0607cf8146105c5578063b892bcc0146105e3578063bc197c81146105ff578063c5f4f7b01461062f57610269565b806376074b35146104e457806379927ffa146105155780638903f9381461053157806389a302711461054d5780638b648ee21461056b57610269565b80633c117244116101ea57806351a00983116101ae57806351a0098314610448578063559fda331461046657806358289c7e1461048457806364c77735146104a05780636a7ab9af146104be578063715018a6146104da57610269565b80633c117244146103b65780633ce8d432146103d45780633eda81ad146103f2578063422b201814610410578063423156321461042c57610269565b8063191658741161023157806319165874146103245780631d9389e914610340578063215cccdd1461035c5780632f08d48b1461037a5780633b3037051461039857610269565b806301ffc9a71461026e578063120521761461029e578063150b7a02146102ba57806315e98744146102ea5780631852b38314610306575b600080fd5b61028860048036038101906102839190612d61565b61079f565b6040516102959190612da9565b60405180910390f35b6102b860048036038101906102b39190612ebd565b610819565b005b6102d460048036038101906102cf9190613072565b6108e8565b6040516102e19190613104565b60405180910390f35b61030460048036038101906102ff9190613221565b6108fc565b005b61030e610a52565b60405161031b9190612da9565b60405180910390f35b61033e600480360381019061033991906132d5565b610a57565b005b61035a60048036038101906103559190612ebd565b610bc7565b005b610364610c96565b6040516103719190612da9565b60405180910390f35b610382610c9f565b60405161038f9190612da9565b60405180910390f35b6103a0610ca4565b6040516103ad9190613365565b60405180910390f35b6103be610cc8565b6040516103cb9190612da9565b60405180910390f35b6103dc610ccd565b6040516103e99190613365565b60405180910390f35b6103fa610cf1565b6040516104079190612da9565b60405180910390f35b61042a60048036038101906104259190613380565b610cf6565b005b61044660048036038101906104419190612ebd565b610dce565b005b61045061105d565b60405161045d9190613365565b60405180910390f35b61046e611081565b60405161047b9190613365565b60405180910390f35b61049e60048036038101906104999190613449565b6110a5565b005b6104a8611193565b6040516104b59190612da9565b60405180910390f35b6104d860048036038101906104d39190613221565b61119c565b005b6104e2611289565b005b6104fe60048036038101906104f99190613476565b6112ed565b60405161050c9291906134b2565b60405180910390f35b61052f600480360381019061052a9190613476565b611422565b005b61054b60048036038101906105469190613476565b6118b6565b005b610555611a42565b6040516105629190613365565b60405180910390f35b610573611a66565b6040516105809190612da9565b60405180910390f35b610591611a6b565b60405161059e9190613365565b60405180910390f35b6105af611a94565b6040516105bc9190612da9565b60405180910390f35b6105cd611a99565b6040516105da9190612da9565b60405180910390f35b6105fd60048036038101906105f89190613221565b611a9e565b005b6106196004803603810190610614919061359e565b611bf4565b6040516106269190613104565b60405180910390f35b610637611c09565b6040516106449190613365565b60405180910390f35b6106676004803603810190610662919061366d565b611c2d565b005b610671611ff6565b60405161067e9190612da9565b60405180910390f35b61068f611ffb565b60405161069c9190612da9565b60405180910390f35b6106ad61200e565b6040516106ba91906136cd565b60405180910390f35b6106dd60048036038101906106d89190613221565b612014565b005b6106f960048036038101906106f49190612ebd565b6120ff565b005b610703612429565b6040516107109190612da9565b60405180910390f35b61072161242e565b60405161072e9190612da9565b60405180910390f35b610751600480360381019061074c91906136e8565b612437565b60405161075e9190613104565b60405180910390f35b610781600480360381019061077c9190613449565b61244c565b005b61079d60048036038101906107989190613380565b61251f565b005b60007f4e2312e0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806108125750610811826125f7565b5b9050919050565b610821612661565b610829610cc8565b610868576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085f90613802565b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1663b88d4fde3061088d611a6b565b8686866040518663ffffffff1660e01b81526004016108b0959493929190613860565b600060405180830381600087803b1580156108ca57600080fd5b505af11580156108de573d6000803e3d6000fd5b5050505050505050565b600063150b7a0260e01b9050949350505050565b610904612661565b61090c610a52565b61094b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161094290613920565b60405180910390fd5b60005b86869050811015610a495786868281811061096c5761096b613940565b5b90506020020160208101906109819190613449565b73ffffffffffffffffffffffffffffffffffffffff1663b88d4fde306109a5611a6b565b8888868181106109b8576109b7613940565b5b905060200201358787878181106109d2576109d1613940565b5b90506020028101906109e4919061397e565b6040518663ffffffff1660e01b8152600401610a04959493929190613860565b600060405180830381600087803b158015610a1e57600080fd5b505af1158015610a32573d6000803e3d6000fd5b505050508080610a4190613a10565b91505061094e565b50505050505050565b600090565b610a5f612661565b610a67610cf1565b610aa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9d90613aca565b60405180910390fd5b60005b84849050811015610bc057610bad610abf611a6b565b868684818110610ad257610ad1613940565b5b9050602002016020810190610ae79190613449565b73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610b1f9190613365565b602060405180830381865afa158015610b3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b609190613aff565b878785818110610b7357610b72613940565b5b9050602002016020810190610b889190613449565b73ffffffffffffffffffffffffffffffffffffffff166126df9092919063ffffffff16565b8080610bb890613a10565b915050610aa9565b5050505050565b610bcf612661565b610bd7611a66565b610c16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0d90613b9e565b60405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1663b88d4fde610c3a611a6b565b308686866040518663ffffffff1660e01b8152600401610c5e959493929190613860565b600060405180830381600087803b158015610c7857600080fd5b505af1158015610c8c573d6000803e3d6000fd5b5050505050505050565b60006001905090565b600090565b7f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e281565b600090565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da6681565b600090565b610cfe612661565b610d06611a99565b610d45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3c90613c30565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff16632eb2c2d630610d6a611a6b565b8989898989896040518963ffffffff1660e01b8152600401610d93989796959493929190613ccb565b600060405180830381600087803b158015610dad57600080fd5b505af1158015610dc1573d6000803e3d6000fd5b5050505050505050505050565b610dd6612661565b610dde612765565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610e6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6390613dab565b60405180910390fd5b610ea0610e77611a6b565b30858773ffffffffffffffffffffffffffffffffffffffff166127b4909392919063ffffffff16565b610eeb7f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e2848673ffffffffffffffffffffffffffffffffffffffff1661283d9092919063ffffffff16565b7f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e273ffffffffffffffffffffffffffffffffffffffff1663617ba03785853060006040518563ffffffff1660e01b8152600401610f4b9493929190613e1e565b600060405180830381600087803b158015610f6557600080fd5b505af1158015610f79573d6000803e3d6000fd5b505050507fdf625aa772ce2788204aad4e8fb64f6335d06c93dbb806389da4c5c6d366d94a837f00000000000000000000000098c23e9d8f34fefb1b7bd6a91b7ff122f4e16f5c73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ff89190613365565b602060405180830381865afa158015611015573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110399190613aff565b6040516110479291906134b2565b60405180910390a161105761298c565b50505050565b7f00000000000000000000000094babe9ee75c38034920bc6ed42748e8eefbedd481565b7f00000000000000000000000098c23e9d8f34fefb1b7bd6a91b7ff122f4e16f5c81565b6110ad612661565b600060149054906101000a900460ff16156110fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f490613eaf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361116c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116390613f41565b60405180910390fd5b6001600060146101000a81548160ff02191690831515021790555061119081612995565b50565b60006001905090565b6111a4612661565b6111ac611a94565b6111eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e290613fd3565b60405180910390fd5b60005b868690508110156112805761126d611204611a6b565b3087878581811061121857611217613940565b5b905060200201358a8a8681811061123257611231613940565b5b90506020020160208101906112479190613449565b73ffffffffffffffffffffffffffffffffffffffff166127b4909392919063ffffffff16565b808061127890613a10565b9150506111ee565b50505050505050565b611291612661565b600060149054906101000a900460ff16156112e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d890613eaf565b60405180910390fd5b6112eb6000612995565b565b60008060008311611333576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161132a90614065565b60405180910390fd5b60007f00000000000000000000000094babe9ee75c38034920bc6ed42748e8eefbedd473ffffffffffffffffffffffffffffffffffffffff166307a2d13a856040518263ffffffff1660e01b815260040161138e91906136cd565b602060405180830381865afa1580156113ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113cf9190613aff565b905064e8d4a51000612710600254836113e89190614085565b6113f291906140f6565b6113fc91906140f6565b91508164e8d4a510008261141091906140f6565b61141a9190614127565b925050915091565b61142a612765565b6000811161146d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611464906141cd565b60405180910390fd5b6114c1611478612a59565b30837f00000000000000000000000094babe9ee75c38034920bc6ed42748e8eefbedd473ffffffffffffffffffffffffffffffffffffffff166127b4909392919063ffffffff16565b60007f00000000000000000000000094babe9ee75c38034920bc6ed42748e8eefbedd473ffffffffffffffffffffffffffffffffffffffff1663ba0876528330306040518463ffffffff1660e01b8152600401611520939291906141ed565b6020604051808303816000875af115801561153f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115639190613aff565b90507f0000000000000000000000007aa5bf30042b2145b9f0629ea68de55b42ad3bb673ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b81526004016115be91906136cd565b600060405180830381600087803b1580156115d857600080fd5b505af11580156115ec573d6000803e3d6000fd5b50505050600064e8d4a51000612710600254846116099190614085565b61161391906140f6565b61161d91906140f6565b905060008164e8d4a510008461163391906140f6565b61163d9190614127565b905060007f00000000000000000000000098c23e9d8f34fefb1b7bd6a91b7ff122f4e16f5c73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161169a9190613365565b602060405180830381865afa1580156116b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116db9190613aff565b90508264e8d4a51000856116ef91906140f6565b6116f99190614127565b81101561173b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611732906142bc565b60405180910390fd5b7f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e273ffffffffffffffffffffffffffffffffffffffff166369328dec7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4884306040518463ffffffff1660e01b81526004016117b8939291906142dc565b6020604051808303816000875af11580156117d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117fb9190613aff565b5061184e611807612a59565b837f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff166126df9092919063ffffffff16565b611856612a59565b73ffffffffffffffffffffffffffffffffffffffff167f9753762b2f9166d2c5051c1d195b32262e9a1b2299b7adbcd8f918cbee35b50386848660405161189f93929190614313565b60405180910390a2505050506118b361298c565b50565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da6673ffffffffffffffffffffffffffffffffffffffff16620960456040518163ffffffff1660e01b8152600401602060405180830381865afa158015611920573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611944919061435f565b73ffffffffffffffffffffffffffffffffffffffff16611962612a59565b73ffffffffffffffffffffffffffffffffffffffff16146119b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119af906143fe565b60405180910390fd5b6103e88111156119fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f490614490565b60405180910390fd5b7ff63108a80862c66e8aecb49b35d0435bb8316150cea70f873de20089ddc6810760025482604051611a309291906134b2565b60405180910390a18060028190555050565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b600090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600090565b600090565b611aa6612661565b611aae612429565b611aed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae490614522565b60405180910390fd5b60005b86869050811015611beb57868682818110611b0e57611b0d613940565b5b9050602002016020810190611b239190613449565b73ffffffffffffffffffffffffffffffffffffffff1663b88d4fde611b46611a6b565b30888886818110611b5a57611b59613940565b5b90506020020135878787818110611b7457611b73613940565b5b9050602002810190611b86919061397e565b6040518663ffffffff1660e01b8152600401611ba6959493929190613860565b600060405180830381600087803b158015611bc057600080fd5b505af1158015611bd4573d6000803e3d6000fd5b505050508080611be390613a10565b915050611af0565b50505050505050565b600063bc197c8160e01b905095945050505050565b7f0000000000000000000000007aa5bf30042b2145b9f0629ea68de55b42ad3bb681565b611c35612661565b611c3d612765565b7f00000000000000000000000098c23e9d8f34fefb1b7bd6a91b7ff122f4e16f5c73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc2906145b4565b60405180910390fd5b60007f00000000000000000000000098c23e9d8f34fefb1b7bd6a91b7ff122f4e16f5c73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611d269190613365565b602060405180830381865afa158015611d43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d679190613aff565b90507f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e273ffffffffffffffffffffffffffffffffffffffff166369328dec7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4883306040518463ffffffff1660e01b8152600401611de6939291906142dc565b6020604051808303816000875af1158015611e05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e299190613aff565b507f69f6b9032974030b0d17a839a4f9d1c71b6df68355d4f5563d6e17c84d8576507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611ea49190613365565b602060405180830381865afa158015611ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee59190613aff565b6000604051611ef5929190614605565b60405180910390a1611fe8611f08611a6b565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611f619190613365565b602060405180830381865afa158015611f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fa29190613aff565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff166126df9092919063ffffffff16565b50611ff161298c565b505050565b600090565b600060149054906101000a900460ff1681565b60025481565b61201c612661565b612024610c9f565b612063576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205a906146a0565b60405180910390fd5b60005b868690508110156120f6576120e361207c611a6b565b86868481811061208f5761208e613940565b5b905060200201358989858181106120a9576120a8613940565b5b90506020020160208101906120be9190613449565b73ffffffffffffffffffffffffffffffffffffffff166126df9092919063ffffffff16565b80806120ee90613a10565b915050612066565b50505050505050565b612107612661565b61210f612765565b7f00000000000000000000000098c23e9d8f34fefb1b7bd6a91b7ff122f4e16f5c73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461219d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161219490614732565b60405180910390fd5b7f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e273ffffffffffffffffffffffffffffffffffffffff166369328dec7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4885306040518463ffffffff1660e01b815260040161221a939291906142dc565b6020604051808303816000875af1158015612239573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225d9190613aff565b507f69f6b9032974030b0d17a839a4f9d1c71b6df68355d4f5563d6e17c84d857650837f00000000000000000000000098c23e9d8f34fefb1b7bd6a91b7ff122f4e16f5c73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016122d99190613365565b602060405180830381865afa1580156122f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231a9190613aff565b6040516123289291906134b2565b60405180910390a161241b61233b611a6b565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016123949190613365565b602060405180830381865afa1580156123b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d59190613aff565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873ffffffffffffffffffffffffffffffffffffffff166126df9092919063ffffffff16565b61242361298c565b50505050565b600090565b60006001905090565b600063f23a6e6160e01b905095945050505050565b612454612661565b600060149054906101000a900460ff16156124a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249b90613eaf565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612513576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250a906147c4565b60405180910390fd5b61251c81612995565b50565b612527612661565b61252f611ff6565b61256e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161256590614856565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff16632eb2c2d6612592611a6b565b308989898989896040518963ffffffff1660e01b81526004016125bc989796959493929190613ccb565b600060405180830381600087803b1580156125d657600080fd5b505af11580156125ea573d6000803e3d6000fd5b5050505050505050505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612669612a59565b73ffffffffffffffffffffffffffffffffffffffff16612687611a6b565b73ffffffffffffffffffffffffffffffffffffffff16146126dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126d4906148c2565b60405180910390fd5b565b6127608363a9059cbb60e01b84846040516024016126fe9291906148e2565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a61565b505050565b6002600154036127aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a190614957565b60405180910390fd5b6002600181905550565b612837846323b872dd60e01b8585856040516024016127d593929190614977565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a61565b50505050565b60008114806128c7575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b81526004016128849291906149ae565b602060405180830381865afa1580156128a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c59190613aff565b145b612906576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128fd90614a49565b60405180910390fd5b6129878363095ea7b360e01b84846040516024016129259291906148e2565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612a61565b505050565b60018081905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000612ac3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612b289092919063ffffffff16565b9050600081511115612b235780806020019051810190612ae39190614a95565b612b22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1990614b34565b60405180910390fd5b5b505050565b6060612b378484600085612b40565b90509392505050565b606082471015612b85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b7c90614bc6565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612bae9190614c57565b60006040518083038185875af1925050503d8060008114612beb576040519150601f19603f3d011682016040523d82523d6000602084013e612bf0565b606091505b5091509150612c0187838387612c0d565b92505050949350505050565b60608315612c6f576000835103612c6757612c2785612c82565b612c66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5d90614cba565b60405180910390fd5b5b829050612c7a565b612c798383612ca5565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600082511115612cb85781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cec9190614d1e565b60405180910390fd5b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612d3e81612d09565b8114612d4957600080fd5b50565b600081359050612d5b81612d35565b92915050565b600060208284031215612d7757612d76612cff565b5b6000612d8584828501612d4c565b91505092915050565b60008115159050919050565b612da381612d8e565b82525050565b6000602082019050612dbe6000830184612d9a565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612def82612dc4565b9050919050565b612dff81612de4565b8114612e0a57600080fd5b50565b600081359050612e1c81612df6565b92915050565b6000819050919050565b612e3581612e22565b8114612e4057600080fd5b50565b600081359050612e5281612e2c565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612e7d57612e7c612e58565b5b8235905067ffffffffffffffff811115612e9a57612e99612e5d565b5b602083019150836001820283011115612eb657612eb5612e62565b5b9250929050565b60008060008060608587031215612ed757612ed6612cff565b5b6000612ee587828801612e0d565b9450506020612ef687828801612e43565b935050604085013567ffffffffffffffff811115612f1757612f16612d04565b5b612f2387828801612e67565b925092505092959194509250565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612f7f82612f36565b810181811067ffffffffffffffff82111715612f9e57612f9d612f47565b5b80604052505050565b6000612fb1612cf5565b9050612fbd8282612f76565b919050565b600067ffffffffffffffff821115612fdd57612fdc612f47565b5b612fe682612f36565b9050602081019050919050565b82818337600083830152505050565b600061301561301084612fc2565b612fa7565b90508281526020810184848401111561303157613030612f31565b5b61303c848285612ff3565b509392505050565b600082601f83011261305957613058612e58565b5b8135613069848260208601613002565b91505092915050565b6000806000806080858703121561308c5761308b612cff565b5b600061309a87828801612e0d565b94505060206130ab87828801612e0d565b93505060406130bc87828801612e43565b925050606085013567ffffffffffffffff8111156130dd576130dc612d04565b5b6130e987828801613044565b91505092959194509250565b6130fe81612d09565b82525050565b600060208201905061311960008301846130f5565b92915050565b60008083601f84011261313557613134612e58565b5b8235905067ffffffffffffffff81111561315257613151612e5d565b5b60208301915083602082028301111561316e5761316d612e62565b5b9250929050565b60008083601f84011261318b5761318a612e58565b5b8235905067ffffffffffffffff8111156131a8576131a7612e5d565b5b6020830191508360208202830111156131c4576131c3612e62565b5b9250929050565b60008083601f8401126131e1576131e0612e58565b5b8235905067ffffffffffffffff8111156131fe576131fd612e5d565b5b60208301915083602082028301111561321a57613219612e62565b5b9250929050565b6000806000806000806060878903121561323e5761323d612cff565b5b600087013567ffffffffffffffff81111561325c5761325b612d04565b5b61326889828a0161311f565b9650965050602087013567ffffffffffffffff81111561328b5761328a612d04565b5b61329789828a01613175565b9450945050604087013567ffffffffffffffff8111156132ba576132b9612d04565b5b6132c689828a016131cb565b92509250509295509295509295565b600080600080604085870312156132ef576132ee612cff565b5b600085013567ffffffffffffffff81111561330d5761330c612d04565b5b6133198782880161311f565b9450945050602085013567ffffffffffffffff81111561333c5761333b612d04565b5b613348878288016131cb565b925092505092959194509250565b61335f81612de4565b82525050565b600060208201905061337a6000830184613356565b92915050565b60008060008060008060006080888a03121561339f5761339e612cff565b5b60006133ad8a828b01612e0d565b975050602088013567ffffffffffffffff8111156133ce576133cd612d04565b5b6133da8a828b01613175565b9650965050604088013567ffffffffffffffff8111156133fd576133fc612d04565b5b6134098a828b01613175565b9450945050606088013567ffffffffffffffff81111561342c5761342b612d04565b5b6134388a828b01612e67565b925092505092959891949750929550565b60006020828403121561345f5761345e612cff565b5b600061346d84828501612e0d565b91505092915050565b60006020828403121561348c5761348b612cff565b5b600061349a84828501612e43565b91505092915050565b6134ac81612e22565b82525050565b60006040820190506134c760008301856134a3565b6134d460208301846134a3565b9392505050565b600067ffffffffffffffff8211156134f6576134f5612f47565b5b602082029050602081019050919050565b600061351a613515846134db565b612fa7565b9050808382526020820190506020840283018581111561353d5761353c612e62565b5b835b8181101561356657806135528882612e43565b84526020840193505060208101905061353f565b5050509392505050565b600082601f83011261358557613584612e58565b5b8135613595848260208601613507565b91505092915050565b600080600080600060a086880312156135ba576135b9612cff565b5b60006135c888828901612e0d565b95505060206135d988828901612e0d565b945050604086013567ffffffffffffffff8111156135fa576135f9612d04565b5b61360688828901613570565b935050606086013567ffffffffffffffff81111561362757613626612d04565b5b61363388828901613570565b925050608086013567ffffffffffffffff81111561365457613653612d04565b5b61366088828901613044565b9150509295509295909350565b60008060006040848603121561368657613685612cff565b5b600061369486828701612e0d565b935050602084013567ffffffffffffffff8111156136b5576136b4612d04565b5b6136c186828701612e67565b92509250509250925092565b60006020820190506136e260008301846134a3565b92915050565b600080600080600060a0868803121561370457613703612cff565b5b600061371288828901612e0d565b955050602061372388828901612e0d565b945050604061373488828901612e43565b935050606061374588828901612e43565b925050608086013567ffffffffffffffff81111561376657613765612d04565b5b61377288828901613044565b9150509295509295909350565b600082825260208201905092915050565b7f5a69766f654c6f636b65723a3a70756c6c46726f6d4c6f636b6572455243373260008201527f312829202163616e50756c6c4552433732312829000000000000000000000000602082015250565b60006137ec60348361377f565b91506137f782613790565b604082019050919050565b6000602082019050818103600083015261381b816137df565b9050919050565b600082825260208201905092915050565b600061383f8385613822565b935061384c838584612ff3565b61385583612f36565b840190509392505050565b60006080820190506138756000830188613356565b6138826020830187613356565b61388f60408301866134a3565b81810360608301526138a2818486613833565b90509695505050505050565b7f5a69766f654c6f636b65723a3a70756c6c46726f6d4c6f636b65724d756c746960008201527f4552433732312829202163616e50756c6c4d756c746945524337323128290000602082015250565b600061390a603e8361377f565b9150613915826138ae565b604082019050919050565b60006020820190508181036000830152613939816138fd565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b6000808335600160200384360303811261399b5761399a61396f565b5b80840192508235915067ffffffffffffffff8211156139bd576139bc613974565b5b6020830192506001820236038313156139d9576139d8613979565b5b509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613a1b82612e22565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613a4d57613a4c6139e1565b5b600182019050919050565b7f5a69766f654c6f636b65723a3a70756c6c46726f6d4c6f636b65724d756c746960008201527f2829202163616e50756c6c4d756c746928290000000000000000000000000000602082015250565b6000613ab460328361377f565b9150613abf82613a58565b604082019050919050565b60006020820190508181036000830152613ae381613aa7565b9050919050565b600081519050613af981612e2c565b92915050565b600060208284031215613b1557613b14612cff565b5b6000613b2384828501613aea565b91505092915050565b7f5a69766f654c6f636b65723a3a70757368546f4c6f636b65724552433732312860008201527f29202163616e5075736845524337323128290000000000000000000000000000602082015250565b6000613b8860328361377f565b9150613b9382613b2c565b604082019050919050565b60006020820190508181036000830152613bb781613b7b565b9050919050565b7f5a69766f654c6f636b65723a3a70756c6c46726f6d4c6f636b6572455243313160008201527f35352829202163616e50756c6c45524331313535282900000000000000000000602082015250565b6000613c1a60368361377f565b9150613c2582613bbe565b604082019050919050565b60006020820190508181036000830152613c4981613c0d565b9050919050565b600082825260208201905092915050565b600080fd5b82818337505050565b6000613c7b8385613c50565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115613cae57613cad613c61565b5b602083029250613cbf838584613c66565b82840190509392505050565b600060a082019050613ce0600083018b613356565b613ced602083018a613356565b8181036040830152613d0081888a613c6f565b90508181036060830152613d15818688613c6f565b90508181036080830152613d2a818486613833565b90509998505050505050505050565b7f4f43525f496e7374616e743a3a70757368546f4c6f636b65722829206173736560008201527f7420213d20555344430000000000000000000000000000000000000000000000602082015250565b6000613d9560298361377f565b9150613da082613d39565b604082019050919050565b60006020820190508181036000830152613dc481613d88565b9050919050565b6000819050919050565b600061ffff82169050919050565b6000819050919050565b6000613e08613e03613dfe84613dcb565b613de3565b613dd5565b9050919050565b613e1881613ded565b82525050565b6000608082019050613e336000830187613356565b613e4060208301866134a3565b613e4d6040830185613356565b613e5a6060830184613e0f565b95945050505050565b7f4f776e61626c654c6f636b65643a3a756e6c6f636b65642829206c6f636b6564600082015250565b6000613e9960208361377f565b9150613ea482613e63565b602082019050919050565b60006020820190508181036000830152613ec881613e8c565b9050919050565b7f4f776e61626c654c6f636b65643a3a7472616e736665724f776e65727368697060008201527f416e644c6f636b2829206e65774f776e6572203d3d2061646472657373283029602082015250565b6000613f2b60408361377f565b9150613f3682613ecf565b604082019050919050565b60006020820190508181036000830152613f5a81613f1e565b9050919050565b7f5a69766f654c6f636b65723a3a70757368546f4c6f636b65724d756c7469282960008201527f202163616e507573684d756c7469282900000000000000000000000000000000602082015250565b6000613fbd60308361377f565b9150613fc882613f61565b604082019050919050565b60006020820190508181036000830152613fec81613fb0565b9050919050565b7f4f43525f496e7374616e743a3a63616c63756c617465526564656d7074696f6e60008201527f416d6f756e742829207a564c54416d6f756e74203d3d20300000000000000000602082015250565b600061404f60388361377f565b915061405a82613ff3565b604082019050919050565b6000602082019050818103600083015261407e81614042565b9050919050565b600061409082612e22565b915061409b83612e22565b92508282026140a981612e22565b915082820484148315176140c0576140bf6139e1565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061410182612e22565b915061410c83612e22565b92508261411c5761411b6140c7565b5b828204905092915050565b600061413282612e22565b915061413d83612e22565b9250828203905081811115614155576141546139e1565b5b92915050565b7f4f43525f496e7374616e743a3a72656465656d555344432829207a564c54416d60008201527f6f756e74203d3d20300000000000000000000000000000000000000000000000602082015250565b60006141b760298361377f565b91506141c28261415b565b604082019050919050565b600060208201905081810360008301526141e6816141aa565b9050919050565b600060608201905061420260008301866134a3565b61420f6020830185613356565b61421c6040830184613356565b949350505050565b7f4f43525f496e7374616e743a3a72656465656d5553444328292061555344434260008201527f616c616e6365203c207a5354545265636569766564202f2031302a2a3132202d60208201527f2066656500000000000000000000000000000000000000000000000000000000604082015250565b60006142a660448361377f565b91506142b182614224565b606082019050919050565b600060208201905081810360008301526142d581614299565b9050919050565b60006060820190506142f16000830186613356565b6142fe60208301856134a3565b61430b6040830184613356565b949350505050565b600060608201905061432860008301866134a3565b61433560208301856134a3565b61434260408301846134a3565b949350505050565b60008151905061435981612df6565b92915050565b60006020828403121561437557614374612cff565b5b60006143838482850161434a565b91505092915050565b7f4f43525f496e7374616e743a3a757064617465526564656d7074696f6e46656560008201527f424950532829205f6d736753656e646572282920213d205a564c282900000000602082015250565b60006143e8603c8361377f565b91506143f38261438c565b604082019050919050565b60006020820190508181036000830152614417816143db565b9050919050565b7f4f43525f496e7374616e743a3a757064617465526564656d7074696f6e46656560008201527f424950532829205f726564656d7074696f6e46656542495053203e2031303030602082015250565b600061447a60408361377f565b91506144858261441e565b604082019050919050565b600060208201905081810360008301526144a98161446d565b9050919050565b7f5a69766f654c6f636b65723a3a70757368546f4c6f636b65724d756c7469455260008201527f433732312829202163616e507573684d756c7469455243373231282900000000602082015250565b600061450c603c8361377f565b9150614517826144b0565b604082019050919050565b6000602082019050818103600083015261453b816144ff565b9050919050565b7f4f43525f496e7374616e743a3a70756c6c46726f6d4c6f636b6572282920617360008201527f73657420213d2061555344430000000000000000000000000000000000000000602082015250565b600061459e602c8361377f565b91506145a982614542565b604082019050919050565b600060208201905081810360008301526145cd81614591565b9050919050565b60006145ef6145ea6145e584613dcb565b613de3565b612e22565b9050919050565b6145ff816145d4565b82525050565b600060408201905061461a60008301856134a3565b61462760208301846145f6565b9392505050565b7f5a69766f654c6f636b65723a3a70756c6c46726f6d4c6f636b65724d756c746960008201527f5061727469616c2829202163616e50756c6c4d756c74695061727469616c2829602082015250565b600061468a60408361377f565b91506146958261462e565b604082019050919050565b600060208201905081810360008301526146b98161467d565b9050919050565b7f4f43525f496e7374616e743a3a70756c6c46726f6d4c6f636b6572506172746960008201527f616c282920617373657420213d20615553444300000000000000000000000000602082015250565b600061471c60338361377f565b9150614727826146c0565b604082019050919050565b6000602082019050818103600083015261474b8161470f565b9050919050565b7f4f776e61626c654c6f636b65643a3a7472616e736665724f776e65727368697060008201527f2829206e65774f776e6572203d3d206164647265737328302900000000000000602082015250565b60006147ae60398361377f565b91506147b982614752565b604082019050919050565b600060208201905081810360008301526147dd816147a1565b9050919050565b7f5a69766f654c6f636b65723a3a70757368546f4c6f636b65724552433131353560008201527f2829202163616e50757368455243313135352829000000000000000000000000602082015250565b600061484060348361377f565b915061484b826147e4565b604082019050919050565b6000602082019050818103600083015261486f81614833565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006148ac60208361377f565b91506148b782614876565b602082019050919050565b600060208201905081810360008301526148db8161489f565b9050919050565b60006040820190506148f76000830185613356565b61490460208301846134a3565b9392505050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614941601f8361377f565b915061494c8261490b565b602082019050919050565b6000602082019050818103600083015261497081614934565b9050919050565b600060608201905061498c6000830186613356565b6149996020830185613356565b6149a660408301846134a3565b949350505050565b60006040820190506149c36000830185613356565b6149d06020830184613356565b9392505050565b7f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000602082015250565b6000614a3360368361377f565b9150614a3e826149d7565b604082019050919050565b60006020820190508181036000830152614a6281614a26565b9050919050565b614a7281612d8e565b8114614a7d57600080fd5b50565b600081519050614a8f81614a69565b92915050565b600060208284031215614aab57614aaa612cff565b5b6000614ab984828501614a80565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000614b1e602a8361377f565b9150614b2982614ac2565b604082019050919050565b60006020820190508181036000830152614b4d81614b11565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000614bb060268361377f565b9150614bbb82614b54565b604082019050919050565b60006020820190508181036000830152614bdf81614ba3565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015614c1a578082015181840152602081019050614bff565b60008484015250505050565b6000614c3182614be6565b614c3b8185614bf1565b9350614c4b818560208601614bfc565b80840191505092915050565b6000614c638284614c26565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000614ca4601d8361377f565b9150614caf82614c6e565b602082019050919050565b60006020820190508181036000830152614cd381614c97565b9050919050565b600081519050919050565b6000614cf082614cda565b614cfa818561377f565b9350614d0a818560208601614bfc565b614d1381612f36565b840191505092915050565b60006020820190508181036000830152614d388184614ce5565b90509291505056fea2646970667358221220b1a8b62b0f79de5f019373cd220728ab12062cff0612628ae0ac9a43fac8604364736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b65a66621d7de34afec9b9ac0755133051550dd7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da6600000000000000000000000094babe9ee75c38034920bc6ed42748e8eefbedd40000000000000000000000007aa5bf30042b2145b9f0629ea68de55b42ad3bb600000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e200000000000000000000000098c23e9d8f34fefb1b7bd6a91b7ff122f4e16f5c000000000000000000000000000000000000000000000000000000000000004b
-----Decoded View---------------
Arg [0] : DAO (address): 0xB65a66621D7dE34afec9b9AC0755133051550dD7
Arg [1] : _USDC (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [2] : _GBL (address): 0xEa537eB0bBcC7783bDF7c595bF9371984583dA66
Arg [3] : _zVLT (address): 0x94BaBe9Ee75C38034920bC6ed42748E8eEFbedd4
Arg [4] : _zSTT (address): 0x7aA5Bf30042b2145B9F0629ea68De55B42ad3BB6
Arg [5] : _AAVE_V3_POOL (address): 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2
Arg [6] : _aUSDC (address): 0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c
Arg [7] : _redemptionFeeBIPS (uint16): 75
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000b65a66621d7de34afec9b9ac0755133051550dd7
Arg [1] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [2] : 000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da66
Arg [3] : 00000000000000000000000094babe9ee75c38034920bc6ed42748e8eefbedd4
Arg [4] : 0000000000000000000000007aa5bf30042b2145b9f0629ea68de55b42ad3bb6
Arg [5] : 00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e2
Arg [6] : 00000000000000000000000098c23e9d8f34fefb1b7bd6a91b7ff122f4e16f5c
Arg [7] : 000000000000000000000000000000000000000000000000000000000000004b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.