Source Code
Latest 13 from a total of 13 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Distribute Yield | 23764248 | 8 days ago | IN | 0 ETH | 0.0009539 | ||||
| Distribute Yield | 23549063 | 38 days ago | IN | 0 ETH | 0.00137908 | ||||
| Distribute Yield | 23334317 | 68 days ago | IN | 0 ETH | 0.00121801 | ||||
| Distribute Yield | 23119129 | 98 days ago | IN | 0 ETH | 0.00137955 | ||||
| Distribute Yield | 22894869 | 129 days ago | IN | 0 ETH | 0.00235571 | ||||
| Distribute Yield | 22668408 | 161 days ago | IN | 0 ETH | 0.00129289 | ||||
| Distribute Yield | 22539071 | 179 days ago | IN | 0 ETH | 0.00026508 | ||||
| Distribute Yield | 22441143 | 193 days ago | IN | 0 ETH | 0.00259257 | ||||
| Distribute Yield | 22175854 | 230 days ago | IN | 0 ETH | 0.00055993 | ||||
| Distribute Yield | 21939602 | 263 days ago | IN | 0 ETH | 0.0003728 | ||||
| Distribute Yield | 21687468 | 298 days ago | IN | 0 ETH | 0.00828328 | ||||
| Distribute Yield | 21467211 | 329 days ago | IN | 0 ETH | 0.0067909 | ||||
| Distribute Yield | 21248166 | 359 days ago | IN | 0 ETH | 0.00756504 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
To
|
|||
|---|---|---|---|---|---|---|---|
| 0x60806040 | 20359446 | 483 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ZivoeYDL
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 10 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "./ZivoeMath.sol";
import "./libraries/FloorMath.sol";
import "../lib/openzeppelin-contracts/contracts/utils/Context.sol";
import "../lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol";
import "../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "../lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
interface IZivoeGlobals_YDL {
/// @notice Returns the address of the ZivoeDAO contract.
function DAO() external view returns (address);
/// @notice Returns the address of the ZivoeITO contract.
function ITO() external view returns (address);
/// @notice Returns the address of the ZivoeRewards ($zSTT) contract.
function stSTT() external view returns (address);
/// @notice Returns the address of the ZivoeRewards ($zJTT) contract.
function stJTT() external view returns (address);
/// @notice Returns the address of the ZivoeRewards ($ZVE) contract.
function stZVE() external view returns (address);
/// @notice Returns the address of the Timelock contract.
function TLC() external view returns (address);
/// @notice Returns the address of the ZivoeRewardsVesting ($ZVE) vesting contract.
function vestZVE() external view returns (address);
/// @notice Returns the address of the ZivoeTrancheToken ($zSTT) contract.
function zSTT() external view returns (address);
/// @notice Returns the address of the ZivoeTrancheToken ($zJTT) contract.
function zJTT() external view returns (address);
/// @notice Returns the address of the Zivoe Laboratory.
function ZVL() external view returns (address);
/// @notice Returns total circulating supply of zSTT and zJTT, accounting for defaults via markdowns.
/// @return zSTTSupply zSTT.totalSupply() adjusted for defaults.
/// @return zJTTSupply zJTT.totalSupply() adjusted for defaults.
function adjustedSupplies() external view returns (uint256 zSTTSupply, uint256 zJTTSupply);
/// @notice Handles WEI standardization of a given asset amount (i.e. 6 decimal precision => 18 decimal precision).
/// @param amount The amount of a given "asset".
/// @param asset The asset (ERC-20) from which to standardize the amount to WEI.
/// @return standardizedAmount The above amount standardized to 18 decimals.
function standardize(uint256 amount, address asset) external view returns (uint256 standardizedAmount);
/// @notice This function will verify if a given stablecoin has been whitelisted for use throughout system.
/// @param stablecoin address of the stablecoin to verify acceptance for.
function stablecoinWhitelist(address stablecoin) external view returns (bool);
}
interface IZivoeRewards_YDL {
/// @notice Deposits a reward to this contract for distribution.
/// @param _rewardsToken The asset that's being distributed.
/// @param reward The amount of the _rewardsToken to deposit.
function depositReward(address _rewardsToken, uint256 reward) external;
}
/// @notice This contract manages the accounting for distributing yield across multiple contracts.
/// This contract has the following responsibilities:
/// - Escrows yield in between distribution periods.
/// - Manages accounting for yield distribution.
/// - Supports modification of certain state variables for governance purposes.
/// - Tracks historical values using EMA (exponential moving average) on 30-day basis.
contract ZivoeYDL is Context, ReentrancyGuard {
using SafeERC20 for IERC20;
using FloorMath for uint256;
// ---------------------
// State Variables
// ---------------------
struct Recipients {
address[] recipients;
uint256[] proportion;
}
Recipients protocolRecipients; /// @dev Tracks the distributions for protocol earnings.
Recipients residualRecipients; /// @dev Tracks the distributions for residual earnings.
address public immutable GBL; /// @dev The ZivoeGlobals contract.
address public distributedAsset; /// @dev The "stablecoin" that will be distributed via YDL.
// Weighted moving averages.
uint256 public emaSTT; /// @dev Weighted moving average for senior tranche size, a.k.a. zSTT.totalSupply().
uint256 public emaJTT; /// @dev Weighted moving average for junior tranche size, a.k.a. zJTT.totalSupply().
// Indexing.
uint256 public distributionCounter = 1; /// @dev Number of calls to distributeYield().
uint256 public lastDistribution; /// @dev Used for timelock constraint to call distributeYield().
// Accounting vars (governable).
uint256 public targetAPYBIPS = 1000; /// @dev The target annualized yield for senior tranche.
uint256 public targetRatioBIPS = 22000; /// @dev The target ratio of junior to senior tranche.
uint256 public protocolEarningsRateBIPS = 2000; /// @dev The protocol earnings rate.
// Accounting vars (constant).
uint256 public constant daysBetweenDistributions = 30; /// @dev Number of days between yield distributions.
uint256 public constant retrospectiveDistributions = 6; /// @dev Retrospective moving average period.
bool public unlocked; /// @dev Prevents contract from supporting functionality until unlocked.
uint256 private constant BIPS = 10000;
uint256 private constant RAY = 10 ** 27;
ZivoeMath public MATH;
// -----------------
// Constructor
// -----------------
/// @notice Initialize the ZivoeYDL contract.
/// @param _GBL The ZivoeGlobals contract.
/// @param _distributedAsset The "stablecoin" that will be distributed via YDL.
constructor(address _GBL, address _distributedAsset) {
GBL = _GBL;
distributedAsset = _distributedAsset;
MATH = new ZivoeMath();
}
// ------------
// Events
// ------------
/// @notice Emitted during returnAsset().
/// @param asset The asset returned.
/// @param amount The amount of "asset" returned to DAO.
event AssetReturned(address indexed asset, uint256 amount);
/// @notice Emitted during updateDistributedAsset().
/// @param oldAsset The old value of distributedAsset.
/// @param newAsset The new value of distributedAsset.
event UpdatedDistributedAsset(address indexed oldAsset, address indexed newAsset);
/// @notice Emitted during updateProtocolEarningsRateBIPS().
/// @param oldValue The old value of protocolEarningsRateBIPS.
/// @param newValue The new value of protocolEarningsRateBIPS.
event UpdatedProtocolEarningsRateBIPS(uint256 oldValue, uint256 newValue);
/// @notice Emitted during updateRecipients().
/// @param recipients The new recipients to receive protocol earnings.
/// @param proportion The proportion distributed across recipients.
event UpdatedProtocolRecipients(address[] recipients, uint256[] proportion);
/// @notice Emitted during updateRecipients().
/// @param recipients The new recipients to receive residual earnings.
/// @param proportion The proportion distributed across recipients.
event UpdatedResidualRecipients(address[] recipients, uint256[] proportion);
/// @notice Emitted during updateTargetAPYBIPS().
/// @param oldValue The old value of targetAPYBIPS.
/// @param newValue The new value of targetAPYBIPS.
event UpdatedTargetAPYBIPS(uint256 oldValue, uint256 newValue);
/// @notice Emitted during updateTargetRatioBIPS().
/// @param oldValue The old value of targetRatioBIPS.
/// @param newValue The new value of targetRatioBIPS.
event UpdatedTargetRatioBIPS(uint256 oldValue, uint256 newValue);
/// @notice Emitted during distributeYield().
/// @param protocol The amount of earnings distributed to protocol earnings recipients.
/// @param senior The amount of earnings distributed to the senior tranche.
/// @param junior The amount of earnings distributed to the junior tranche.
/// @param residual The amount of earnings distributed to residual earnings recipients.
event YieldDistributed(uint256[] protocol, uint256 senior, uint256 junior, uint256[] residual);
/// @notice Emitted during distributeYield().
/// @param asset The "asset" being distributed.
/// @param recipient The recipient of the distribution.
/// @param amount The amount distributed.
event YieldDistributedSingle(address indexed asset, address indexed recipient, uint256 amount);
// ---------------
// Functions
// ---------------
/// @notice View distribution information for protocol and residual earnings recipients.
/// @return protocolEarningsRecipients The destinations for protocol earnings distributions.
/// @return protocolEarningsProportion The proportions for protocol earnings distributions.
/// @return residualEarningsRecipients The destinations for residual earnings distributions.
/// @return residualEarningsProportion The proportions for residual earnings distributions.
function viewDistributions() external view returns (
address[] memory protocolEarningsRecipients, uint256[] memory protocolEarningsProportion,
address[] memory residualEarningsRecipients, uint256[] memory residualEarningsProportion
) {
return (
protocolRecipients.recipients,
protocolRecipients.proportion,
residualRecipients.recipients,
residualRecipients.proportion
);
}
/// @notice Distributes available yield within this contract to appropriate entities.
function distributeYield() external nonReentrant {
require(unlocked, "ZivoeYDL::distributeYield() !unlocked");
require(
block.timestamp >= lastDistribution + daysBetweenDistributions * 86400,
"ZivoeYDL::distributeYield() block.timestamp < lastDistribution + daysBetweenDistributions * 86400"
);
// Calculate protocol earnings.
uint256 earnings = IERC20(distributedAsset).balanceOf(address(this));
uint256 protocolEarnings = protocolEarningsRateBIPS * earnings / BIPS;
uint256 postFeeYield = earnings.floorSub(protocolEarnings);
// Update timeline.
distributionCounter += 1;
lastDistribution = block.timestamp;
// Update ema-based supply values.
(uint256 aSTT, uint256 aJTT) = IZivoeGlobals_YDL(GBL).adjustedSupplies();
emaSTT = MATH.ema(emaSTT, aSTT, retrospectiveDistributions.min(distributionCounter));
emaJTT = MATH.ema(emaJTT, aJTT, retrospectiveDistributions.min(distributionCounter));
// Calculate yield distribution (trancheuse = "slicer" in French).
(
uint256[] memory _protocol, uint256 _seniorTranche, uint256 _juniorTranche, uint256[] memory _residual
) = earningsTrancheuse(protocolEarnings, postFeeYield);
emit YieldDistributed(_protocol, _seniorTranche, _juniorTranche, _residual);
// Distribute protocol earnings.
for (uint256 i = 0; i < protocolRecipients.recipients.length; i++) {
address _recipient = protocolRecipients.recipients[i];
if (_recipient == IZivoeGlobals_YDL(GBL).stSTT() ||_recipient == IZivoeGlobals_YDL(GBL).stJTT()) {
IERC20(distributedAsset).safeIncreaseAllowance(_recipient, _protocol[i]);
IZivoeRewards_YDL(_recipient).depositReward(distributedAsset, _protocol[i]);
emit YieldDistributedSingle(distributedAsset, _recipient, _protocol[i]);
}
else if (_recipient == IZivoeGlobals_YDL(GBL).stZVE()) {
uint stZVEAllocation = _protocol[i] * (IERC20(IZivoeGlobals_YDL(GBL).stZVE()).totalSupply() * BIPS) /
(BIPS * (IERC20(IZivoeGlobals_YDL(GBL).stZVE()).totalSupply() +
IERC20(IZivoeGlobals_YDL(GBL).vestZVE()).totalSupply()));
uint vestZVEAllocation = _protocol[i] * (IERC20(IZivoeGlobals_YDL(GBL).vestZVE()).totalSupply() * BIPS) /
(BIPS * (IERC20(IZivoeGlobals_YDL(GBL).stZVE()).totalSupply() +
IERC20(IZivoeGlobals_YDL(GBL).vestZVE()).totalSupply()));
IERC20(distributedAsset).safeIncreaseAllowance(IZivoeGlobals_YDL(GBL).stZVE(), stZVEAllocation);
IERC20(distributedAsset).safeIncreaseAllowance(IZivoeGlobals_YDL(GBL).vestZVE(),vestZVEAllocation);
IZivoeRewards_YDL(IZivoeGlobals_YDL(GBL).stZVE()).depositReward(distributedAsset, stZVEAllocation);
IZivoeRewards_YDL(IZivoeGlobals_YDL(GBL).vestZVE()).depositReward(distributedAsset, vestZVEAllocation);
emit YieldDistributedSingle(distributedAsset, IZivoeGlobals_YDL(GBL).stZVE(), stZVEAllocation);
emit YieldDistributedSingle(distributedAsset, IZivoeGlobals_YDL(GBL).vestZVE(), vestZVEAllocation);
}
else {
IERC20(distributedAsset).safeTransfer(_recipient, _protocol[i]);
emit YieldDistributedSingle(distributedAsset, _recipient, _protocol[i]);
}
}
// Distribute senior and junior tranche earnings.
IERC20(distributedAsset).safeIncreaseAllowance(IZivoeGlobals_YDL(GBL).stSTT(), _seniorTranche);
IERC20(distributedAsset).safeIncreaseAllowance(IZivoeGlobals_YDL(GBL).stJTT(), _juniorTranche);
IZivoeRewards_YDL(IZivoeGlobals_YDL(GBL).stSTT()).depositReward(distributedAsset, _seniorTranche);
IZivoeRewards_YDL(IZivoeGlobals_YDL(GBL).stJTT()).depositReward(distributedAsset, _juniorTranche);
emit YieldDistributedSingle(distributedAsset, IZivoeGlobals_YDL(GBL).stSTT(), _seniorTranche);
emit YieldDistributedSingle(distributedAsset, IZivoeGlobals_YDL(GBL).stJTT(), _juniorTranche);
// Distribute residual earnings.
for (uint256 i = 0; i < residualRecipients.recipients.length; i++) {
if (_residual[i] > 0) {
address _recipient = residualRecipients.recipients[i];
if (_recipient == IZivoeGlobals_YDL(GBL).stSTT() ||_recipient == IZivoeGlobals_YDL(GBL).stJTT()) {
IERC20(distributedAsset).safeIncreaseAllowance(_recipient, _residual[i]);
IZivoeRewards_YDL(_recipient).depositReward(distributedAsset, _residual[i]);
emit YieldDistributedSingle(distributedAsset, _recipient, _residual[i]);
}
else if (_recipient == IZivoeGlobals_YDL(GBL).stZVE()) {
uint stZVEAllocation = _residual[i] * (IERC20(IZivoeGlobals_YDL(GBL).stZVE()).totalSupply() * BIPS) /
(BIPS * (IERC20(IZivoeGlobals_YDL(GBL).stZVE()).totalSupply() +
IERC20(IZivoeGlobals_YDL(GBL).vestZVE()).totalSupply()));
uint vestZVEAllocation = _residual[i] * (IERC20(IZivoeGlobals_YDL(GBL).vestZVE()).totalSupply() * BIPS) /
(BIPS * (IERC20(IZivoeGlobals_YDL(GBL).stZVE()).totalSupply() +
IERC20(IZivoeGlobals_YDL(GBL).vestZVE()).totalSupply()));
IERC20(distributedAsset).safeIncreaseAllowance(IZivoeGlobals_YDL(GBL).stZVE(), stZVEAllocation);
IERC20(distributedAsset).safeIncreaseAllowance(IZivoeGlobals_YDL(GBL).vestZVE(), vestZVEAllocation);
IZivoeRewards_YDL(IZivoeGlobals_YDL(GBL).stZVE()).depositReward(distributedAsset, stZVEAllocation);
IZivoeRewards_YDL(IZivoeGlobals_YDL(GBL).vestZVE()).depositReward(distributedAsset, vestZVEAllocation);
emit YieldDistributedSingle(distributedAsset, IZivoeGlobals_YDL(GBL).stZVE(), stZVEAllocation);
emit YieldDistributedSingle(distributedAsset, IZivoeGlobals_YDL(GBL).vestZVE(), vestZVEAllocation);
}
else {
IERC20(distributedAsset).safeTransfer(_recipient, _residual[i]);
emit YieldDistributedSingle(distributedAsset, _recipient, _residual[i]);
}
}
}
}
/// @notice Returns an asset to DAO if not distributedAsset().
/// @param asset The asset to return.
function returnAsset(address asset) external {
require(asset != distributedAsset, "ZivoeYDL::returnAsset() asset == distributedAsset");
emit AssetReturned(asset, IERC20(asset).balanceOf(address(this)));
IERC20(asset).safeTransfer(IZivoeGlobals_YDL(GBL).DAO(), IERC20(asset).balanceOf(address(this)));
}
/// @notice Unlocks this contract for distributions, initializes values.
function unlock() external {
require(
_msgSender() == IZivoeGlobals_YDL(GBL).ITO(),
"ZivoeYDL::unlock() _msgSender() != IZivoeGlobals_YDL(GBL).ITO()"
);
unlocked = true;
lastDistribution = block.timestamp + 30 days;
emaSTT = IERC20(IZivoeGlobals_YDL(GBL).zSTT()).totalSupply();
emaJTT = IERC20(IZivoeGlobals_YDL(GBL).zJTT()).totalSupply();
address[] memory protocolRecipientAcc = new address[](2);
uint256[] memory protocolRecipientAmt = new uint256[](2);
protocolRecipientAcc[0] = address(IZivoeGlobals_YDL(GBL).stZVE());
protocolRecipientAmt[0] = 6666;
protocolRecipientAcc[1] = address(IZivoeGlobals_YDL(GBL).ZVL());
protocolRecipientAmt[1] = 3334;
protocolRecipients = Recipients(protocolRecipientAcc, protocolRecipientAmt);
address[] memory residualRecipientAcc = new address[](2);
uint256[] memory residualRecipientAmt = new uint256[](2);
residualRecipientAcc[0] = address(IZivoeGlobals_YDL(GBL).stZVE());
residualRecipientAmt[0] = 6666;
residualRecipientAcc[1] = address(IZivoeGlobals_YDL(GBL).ZVL());
residualRecipientAmt[1] = 3334;
residualRecipients = Recipients(residualRecipientAcc, residualRecipientAmt);
}
/// @notice Updates the distributed asset for this particular contract.
/// @param _distributedAsset The new value for distributedAsset.
function updateDistributedAsset(address _distributedAsset) external nonReentrant {
require(
_distributedAsset != distributedAsset,
"ZivoeYDL::updateDistributedAsset() _distributedAsset == distributedAsset"
);
require(
_msgSender() == IZivoeGlobals_YDL(GBL).TLC(),
"ZivoeYDL::updateDistributedAsset() _msgSender() != TLC()"
);
require(
IZivoeGlobals_YDL(GBL).stablecoinWhitelist(_distributedAsset),
"ZivoeYDL::updateDistributedAsset() !IZivoeGlobals_YDL(GBL).stablecoinWhitelist(_distributedAsset)"
);
emit UpdatedDistributedAsset(distributedAsset, _distributedAsset);
distributedAsset = _distributedAsset;
}
/// @notice Updates the state variable "protocolEarningsRateBIPS".
/// @param _protocolEarningsRateBIPS The new value for protocolEarningsRateBIPS.
function updateProtocolEarningsRateBIPS(uint256 _protocolEarningsRateBIPS) external {
require(
_msgSender() == IZivoeGlobals_YDL(GBL).TLC(),
"ZivoeYDL::updateProtocolEarningsRateBIPS() _msgSender() != TLC()"
);
require(
_protocolEarningsRateBIPS <= 9000,
"ZivoeYDL::updateProtocolEarningsRateBIPS() _protocolEarningsRateBIPS > 9000"
);
emit UpdatedProtocolEarningsRateBIPS(protocolEarningsRateBIPS, _protocolEarningsRateBIPS);
protocolEarningsRateBIPS = _protocolEarningsRateBIPS;
}
/// @notice Updates the protocolRecipients or residualRecipients.
/// @param recipients An array of addresses to which protocol earnings will be distributed.
/// @param proportions An array of ratios relative to the recipients - in BIPS. Sum should equal to 10000.
/// @param protocol Specify "true" to update protocol earnings, or "false" to update residual earnings.
function updateRecipients(address[] memory recipients, uint256[] memory proportions, bool protocol) external {
require(_msgSender() == IZivoeGlobals_YDL(GBL).TLC(), "ZivoeYDL::updateRecipients() _msgSender() != TLC()");
require(
recipients.length == proportions.length && recipients.length > 0,
"ZivoeYDL::updateRecipients() recipients.length != proportions.length || recipients.length == 0"
);
require(unlocked, "ZivoeYDL::updateRecipients() !unlocked");
uint256 proportionTotal;
for (uint256 i = 0; i < recipients.length; i++) {
proportionTotal += proportions[i];
require(proportions[i] > 0, "ZivoeYDL::updateRecipients() proportions[i] == 0");
require(recipients[i] != address(0), "ZivoeYDL::updateRecipients() recipients[i] == address(0)");
}
require(proportionTotal == BIPS, "ZivoeYDL::updateRecipients() proportionTotal != BIPS (10,000)");
if (protocol) {
emit UpdatedProtocolRecipients(recipients, proportions);
protocolRecipients = Recipients(recipients, proportions);
}
else {
emit UpdatedResidualRecipients(recipients, proportions);
residualRecipients = Recipients(recipients, proportions);
}
}
/// @notice Updates the state variable "targetAPYBIPS".
/// @param _targetAPYBIPS The new value for targetAPYBIPS.
function updateTargetAPYBIPS(uint256 _targetAPYBIPS) external {
require(_msgSender() == IZivoeGlobals_YDL(GBL).TLC(), "ZivoeYDL::updateTargetAPYBIPS() _msgSender() != TLC()");
emit UpdatedTargetAPYBIPS(targetAPYBIPS, _targetAPYBIPS);
targetAPYBIPS = _targetAPYBIPS;
}
/// @notice Updates the state variable "targetRatioBIPS".
/// @param _targetRatioBIPS The new value for targetRatioBIPS.
function updateTargetRatioBIPS(uint256 _targetRatioBIPS) external {
require(_msgSender() == IZivoeGlobals_YDL(GBL).TLC(), "ZivoeYDL::updateTargetRatioBIPS() _msgSender() != TLC()");
emit UpdatedTargetRatioBIPS(targetRatioBIPS, _targetRatioBIPS);
targetRatioBIPS = _targetRatioBIPS;
}
// ----------
// Math
// ----------
/// @notice Calculates the distribution of yield ("earnings") for the four primary groups.
/// @param yP Yield for the protocol.
/// @param yD Yield for the remaining three groups.
/// @return protocol Protocol earnings.
/// @return senior Senior tranche earnings.
/// @return junior Junior tranche earnings.
/// @return residual Residual earnings.
function earningsTrancheuse(uint256 yP, uint256 yD) public view returns (
uint256[] memory protocol, uint256 senior, uint256 junior, uint256[] memory residual
) {
protocol = new uint256[](protocolRecipients.recipients.length);
residual = new uint256[](residualRecipients.recipients.length);
// Accounting for protocol earnings.
for (uint256 i = 0; i < protocolRecipients.recipients.length; i++) {
protocol[i] = protocolRecipients.proportion[i] * yP / BIPS;
}
// Accounting for senior and junior earnings.
uint256 _seniorProportion = MATH.seniorProportion(
IZivoeGlobals_YDL(GBL).standardize(yD, distributedAsset),
MATH.yieldTarget(emaSTT, emaJTT, targetAPYBIPS, targetRatioBIPS, daysBetweenDistributions),
emaSTT, emaJTT, targetAPYBIPS, targetRatioBIPS, daysBetweenDistributions
);
senior = (yD * _seniorProportion) / RAY;
junior = (yD * MATH.juniorProportion(emaSTT, emaJTT, _seniorProportion, targetRatioBIPS)) / RAY;
// Handle accounting for residual earnings.
yD = yD.floorSub(senior + junior);
for (uint256 i = 0; i < residualRecipients.recipients.length; i++) {
residual[i] = residualRecipients.proportion[i] * yD / BIPS;
}
}
}// 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: 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.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) (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/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: UNLICENSED
pragma solidity ^0.8.17;
/// @notice Specialized math functions that always return uint256 and never revert.
/// This condenses and simplifies the codebase, for example trySub() from OpenZeppelin
/// would have sufficed, however they returned tuples to include information
/// about the success of the function, which is inefficient for our purposes.
library FloorMath {
/// @notice Returns 0 if divisions results in value less than 1, or division by zero.
function floorDiv(uint256 x, uint256 y) internal pure returns (uint256) {
unchecked {
if (y == 0) return 0;
if (y > x) return 0;
return (x / y);
}
}
/// @notice The return value is if subtraction results in underflow.
/// Subtraction routine that does not revert and returns a singleton,
/// making it cheaper and more suitable for composition and use as an attribute.
/// It was made to be a cheaper version of openZepelins trySub.
function floorSub(uint256 x, uint256 y) internal pure returns (uint256) {
unchecked {
if (y > x) return 0;
return (x - y);
}
}
/// @notice Returns the smallest of two numbers.
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "./libraries/FloorMath.sol";
/// @notice This contract facilitates mathematics, intended solely for the YDL.
contract ZivoeMath {
using FloorMath for uint256;
// ---------------------
// State Variables
// ---------------------
uint256 private constant BIPS = 10000;
uint256 private constant WAD = 10 ** 18;
uint256 private constant RAY = 10 ** 27;
// ----------
// Math
// ----------
/**
@notice Calculates the current EMA (exponential moving average).
@dev M * cV + (1 - M) * bV, where our smoothing factor M = 2 / (N + 1)
@param bV = The base value (typically an EMA from prior calculations).
@param cV = The current value, which is factored into bV.
@param N = Number of steps to average over.
@return eV = EMA-based value given prior and current conditions.
*/
function ema(uint256 bV, uint256 cV, uint256 N) external pure returns (uint256 eV) {
assert(N != 0);
uint256 M = (WAD * 2).floorDiv(N + 1);
eV = ((M * cV) + (WAD - M) * bV).floorDiv(WAD);
}
/**
@notice Calculates proportion of yield attributable to junior tranche.
@dev (Q * eJTT * sP / BIPS).floorDiv(eSTT).min(RAY - sP)
@param eSTT = ema-based supply of zSTT (units = WEI)
@param eJTT = ema-based supply of zJTT (units = WEI)
@param sP = Proportion of yield attributable to seniors (units = RAY)
@param Q = junior to senior tranche target ratio (units = BIPS)
@return jP = Yield attributable to junior tranche in RAY.
@dev Precision of return value, jP, is in RAY (10**27).
@dev The return value for this equation MUST never exceed RAY (10**27).
*/
function juniorProportion(uint256 eSTT, uint256 eJTT, uint256 sP, uint256 Q) external pure returns (uint256 jP) {
if (sP <= RAY) { jP = (Q * eJTT * sP / BIPS).floorDiv(eSTT).min(RAY - sP); }
}
/**
@notice Calculates proportion of yield distributble which is attributable to the senior tranche.
@param yD = yield distributable (units = WEI)
@param yT = ema-based yield target (units = WEI)
@param eSTT = ema-based supply of zSTT (units = WEI)
@param eJTT = ema-based supply of zJTT (units = WEI)
@param Y = target annual yield for senior tranche (units = BIPS)
@param Q = multiple of Y (units = BIPS)
@param T = # of days between distributions (units = integer)
@return sP = Proportion of yD attributable to senior tranche.
@dev Precision of return value, sP, is in RAY (10**27).
*/
function seniorProportion(
uint256 yD, uint256 yT, uint256 eSTT, uint256 eJTT, uint256 Y, uint256 Q, uint256 T
) external pure returns (uint256 sP) {
// Shortfall of yield.
if (yD < yT) { sP = seniorProportionShortfall(eSTT, eJTT, Q); }
// Excess yield and historical out-performance.
else { sP = seniorProportionBase(yD, eSTT, Y, T); }
}
/**
@notice Calculates proportion of yield attributed to senior tranche (no extenuating circumstances).
@dev Y * eSTT * T
----------------- * RAY
(365) * yD
@param yD = yield distributable (units = WEI)
@param eSTT = ema-based supply of zSTT (units = WEI)
@param Y = target annual yield for senior tranche (units = BIPS)
@param T = # of days between distributions (units = integer)
@return sPB = Proportion of yield attributed to senior tranche in RAY.
@dev Precision of return value, sRB, is in RAY (10**27).
*/
function seniorProportionBase(uint256 yD, uint256 eSTT, uint256 Y, uint256 T) public pure returns (uint256 sPB) {
sPB = ((RAY * Y * (eSTT) * T / BIPS) / 365).floorDiv(yD).min(RAY);
}
/**
@notice Calculates proportion of yield attributed to senior tranche (shortfall occurence).
@dev WAD
-------------------------------- * RAY
Q * eJTT * WAD / BIPS
WAD + ---------------------
eSTT
@param eSTT = ema-based supply of zSTT (units = WEI)
@param eJTT = ema-based supply of zJTT (units = WEI)
@param Q = junior to senior tranche target ratio (units = integer)
@return sPS = Proportion of yield attributed to senior tranche in RAY.
@dev Precision of return value, sPS, is in RAY (10**27).
*/
function seniorProportionShortfall(uint256 eSTT, uint256 eJTT, uint256 Q) public pure returns (uint256 sPS) {
sPS = (WAD * RAY).floorDiv(WAD + (Q * eJTT * WAD / BIPS).floorDiv(eSTT)).min(RAY);
}
/**
@notice Calculates amount of annual yield required to meet target rate for both tranches.
@dev (Y * T * (eSTT + eJTT * Q / BIPS) / BIPS) / 365
@param eSTT = ema-based supply of zSTT (units = WEI)
@param eJTT = ema-based supply of zJTT (units = WEI)
@param Y = target annual yield for senior tranche (units = BIPS)
@param Q = multiple of Y (units = BIPS)
@param T = # of days between distributions (units = integer)
@return yT = yield target for the senior and junior tranche combined.
@dev Precision of the return value, yT, is in WEI (10**18).
*/
function yieldTarget(uint256 eSTT, uint256 eJTT, uint256 Y, uint256 Q, uint256 T) public pure returns (uint256 yT) {
yT = (Y * T * (eSTT + eJTT * Q / BIPS) / BIPS) / 365;
}
}{
"optimizer": {
"enabled": true,
"runs": 10
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_GBL","type":"address"},{"internalType":"address","name":"_distributedAsset","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AssetReturned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAsset","type":"address"},{"indexed":true,"internalType":"address","name":"newAsset","type":"address"}],"name":"UpdatedDistributedAsset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdatedProtocolEarningsRateBIPS","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"recipients","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"proportion","type":"uint256[]"}],"name":"UpdatedProtocolRecipients","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"recipients","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"proportion","type":"uint256[]"}],"name":"UpdatedResidualRecipients","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdatedTargetAPYBIPS","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdatedTargetRatioBIPS","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"protocol","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"senior","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"junior","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"residual","type":"uint256[]"}],"name":"YieldDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"YieldDistributedSingle","type":"event"},{"inputs":[],"name":"GBL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MATH","outputs":[{"internalType":"contract ZivoeMath","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daysBetweenDistributions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributeYield","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributedAsset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributionCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"yP","type":"uint256"},{"internalType":"uint256","name":"yD","type":"uint256"}],"name":"earningsTrancheuse","outputs":[{"internalType":"uint256[]","name":"protocol","type":"uint256[]"},{"internalType":"uint256","name":"senior","type":"uint256"},{"internalType":"uint256","name":"junior","type":"uint256"},{"internalType":"uint256[]","name":"residual","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emaJTT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emaSTT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastDistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolEarningsRateBIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"retrospectiveDistributions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"returnAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"targetAPYBIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetRatioBIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_distributedAsset","type":"address"}],"name":"updateDistributedAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_protocolEarningsRateBIPS","type":"uint256"}],"name":"updateProtocolEarningsRateBIPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"proportions","type":"uint256[]"},{"internalType":"bool","name":"protocol","type":"bool"}],"name":"updateRecipients","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_targetAPYBIPS","type":"uint256"}],"name":"updateTargetAPYBIPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_targetRatioBIPS","type":"uint256"}],"name":"updateTargetRatioBIPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"viewDistributions","outputs":[{"internalType":"address[]","name":"protocolEarningsRecipients","type":"address[]"},{"internalType":"uint256[]","name":"protocolEarningsProportion","type":"uint256[]"},{"internalType":"address[]","name":"residualEarningsRecipients","type":"address[]"},{"internalType":"uint256[]","name":"residualEarningsProportion","type":"uint256[]"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a060405260016008556103e8600a556155f0600b556107d0600c553480156200002857600080fd5b5060405162005464380380620054648339810160408190526200004b91620000fa565b60016000556001600160a01b03828116608052600580546001600160a01b0319169183169190911790556040516200008390620000cf565b604051809103906000f080158015620000a0573d6000803e3d6000fd5b50600d60016101000a8154816001600160a01b0302191690836001600160a01b03160217905550505062000132565b6105268062004f3e83390190565b80516001600160a01b0381168114620000f557600080fd5b919050565b600080604083850312156200010e57600080fd5b6200011983620000dd565b91506200012960208401620000dd565b90509250929050565b608051614c84620002ba6000396000818161015a0152818161043b015281816105f301528181610c8901528181610ef101528181610f8d0152818161113b015281816111d7015281816112ba015281816113b6015281816114d5015281816115b8015281816116b4015281816117d40152818161186c01528181611901015281816119e801528181611acf01528181611b8501528181611ce201528181611d7a01528181611dd801528181611ebf01528181611fa60152818161205c0152818161217901528181612215015281816123a50152818161244101528181612524015281816126200152818161273f015281816128220152818161291e01528181612a3e01528181612a9f01528181612afd01528181612be401528181612ccb01528181612d8101528181612f5e01528181613064015281816132e9015281816133e90152818161352c015281816136540152818161373d015281816138680152818161393f01528181613aab01528181613b8201528181613dd201526140d70152614c846000f3fe608060405234801561001057600080fd5b506004361061011d5760003560e01c806307061b941461012257806336b774a21461013d5780633ce8d432146101555780635df8d168146101895780636635e82c1461019c5780636a5e2650146101a55780636be09f77146101c2578063718bfc4c146101d75780638a570a12146101ea5780639048613a146101f25780639e3b5d2214610205578063a4abd79914610218578063a69df4b51461022b578063a717639c14610233578063a8e60c991461023c578063b9f543441461025f578063c2e63afa14610267578063c78f912a14610270578063c81a176614610279578063dd40482614610282578063e68c728914610295578063ed6c15461461029e578063feafdaa7146102b6575b600080fd5b61012a600681565b6040519081526020015b60405180910390f35b6101456102bf565b604051610134949392919061472a565b61017c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516101349190614777565b60055461017c906001600160a01b031681565b61012a600a5481565b600d546101b29060ff1681565b6040519015158152602001610134565b6101d56101d036600461478b565b610439565b005b6101d56101e53660046148ab565b6105f1565b6101d5610a9a565b6101d561020036600461497c565b612ed1565b6101d561021336600461497c565b6131ca565b6101d561022636600461478b565b6133e7565b6101d561352a565b61012a60095481565b61024f61024a366004614999565b613c89565b60405161013494939291906149bb565b61012a601e81565b61012a600b5481565b61012a60065481565b61012a60075481565b6101d561029036600461478b565b6140d5565b61012a600c5481565b600d5461017c9061010090046001600160a01b031681565b61012a60085481565b600180546040805160208084028201810190925282815260609384938493849360029260039260049291869183018282801561032457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610306575b505050505093508280548060200260200160405190810160405280929190818152602001828054801561037657602002820191906000526020600020905b815481526020019060010190808311610362575b50505050509250818054806020026020016040519081016040528092919081815260200182805480156103d257602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116103b4575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561042457602002820191906000526020600020905b815481526020019060010190808311610410575b50505050509050935093509350935090919293565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c76d41c86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bb91906149ec565b6001600160a01b0316336001600160a01b031614610536576040805162461bcd60e51b8152602060048201526024810191909152600080516020614baf83398151915260448201527f52617465424950532829205f6d736753656e646572282920213d20544c43282960648201526084015b60405180910390fd5b6123288111156105b05760405162461bcd60e51b815260206004820152604b6024820152600080516020614baf83398151915260448201527f52617465424950532829205f70726f746f636f6c4561726e696e67735261746560648201526a042495053203e20393030360ac1b608482015260a40161052d565b600c5460408051918252602082018390527f4fc744850bd93e9f01c96ffba23c38cd46e64cfc8b77e26df28f598a92f4895a910160405180910390a1600c55565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c76d41c86040518163ffffffff1660e01b8152600401602060405180830381865afa15801561064f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067391906149ec565b6001600160a01b0316336001600160a01b0316146106ee5760405162461bcd60e51b815260206004820152603260248201527f5a69766f6559444c3a3a757064617465526563697069656e74732829205f6d736044820152716753656e646572282920213d20544c43282960701b606482015260840161052d565b81518351148015610700575060008351115b6107865760405162461bcd60e51b815260206004820152605e6024820152600080516020614bcf83398151915260448201527f697069656e74732e6c656e67746820213d2070726f706f7274696f6e732e6c6560648201527f6e677468207c7c20726563697069656e74732e6c656e677468203d3d20300000608482015260a40161052d565b600d5460ff166107e75760405162461bcd60e51b815260206004820152602660248201527f5a69766f6559444c3a3a757064617465526563697069656e747328292021756e6044820152651b1bd8dad95960d21b606482015260840161052d565b6000805b84518110156109275783818151811061080657610806614a09565b6020026020010151826108199190614a35565b9150600084828151811061082f5761082f614a09565b60200260200101511161088b5760405162461bcd60e51b81526020600482015260306024820152600080516020614bef83398151915260448201526f0706f7274696f6e735b695d203d3d20360841b606482015260840161052d565b60006001600160a01b03168582815181106108a8576108a8614a09565b60200260200101516001600160a01b0316036109155760405162461bcd60e51b81526020600482015260386024820152600080516020614bcf833981519152604482015277697069656e74735b695d203d3d206164647265737328302960401b606482015260840161052d565b8061091f81614a48565b9150506107eb565b50612710811461098d5760405162461bcd60e51b815260206004820152603d6024820152600080516020614bef83398151915260448201527f706f7274696f6e546f74616c20213d2042495053202831302c30303029000000606482015260840161052d565b8115610a16577fb11a4b2b83a8e60adf2dadcbb51133b2ab7ce63ea9dc74f0621a7dcd41a578c384846040516109c4929190614a61565b60405180910390a160408051808201909152848152602080820185905285516001916109f4918391890190614601565b506020828101518051610a0d9260018501920190614666565b50905050610a94565b7fabde01bf2c50450e2dcb78815018bae0c080de9172fbcd2d6ecf9496558d2d218484604051610a47929190614a61565b60405180910390a16040805180820190915284815260208082018590528551600391610a77918391890190614601565b506020828101518051610a909260018501920190614666565b5050505b50505050565b610aa2614216565b600d5460ff16610b025760405162461bcd60e51b815260206004820152602560248201527f5a69766f6559444c3a3a646973747269627574655969656c6428292021756e6c6044820152641bd8dad95960da1b606482015260840161052d565b610b10601e62015180614a8f565b600954610b1d9190614a35565b421015610bc25760405162461bcd60e51b815260206004820152606160248201527f5a69766f6559444c3a3a646973747269627574655969656c64282920626c6f6360448201527f6b2e74696d657374616d70203c206c617374446973747269627574696f6e202b60648201527f20646179734265747765656e446973747269627574696f6e73202a20383634306084820152600360fc1b60a482015260c40161052d565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190610bf3903090600401614777565b602060405180830381865afa158015610c10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c349190614aa6565b9050600061271082600c54610c499190614a8f565b610c539190614abf565b90506000610c61838361426f565b9050600160086000828254610c769190614a35565b92505081905550426009819055506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635351d09b6040518163ffffffff1660e01b81526004016040805180830381865afa158015610ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d089190614ae1565b91509150600d60019054906101000a90046001600160a01b03166001600160a01b0316631bcba72760065484610d4a600854600661428c90919063ffffffff16565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa158015610d93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db79190614aa6565b6006908155600d546007546008546101009092046001600160a01b031692631bcba727928591610de69161428c565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa158015610e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e539190614aa6565b6007556000808080610e658888613c89565b93509350935093507fe51adb54e755c91701c15d94aa9a41d83c012ffd78f3acd465309018a69f39ce84848484604051610ea294939291906149bb565b60405180910390a160005b600154811015611cdc57600060016000018281548110610ecf57610ecf614a09565b9060005260206000200160009054906101000a90046001600160a01b031690507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166372ad4ba06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7191906149ec565b6001600160a01b0316816001600160a01b0316148061102257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d8c58b6a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100d91906149ec565b6001600160a01b0316816001600160a01b0316145b156111395761105b8187848151811061103d5761103d614a09565b60209081029190910101516005546001600160a01b031691906142a4565b60055486516001600160a01b0380841692637db4e28f9291169089908690811061108757611087614a09565b60200260200101516040518363ffffffff1660e01b81526004016110ac929190614b05565b600060405180830381600087803b1580156110c657600080fd5b505af11580156110da573d6000803e3d6000fd5b505060055488516001600160a01b0385811694509091169150600080516020614c2f8339815191529089908690811061111557611115614a09565b602002602001015160405161112c91815260200190565b60405180910390a3611cc9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611197573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111bb91906149ec565b6001600160a01b0316816001600160a01b031603611c405760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611233573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125791906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611294573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b89190614aa6565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133a91906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b9190614aa6565b6113a59190614a35565b6113b190612710614a8f565b6127107f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611412573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143691906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611473573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114979190614aa6565b6114a19190614a8f565b8885815181106114b3576114b3614a09565b60200260200101516114c59190614a8f565b6114cf9190614abf565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611531573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155591906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611592573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b69190614aa6565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611614573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163891906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116999190614aa6565b6116a39190614a35565b6116af90612710614a8f565b6127107f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611710573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173491906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117959190614aa6565b61179f9190614a8f565b8986815181106117b1576117b1614a09565b60200260200101516117c39190614a8f565b6117cd9190614abf565b90506118677f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611830573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185491906149ec565b6005546001600160a01b031690846142a4565b6118ff7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ec91906149ec565b6005546001600160a01b031690836142a4565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561195d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198191906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f926119b4929116908690600401614b05565b600060405180830381600087803b1580156119ce57600080fd5b505af11580156119e2573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6891906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f92611a9b929116908590600401614b05565b600060405180830381600087803b158015611ab557600080fd5b505af1158015611ac9573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4f91906149ec565b6005546040518481526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a37f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611be1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0591906149ec565b6005546040518381526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a35050611cc9565b611c7481878481518110611c5657611c56614a09565b60209081029190910101516005546001600160a01b0316919061437b565b60055486516001600160a01b03808416921690600080516020614c2f83398151915290899086908110611ca957611ca9614a09565b6020026020010151604051611cc091815260200190565b60405180910390a35b5080611cd481614a48565b915050610ead565b50611d757f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166372ad4ba06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6291906149ec565b6005546001600160a01b031690856142a4565b611dd67f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d8c58b6a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611830573d6000803e3d6000fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166372ad4ba06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5891906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f92611e8b929116908790600401614b05565b600060405180830381600087803b158015611ea557600080fd5b505af1158015611eb9573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d8c58b6a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f3f91906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f92611f72929116908690600401614b05565b600060405180830381600087803b158015611f8c57600080fd5b505af1158015611fa0573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166372ad4ba06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612002573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202691906149ec565b6005546040518581526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a37f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d8c58b6a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120dc91906149ec565b6005546040518481526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a360005b600354811015612ebb57600082828151811061213157612131614a09565b60200260200101511115612ea95760006003600001828154811061215757612157614a09565b9060005260206000200160009054906101000a90046001600160a01b031690507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166372ad4ba06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f991906149ec565b6001600160a01b0316816001600160a01b031614806122aa57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d8c58b6a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612271573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229591906149ec565b6001600160a01b0316816001600160a01b0316145b156123a3576122c58184848151811061103d5761103d614a09565b60055483516001600160a01b0380841692637db4e28f929116908690869081106122f1576122f1614a09565b60200260200101516040518363ffffffff1660e01b8152600401612316929190614b05565b600060405180830381600087803b15801561233057600080fd5b505af1158015612344573d6000803e3d6000fd5b505060055485516001600160a01b0385811694509091169150600080516020614c2f8339815191529086908690811061237f5761237f614a09565b602002602001015160405161239691815260200190565b60405180910390a3612ea7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612401573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242591906149ec565b6001600160a01b0316816001600160a01b031603612e3c5760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561249d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c191906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125229190614aa6565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612580573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a491906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126059190614aa6565b61260f9190614a35565b61261b90612710614a8f565b6127107f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561267c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126a091906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127019190614aa6565b61270b9190614a8f565b85858151811061271d5761271d614a09565b602002602001015161272f9190614a8f565b6127399190614abf565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561279b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127bf91906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128209190614aa6565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561287e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128a291906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129039190614aa6565b61290d9190614a35565b61291990612710614a8f565b6127107f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561297a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299e91906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ff9190614aa6565b612a099190614a8f565b868681518110612a1b57612a1b614a09565b6020026020010151612a2d9190614a8f565b612a379190614abf565b9050612a9a7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611830573d6000803e3d6000fd5b612afb7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118c8573d6000803e3d6000fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7d91906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f92612bb0929116908690600401614b05565b600060405180830381600087803b158015612bca57600080fd5b505af1158015612bde573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c6491906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f92612c97929116908590600401614b05565b600060405180830381600087803b158015612cb157600080fd5b505af1158015612cc5573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d4b91906149ec565b6005546040518481526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a37f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ddd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0191906149ec565b6005546040518381526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a35050612ea7565b612e5281848481518110611c5657611c56614a09565b60055483516001600160a01b03808416921690600080516020614c2f83398151915290869086908110612e8757612e87614a09565b6020026020010151604051612e9e91815260200190565b60405180910390a35b505b80612eb381614a48565b915050612113565b50505050505050505050612ecf6001600055565b565b612ed9614216565b6005546001600160a01b0390811690821603612f5c5760405162461bcd60e51b81526020600482015260486024820152600080516020614c0f83398151915260448201527f2829205f64697374726962757465644173736574203d3d2064697374726962756064820152671d1959105cdcd95d60c21b608482015260a40161052d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c76d41c86040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fde91906149ec565b6001600160a01b0316336001600160a01b03161461304d5760405162461bcd60e51b81526020600482015260386024820152600080516020614c0f8339815191526044820152772829205f6d736753656e646572282920213d20544c43282960401b606482015260840161052d565b60405163dd1db20160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063dd1db20190613099908490600401614777565b602060405180830381865afa1580156130b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130da9190614b1e565b61316a5760405162461bcd60e51b81526020600482015260616024820152600080516020614c0f83398151915260448201527f28292021495a69766f65476c6f62616c735f59444c2847424c292e737461626c60648201527f65636f696e57686974656c697374285f646973747269627574656441737365746084820152602960f81b60a482015260c40161052d565b6005546040516001600160a01b038084169216907f76e11df14bab23221508ffe147fedc0fe05ee9bea25dc226aba71fe59992b52d90600090a3600580546001600160a01b0319166001600160a01b038316179055600160005550565b50565b6005546001600160a01b03908116908216036132425760405162461bcd60e51b815260206004820152603160248201527f5a69766f6559444c3a3a72657475726e41737365742829206173736574203d3d60448201527008191a5cdd1c9a589d5d1959105cdcd95d607a1b606482015260840161052d565b6040516370a0823160e01b81526001600160a01b038216907f62b6baaf56303822f3a266824c7531678c2db132e29ee7a0a5bcc96964c94ef29082906370a0823190613292903090600401614777565b602060405180830381865afa1580156132af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d39190614aa6565b60405190815260200160405180910390a26131c77f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166398fabd3a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613345573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336991906149ec565b6040516370a0823160e01b81526001600160a01b038416906370a0823190613395903090600401614777565b602060405180830381865afa1580156133b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d69190614aa6565b6001600160a01b038416919061437b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c76d41c86040518163ffffffff1660e01b8152600401602060405180830381865afa158015613445573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346991906149ec565b6001600160a01b0316336001600160a01b0316146134e95760405162461bcd60e51b815260206004820152603760248201527f5a69766f6559444c3a3a757064617465546172676574526174696f424950532860448201527629205f6d736753656e646572282920213d20544c43282960481b606482015260840161052d565b600b5460408051918252602082018390527f6d7b1eed474977b0e6e6e3a4111193aef795ab0c6e024383b30132d72d72564d910160405180910390a1600b55565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166315154aff6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ac91906149ec565b6001600160a01b0316336001600160a01b0316146136325760405162461bcd60e51b815260206004820152603f60248201527f5a69766f6559444c3a3a756e6c6f636b2829205f6d736753656e64657228292060448201527f213d20495a69766f65476c6f62616c735f59444c2847424c292e49544f282900606482015260840161052d565b600d805460ff1916600117905561364c4262278d00614a35565b6009819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c5f4f7b06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156136b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d491906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613711573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137359190614aa6565b6006819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639699177c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613799573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bd91906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061381e9190614aa6565b6007556040805160028082526060820183526000926020830190803683375050604080516002808252606082018352939450600093909250906020830190803683370190505090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138e891906149ec565b826000815181106138fb576138fb614a09565b60200260200101906001600160a01b031690816001600160a01b031681525050611a0a8160008151811061393157613931614a09565b6020026020010181815250507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316620960456040518163ffffffff1660e01b8152600401602060405180830381865afa15801561399a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139be91906149ec565b826001815181106139d1576139d1614a09565b60200260200101906001600160a01b031690816001600160a01b031681525050610d0681600181518110613a0757613a07614a09565b60200260200101818152505060405180604001604052808381526020018281525060016000820151816000019080519060200190613a46929190614601565b506020828101518051613a5f9260018501920190614666565b50506040805160028082526060820183526000935090916020830190803683375050604080516002808252606082018352939450600093909250906020830190803683370190505090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b2b91906149ec565b82600081518110613b3e57613b3e614a09565b60200260200101906001600160a01b031690816001600160a01b031681525050611a0a81600081518110613b7457613b74614a09565b6020026020010181815250507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316620960456040518163ffffffff1660e01b8152600401602060405180830381865afa158015613bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c0191906149ec565b82600181518110613c1457613c14614a09565b60200260200101906001600160a01b031690816001600160a01b031681525050610d0681600181518110613c4a57613c4a614a09565b60200260200101818152505060405180604001604052808381526020018281525060036000820151816000019080519060200190610a77929190614601565b600154606090600090819083906001600160401b03811115613cad57613cad6147a4565b604051908082528060200260200182016040528015613cd6578160200160208202803683370190505b506003549094506001600160401b03811115613cf457613cf46147a4565b604051908082528060200260200182016040528015613d1d578160200160208202803683370190505b50905060005b600154811015613d945761271087600180018381548110613d4657613d46614a09565b9060005260206000200154613d5b9190614a8f565b613d659190614abf565b858281518110613d7757613d77614a09565b602090810291909101015280613d8c81614a48565b915050613d23565b50600d5460055460405163dc3c1da560e01b8152600481018890526001600160a01b039182166024820152600092610100900482169163e0166e9c917f00000000000000000000000000000000000000000000000000000000000000009091169063dc3c1da590604401602060405180830381865afa158015613e1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e3f9190614aa6565b600d54600654600754600a54600b54604051633c157d1760e11b81526004810194909452602484019290925260448301526064820152601e60848201526101009091046001600160a01b03169063782afa2e9060a401602060405180830381865afa158015613eb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ed69190614aa6565b600654600754600a54600b546040516001600160e01b031960e089901b1681526004810196909652602486019490945260448501929092526064840152608483015260a4820152601e60c482015260e401602060405180830381865afa158015613f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f689190614aa6565b9050676765c793fa10079d601b1b613f808288614a8f565b613f8a9190614abf565b600d54600654600754600b546040516336e227ef60e01b815260048101939093526024830191909152604482018590526064820152919550676765c793fa10079d601b1b916101009091046001600160a01b0316906336e227ef90608401602060405180830381865afa158015614005573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140299190614aa6565b6140339088614a8f565b61403d9190614abf565b925061405361404c8486614a35565b879061426f565b955060005b6003548110156140ca57612710876003600101838154811061407c5761407c614a09565b90600052602060002001546140919190614a8f565b61409b9190614abf565b8382815181106140ad576140ad614a09565b6020908102919091010152806140c281614a48565b915050614058565b505092959194509250565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c76d41c86040518163ffffffff1660e01b8152600401602060405180830381865afa158015614133573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061415791906149ec565b6001600160a01b0316336001600160a01b0316146141d55760405162461bcd60e51b815260206004820152603560248201527f5a69766f6559444c3a3a757064617465546172676574415059424950532829206044820152745f6d736753656e646572282920213d20544c43282960581b606482015260840161052d565b600a5460408051918252602082018390527f73e93c22ac34c14a7ecb6aa5ccbdd0e0bd71c015f2bd9ac9018f84950ad37f1e910160405180910390a1600a55565b6002600054036142685760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161052d565b6002600055565b60008282111561428157506000614286565b508082035b92915050565b600081831061429b578161429d565b825b9392505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156142f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143199190614aa6565b6143239190614a35565b9050610a948463095ea7b360e01b8584604051602401614344929190614b05565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261439f565b61439a8363a9059cbb60e01b8484604051602401614344929190614b05565b505050565b60006143f4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166144719092919063ffffffff16565b80519091501561439a57808060200190518101906144129190614b1e565b61439a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161052d565b60606144808484600085614488565b949350505050565b6060824710156144e95760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161052d565b600080866001600160a01b031685876040516145059190614b5f565b60006040518083038185875af1925050503d8060008114614542576040519150601f19603f3d011682016040523d82523d6000602084013e614547565b606091505b509150915061455887838387614563565b979650505050505050565b606083156145d25782516000036145cb576001600160a01b0385163b6145cb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161052d565b5081614480565b61448083838151156145e75781518083602001fd5b8060405162461bcd60e51b815260040161052d9190614b7b565b828054828255906000526020600020908101928215614656579160200282015b8281111561465657825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614621565b506146629291506146a1565b5090565b828054828255906000526020600020908101928215614656579160200282015b82811115614656578251825591602001919060010190614686565b5b8082111561466257600081556001016146a2565b600081518084526020808501945080840160005b838110156146ef5781516001600160a01b0316875295820195908201906001016146ca565b509495945050505050565b600081518084526020808501945080840160005b838110156146ef5781518752958201959082019060010161470e565b60808152600061473d60808301876146b6565b828103602084015261474f81876146fa565b9050828103604084015261476381866146b6565b9050828103606084015261455881856146fa565b6001600160a01b0391909116815260200190565b60006020828403121561479d57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156147e2576147e26147a4565b604052919050565b60006001600160401b03821115614803576148036147a4565b5060051b60200190565b6001600160a01b03811681146131c757600080fd5b600082601f83011261483357600080fd5b81356020614848614843836147ea565b6147ba565b82815260059290921b8401810191818101908684111561486757600080fd5b8286015b84811015614882578035835291830191830161486b565b509695505050505050565b80151581146131c757600080fd5b80356148a68161488d565b919050565b6000806000606084860312156148c057600080fd5b83356001600160401b03808211156148d757600080fd5b818601915086601f8301126148eb57600080fd5b813560206148fb614843836147ea565b82815260059290921b8401810191818101908a84111561491a57600080fd5b948201945b838610156149415785356149328161480d565b8252948201949082019061491f565b9750508701359250508082111561495757600080fd5b5061496486828701614822565b9250506149736040850161489b565b90509250925092565b60006020828403121561498e57600080fd5b813561429d8161480d565b600080604083850312156149ac57600080fd5b50508035926020909101359150565b6080815260006149ce60808301876146fa565b856020840152846040840152828103606084015261455881856146fa565b6000602082840312156149fe57600080fd5b815161429d8161480d565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561428657614286614a1f565b600060018201614a5a57614a5a614a1f565b5060010190565b604081526000614a7460408301856146b6565b8281036020840152614a8681856146fa565b95945050505050565b808202811582820484141761428657614286614a1f565b600060208284031215614ab857600080fd5b5051919050565b600082614adc57634e487b7160e01b600052601260045260246000fd5b500490565b60008060408385031215614af457600080fd5b505080516020909101519092909150565b6001600160a01b03929092168252602082015260400190565b600060208284031215614b3057600080fd5b815161429d8161488d565b60005b83811015614b56578181015183820152602001614b3e565b50506000910152565b60008251614b71818460208701614b3b565b9190910192915050565b6020815260008251806020840152614b9a816040850160208701614b3b565b601f01601f1916919091016040019291505056fe5a69766f6559444c3a3a75706461746550726f746f636f6c4561726e696e67735a69766f6559444c3a3a757064617465526563697069656e74732829207265635a69766f6559444c3a3a757064617465526563697069656e747328292070726f5a69766f6559444c3a3a7570646174654469737472696275746564417373657468321aac2dd94c71686ec859379a0cfd0108e54b95764276b3a39ef1ca7cbe52a2646970667358221220cd374d31267796f176a19c437040cfb30ec05cfc682092cd88934be1abf399c364736f6c63430008110033608060405234801561001057600080fd5b50610506806100206000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80630113858a146100675780631bcba7271461008c57806336e227ef1461009f578063782afa2e146100b2578063bba6a2d8146100c5578063e0166e9c146100d8575b600080fd5b61007a61007536600461034a565b6100eb565b60405190815260200160405180910390f35b61007a61009a36600461037c565b61014f565b61007a6100ad36600461034a565b6101bb565b61007a6100c03660046103a8565b61020b565b61007a6100d336600461037c565b610264565b61007a6100e63660046103e3565b6102c1565b6000610146676765c793fa10079d601b1b6101408761016d612710878a6101128b88610445565b61011c9190610445565b6101269190610445565b6101309190610472565b61013a9190610472565b906102f7565b90610332565b95945050505050565b60008160000361016157610161610494565b60006101846101718460016104aa565b61013a670de0b6b3a76400006002610445565b9050610146670de0b6b3a76400008661019d84836104bd565b6101a79190610445565b6101b18785610445565b61013a91906104aa565b6000676765c793fa10079d601b1b8311610203576101466101e784676765c793fa10079d601b1b6104bd565b61014087612710876101f98a89610445565b6101309190610445565b949350505050565b600061016d6127108061021e8689610445565b6102289190610472565b61023290896104aa565b61023c8588610445565b6102469190610445565b6102509190610472565b61025a9190610472565b9695505050505050565b6000610203676765c793fa10079d601b1b61014061029287612710670de0b6b3a76400006101f98a8a610445565b6102a490670de0b6b3a76400006104aa565b61013a676765c793fa10079d601b1b670de0b6b3a7640000610445565b6000868810156102dd576102d6868685610264565b90506102ec565b6102e9888786856100eb565b90505b979650505050505050565b6000816000036103095750600061032c565b828211156103195750600061032c565b8183816103285761032861045c565b0490505b92915050565b60008183106103415781610343565b825b9392505050565b6000806000806080858703121561036057600080fd5b5050823594602084013594506040840135936060013592509050565b60008060006060848603121561039157600080fd5b505081359360208301359350604090920135919050565b600080600080600060a086880312156103c057600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600080600080600060e0888a0312156103fe57600080fd5b505085359760208701359750604087013596606081013596506080810135955060a0810135945060c0013592509050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761032c5761032c61042f565b634e487b7160e01b600052601260045260246000fd5b60008261048f57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052600160045260246000fd5b8082018082111561032c5761032c61042f565b8181038181111561032c5761032c61042f56fea26469706673582212202edb6295b8919a7c41df1efb4c7937a9fca2ba29aec42583b7694940cf8852f264736f6c63430008110033000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da66000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061011d5760003560e01c806307061b941461012257806336b774a21461013d5780633ce8d432146101555780635df8d168146101895780636635e82c1461019c5780636a5e2650146101a55780636be09f77146101c2578063718bfc4c146101d75780638a570a12146101ea5780639048613a146101f25780639e3b5d2214610205578063a4abd79914610218578063a69df4b51461022b578063a717639c14610233578063a8e60c991461023c578063b9f543441461025f578063c2e63afa14610267578063c78f912a14610270578063c81a176614610279578063dd40482614610282578063e68c728914610295578063ed6c15461461029e578063feafdaa7146102b6575b600080fd5b61012a600681565b6040519081526020015b60405180910390f35b6101456102bf565b604051610134949392919061472a565b61017c7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da6681565b6040516101349190614777565b60055461017c906001600160a01b031681565b61012a600a5481565b600d546101b29060ff1681565b6040519015158152602001610134565b6101d56101d036600461478b565b610439565b005b6101d56101e53660046148ab565b6105f1565b6101d5610a9a565b6101d561020036600461497c565b612ed1565b6101d561021336600461497c565b6131ca565b6101d561022636600461478b565b6133e7565b6101d561352a565b61012a60095481565b61024f61024a366004614999565b613c89565b60405161013494939291906149bb565b61012a601e81565b61012a600b5481565b61012a60065481565b61012a60075481565b6101d561029036600461478b565b6140d5565b61012a600c5481565b600d5461017c9061010090046001600160a01b031681565b61012a60085481565b600180546040805160208084028201810190925282815260609384938493849360029260039260049291869183018282801561032457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610306575b505050505093508280548060200260200160405190810160405280929190818152602001828054801561037657602002820191906000526020600020905b815481526020019060010190808311610362575b50505050509250818054806020026020016040519081016040528092919081815260200182805480156103d257602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116103b4575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561042457602002820191906000526020600020905b815481526020019060010190808311610410575b50505050509050935093509350935090919293565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663c76d41c86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bb91906149ec565b6001600160a01b0316336001600160a01b031614610536576040805162461bcd60e51b8152602060048201526024810191909152600080516020614baf83398151915260448201527f52617465424950532829205f6d736753656e646572282920213d20544c43282960648201526084015b60405180910390fd5b6123288111156105b05760405162461bcd60e51b815260206004820152604b6024820152600080516020614baf83398151915260448201527f52617465424950532829205f70726f746f636f6c4561726e696e67735261746560648201526a042495053203e20393030360ac1b608482015260a40161052d565b600c5460408051918252602082018390527f4fc744850bd93e9f01c96ffba23c38cd46e64cfc8b77e26df28f598a92f4895a910160405180910390a1600c55565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663c76d41c86040518163ffffffff1660e01b8152600401602060405180830381865afa15801561064f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067391906149ec565b6001600160a01b0316336001600160a01b0316146106ee5760405162461bcd60e51b815260206004820152603260248201527f5a69766f6559444c3a3a757064617465526563697069656e74732829205f6d736044820152716753656e646572282920213d20544c43282960701b606482015260840161052d565b81518351148015610700575060008351115b6107865760405162461bcd60e51b815260206004820152605e6024820152600080516020614bcf83398151915260448201527f697069656e74732e6c656e67746820213d2070726f706f7274696f6e732e6c6560648201527f6e677468207c7c20726563697069656e74732e6c656e677468203d3d20300000608482015260a40161052d565b600d5460ff166107e75760405162461bcd60e51b815260206004820152602660248201527f5a69766f6559444c3a3a757064617465526563697069656e747328292021756e6044820152651b1bd8dad95960d21b606482015260840161052d565b6000805b84518110156109275783818151811061080657610806614a09565b6020026020010151826108199190614a35565b9150600084828151811061082f5761082f614a09565b60200260200101511161088b5760405162461bcd60e51b81526020600482015260306024820152600080516020614bef83398151915260448201526f0706f7274696f6e735b695d203d3d20360841b606482015260840161052d565b60006001600160a01b03168582815181106108a8576108a8614a09565b60200260200101516001600160a01b0316036109155760405162461bcd60e51b81526020600482015260386024820152600080516020614bcf833981519152604482015277697069656e74735b695d203d3d206164647265737328302960401b606482015260840161052d565b8061091f81614a48565b9150506107eb565b50612710811461098d5760405162461bcd60e51b815260206004820152603d6024820152600080516020614bef83398151915260448201527f706f7274696f6e546f74616c20213d2042495053202831302c30303029000000606482015260840161052d565b8115610a16577fb11a4b2b83a8e60adf2dadcbb51133b2ab7ce63ea9dc74f0621a7dcd41a578c384846040516109c4929190614a61565b60405180910390a160408051808201909152848152602080820185905285516001916109f4918391890190614601565b506020828101518051610a0d9260018501920190614666565b50905050610a94565b7fabde01bf2c50450e2dcb78815018bae0c080de9172fbcd2d6ecf9496558d2d218484604051610a47929190614a61565b60405180910390a16040805180820190915284815260208082018590528551600391610a77918391890190614601565b506020828101518051610a909260018501920190614666565b5050505b50505050565b610aa2614216565b600d5460ff16610b025760405162461bcd60e51b815260206004820152602560248201527f5a69766f6559444c3a3a646973747269627574655969656c6428292021756e6c6044820152641bd8dad95960da1b606482015260840161052d565b610b10601e62015180614a8f565b600954610b1d9190614a35565b421015610bc25760405162461bcd60e51b815260206004820152606160248201527f5a69766f6559444c3a3a646973747269627574655969656c64282920626c6f6360448201527f6b2e74696d657374616d70203c206c617374446973747269627574696f6e202b60648201527f20646179734265747765656e446973747269627574696f6e73202a20383634306084820152600360fc1b60a482015260c40161052d565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190610bf3903090600401614777565b602060405180830381865afa158015610c10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c349190614aa6565b9050600061271082600c54610c499190614a8f565b610c539190614abf565b90506000610c61838361426f565b9050600160086000828254610c769190614a35565b92505081905550426009819055506000807f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b0316635351d09b6040518163ffffffff1660e01b81526004016040805180830381865afa158015610ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d089190614ae1565b91509150600d60019054906101000a90046001600160a01b03166001600160a01b0316631bcba72760065484610d4a600854600661428c90919063ffffffff16565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa158015610d93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db79190614aa6565b6006908155600d546007546008546101009092046001600160a01b031692631bcba727928591610de69161428c565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa158015610e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e539190614aa6565b6007556000808080610e658888613c89565b93509350935093507fe51adb54e755c91701c15d94aa9a41d83c012ffd78f3acd465309018a69f39ce84848484604051610ea294939291906149bb565b60405180910390a160005b600154811015611cdc57600060016000018281548110610ecf57610ecf614a09565b9060005260206000200160009054906101000a90046001600160a01b031690507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b03166372ad4ba06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7191906149ec565b6001600160a01b0316816001600160a01b0316148061102257507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d8c58b6a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100d91906149ec565b6001600160a01b0316816001600160a01b0316145b156111395761105b8187848151811061103d5761103d614a09565b60209081029190910101516005546001600160a01b031691906142a4565b60055486516001600160a01b0380841692637db4e28f9291169089908690811061108757611087614a09565b60200260200101516040518363ffffffff1660e01b81526004016110ac929190614b05565b600060405180830381600087803b1580156110c657600080fd5b505af11580156110da573d6000803e3d6000fd5b505060055488516001600160a01b0385811694509091169150600080516020614c2f8339815191529089908690811061111557611115614a09565b602002602001015160405161112c91815260200190565b60405180910390a3611cc9565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611197573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111bb91906149ec565b6001600160a01b0316816001600160a01b031603611c405760007f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611233573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125791906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611294573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b89190614aa6565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133a91906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b9190614aa6565b6113a59190614a35565b6113b190612710614a8f565b6127107f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611412573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143691906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611473573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114979190614aa6565b6114a19190614a8f565b8885815181106114b3576114b3614a09565b60200260200101516114c59190614a8f565b6114cf9190614abf565b905060007f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611531573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155591906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611592573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b69190614aa6565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611614573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163891906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611675573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116999190614aa6565b6116a39190614a35565b6116af90612710614a8f565b6127107f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611710573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173491906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117959190614aa6565b61179f9190614a8f565b8986815181106117b1576117b1614a09565b60200260200101516117c39190614a8f565b6117cd9190614abf565b90506118677f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611830573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185491906149ec565b6005546001600160a01b031690846142a4565b6118ff7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ec91906149ec565b6005546001600160a01b031690836142a4565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561195d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061198191906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f926119b4929116908690600401614b05565b600060405180830381600087803b1580156119ce57600080fd5b505af11580156119e2573d6000803e3d6000fd5b505050507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6891906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f92611a9b929116908590600401614b05565b600060405180830381600087803b158015611ab557600080fd5b505af1158015611ac9573d6000803e3d6000fd5b505050507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4f91906149ec565b6005546040518481526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a37f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611be1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0591906149ec565b6005546040518381526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a35050611cc9565b611c7481878481518110611c5657611c56614a09565b60209081029190910101516005546001600160a01b0316919061437b565b60055486516001600160a01b03808416921690600080516020614c2f83398151915290899086908110611ca957611ca9614a09565b6020026020010151604051611cc091815260200190565b60405180910390a35b5080611cd481614a48565b915050610ead565b50611d757f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b03166372ad4ba06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6291906149ec565b6005546001600160a01b031690856142a4565b611dd67f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d8c58b6a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611830573d6000803e3d6000fd5b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b03166372ad4ba06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5891906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f92611e8b929116908790600401614b05565b600060405180830381600087803b158015611ea557600080fd5b505af1158015611eb9573d6000803e3d6000fd5b505050507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d8c58b6a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f3f91906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f92611f72929116908690600401614b05565b600060405180830381600087803b158015611f8c57600080fd5b505af1158015611fa0573d6000803e3d6000fd5b505050507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b03166372ad4ba06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612002573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202691906149ec565b6005546040518581526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a37f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d8c58b6a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120dc91906149ec565b6005546040518481526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a360005b600354811015612ebb57600082828151811061213157612131614a09565b60200260200101511115612ea95760006003600001828154811061215757612157614a09565b9060005260206000200160009054906101000a90046001600160a01b031690507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b03166372ad4ba06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f991906149ec565b6001600160a01b0316816001600160a01b031614806122aa57507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d8c58b6a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612271573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061229591906149ec565b6001600160a01b0316816001600160a01b0316145b156123a3576122c58184848151811061103d5761103d614a09565b60055483516001600160a01b0380841692637db4e28f929116908690869081106122f1576122f1614a09565b60200260200101516040518363ffffffff1660e01b8152600401612316929190614b05565b600060405180830381600087803b15801561233057600080fd5b505af1158015612344573d6000803e3d6000fd5b505060055485516001600160a01b0385811694509091169150600080516020614c2f8339815191529086908690811061237f5761237f614a09565b602002602001015160405161239691815260200190565b60405180910390a3612ea7565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612401573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242591906149ec565b6001600160a01b0316816001600160a01b031603612e3c5760007f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561249d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c191906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125229190614aa6565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612580573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a491906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126059190614aa6565b61260f9190614a35565b61261b90612710614a8f565b6127107f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561267c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126a091906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156126dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127019190614aa6565b61270b9190614a8f565b85858151811061271d5761271d614a09565b602002602001015161272f9190614a8f565b6127399190614abf565b905060007f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561279b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127bf91906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128209190614aa6565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561287e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128a291906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129039190614aa6565b61290d9190614a35565b61291990612710614a8f565b6127107f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561297a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299e91906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ff9190614aa6565b612a099190614a8f565b868681518110612a1b57612a1b614a09565b6020026020010151612a2d9190614a8f565b612a379190614abf565b9050612a9a7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611830573d6000803e3d6000fd5b612afb7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118c8573d6000803e3d6000fd5b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7d91906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f92612bb0929116908690600401614b05565b600060405180830381600087803b158015612bca57600080fd5b505af1158015612bde573d6000803e3d6000fd5b505050507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c6491906149ec565b600554604051637db4e28f60e01b81526001600160a01b0392831692637db4e28f92612c97929116908590600401614b05565b600060405180830381600087803b158015612cb157600080fd5b505af1158015612cc5573d6000803e3d6000fd5b505050507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d4b91906149ec565b6005546040518481526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a37f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663201d620a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ddd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0191906149ec565b6005546040518381526001600160a01b039283169290911690600080516020614c2f8339815191529060200160405180910390a35050612ea7565b612e5281848481518110611c5657611c56614a09565b60055483516001600160a01b03808416921690600080516020614c2f83398151915290869086908110612e8757612e87614a09565b6020026020010151604051612e9e91815260200190565b60405180910390a35b505b80612eb381614a48565b915050612113565b50505050505050505050612ecf6001600055565b565b612ed9614216565b6005546001600160a01b0390811690821603612f5c5760405162461bcd60e51b81526020600482015260486024820152600080516020614c0f83398151915260448201527f2829205f64697374726962757465644173736574203d3d2064697374726962756064820152671d1959105cdcd95d60c21b608482015260a40161052d565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663c76d41c86040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fde91906149ec565b6001600160a01b0316336001600160a01b03161461304d5760405162461bcd60e51b81526020600482015260386024820152600080516020614c0f8339815191526044820152772829205f6d736753656e646572282920213d20544c43282960401b606482015260840161052d565b60405163dd1db20160e01b81526001600160a01b037f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da66169063dd1db20190613099908490600401614777565b602060405180830381865afa1580156130b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130da9190614b1e565b61316a5760405162461bcd60e51b81526020600482015260616024820152600080516020614c0f83398151915260448201527f28292021495a69766f65476c6f62616c735f59444c2847424c292e737461626c60648201527f65636f696e57686974656c697374285f646973747269627574656441737365746084820152602960f81b60a482015260c40161052d565b6005546040516001600160a01b038084169216907f76e11df14bab23221508ffe147fedc0fe05ee9bea25dc226aba71fe59992b52d90600090a3600580546001600160a01b0319166001600160a01b038316179055600160005550565b50565b6005546001600160a01b03908116908216036132425760405162461bcd60e51b815260206004820152603160248201527f5a69766f6559444c3a3a72657475726e41737365742829206173736574203d3d60448201527008191a5cdd1c9a589d5d1959105cdcd95d607a1b606482015260840161052d565b6040516370a0823160e01b81526001600160a01b038216907f62b6baaf56303822f3a266824c7531678c2db132e29ee7a0a5bcc96964c94ef29082906370a0823190613292903090600401614777565b602060405180830381865afa1580156132af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d39190614aa6565b60405190815260200160405180910390a26131c77f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b03166398fabd3a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613345573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336991906149ec565b6040516370a0823160e01b81526001600160a01b038416906370a0823190613395903090600401614777565b602060405180830381865afa1580156133b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d69190614aa6565b6001600160a01b038416919061437b565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663c76d41c86040518163ffffffff1660e01b8152600401602060405180830381865afa158015613445573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346991906149ec565b6001600160a01b0316336001600160a01b0316146134e95760405162461bcd60e51b815260206004820152603760248201527f5a69766f6559444c3a3a757064617465546172676574526174696f424950532860448201527629205f6d736753656e646572282920213d20544c43282960481b606482015260840161052d565b600b5460408051918252602082018390527f6d7b1eed474977b0e6e6e3a4111193aef795ab0c6e024383b30132d72d72564d910160405180910390a1600b55565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b03166315154aff6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ac91906149ec565b6001600160a01b0316336001600160a01b0316146136325760405162461bcd60e51b815260206004820152603f60248201527f5a69766f6559444c3a3a756e6c6f636b2829205f6d736753656e64657228292060448201527f213d20495a69766f65476c6f62616c735f59444c2847424c292e49544f282900606482015260840161052d565b600d805460ff1916600117905561364c4262278d00614a35565b6009819055507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663c5f4f7b06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156136b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d491906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613711573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137359190614aa6565b6006819055507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b0316639699177c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613799573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bd91906149ec565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061381e9190614aa6565b6007556040805160028082526060820183526000926020830190803683375050604080516002808252606082018352939450600093909250906020830190803683370190505090507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138e891906149ec565b826000815181106138fb576138fb614a09565b60200260200101906001600160a01b031690816001600160a01b031681525050611a0a8160008151811061393157613931614a09565b6020026020010181815250507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b0316620960456040518163ffffffff1660e01b8152600401602060405180830381865afa15801561399a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139be91906149ec565b826001815181106139d1576139d1614a09565b60200260200101906001600160a01b031690816001600160a01b031681525050610d0681600181518110613a0757613a07614a09565b60200260200101818152505060405180604001604052808381526020018281525060016000820151816000019080519060200190613a46929190614601565b506020828101518051613a5f9260018501920190614666565b50506040805160028082526060820183526000935090916020830190803683375050604080516002808252606082018352939450600093909250906020830190803683370190505090507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663d9fa86ed6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b2b91906149ec565b82600081518110613b3e57613b3e614a09565b60200260200101906001600160a01b031690816001600160a01b031681525050611a0a81600081518110613b7457613b74614a09565b6020026020010181815250507f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b0316620960456040518163ffffffff1660e01b8152600401602060405180830381865afa158015613bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c0191906149ec565b82600181518110613c1457613c14614a09565b60200260200101906001600160a01b031690816001600160a01b031681525050610d0681600181518110613c4a57613c4a614a09565b60200260200101818152505060405180604001604052808381526020018281525060036000820151816000019080519060200190610a77929190614601565b600154606090600090819083906001600160401b03811115613cad57613cad6147a4565b604051908082528060200260200182016040528015613cd6578160200160208202803683370190505b506003549094506001600160401b03811115613cf457613cf46147a4565b604051908082528060200260200182016040528015613d1d578160200160208202803683370190505b50905060005b600154811015613d945761271087600180018381548110613d4657613d46614a09565b9060005260206000200154613d5b9190614a8f565b613d659190614abf565b858281518110613d7757613d77614a09565b602090810291909101015280613d8c81614a48565b915050613d23565b50600d5460055460405163dc3c1da560e01b8152600481018890526001600160a01b039182166024820152600092610100900482169163e0166e9c917f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da669091169063dc3c1da590604401602060405180830381865afa158015613e1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e3f9190614aa6565b600d54600654600754600a54600b54604051633c157d1760e11b81526004810194909452602484019290925260448301526064820152601e60848201526101009091046001600160a01b03169063782afa2e9060a401602060405180830381865afa158015613eb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ed69190614aa6565b600654600754600a54600b546040516001600160e01b031960e089901b1681526004810196909652602486019490945260448501929092526064840152608483015260a4820152601e60c482015260e401602060405180830381865afa158015613f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f689190614aa6565b9050676765c793fa10079d601b1b613f808288614a8f565b613f8a9190614abf565b600d54600654600754600b546040516336e227ef60e01b815260048101939093526024830191909152604482018590526064820152919550676765c793fa10079d601b1b916101009091046001600160a01b0316906336e227ef90608401602060405180830381865afa158015614005573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140299190614aa6565b6140339088614a8f565b61403d9190614abf565b925061405361404c8486614a35565b879061426f565b955060005b6003548110156140ca57612710876003600101838154811061407c5761407c614a09565b90600052602060002001546140919190614a8f565b61409b9190614abf565b8382815181106140ad576140ad614a09565b6020908102919091010152806140c281614a48565b915050614058565b505092959194509250565b7f000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da666001600160a01b031663c76d41c86040518163ffffffff1660e01b8152600401602060405180830381865afa158015614133573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061415791906149ec565b6001600160a01b0316336001600160a01b0316146141d55760405162461bcd60e51b815260206004820152603560248201527f5a69766f6559444c3a3a757064617465546172676574415059424950532829206044820152745f6d736753656e646572282920213d20544c43282960581b606482015260840161052d565b600a5460408051918252602082018390527f73e93c22ac34c14a7ecb6aa5ccbdd0e0bd71c015f2bd9ac9018f84950ad37f1e910160405180910390a1600a55565b6002600054036142685760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161052d565b6002600055565b60008282111561428157506000614286565b508082035b92915050565b600081831061429b578161429d565b825b9392505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156142f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143199190614aa6565b6143239190614a35565b9050610a948463095ea7b360e01b8584604051602401614344929190614b05565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261439f565b61439a8363a9059cbb60e01b8484604051602401614344929190614b05565b505050565b60006143f4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166144719092919063ffffffff16565b80519091501561439a57808060200190518101906144129190614b1e565b61439a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161052d565b60606144808484600085614488565b949350505050565b6060824710156144e95760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161052d565b600080866001600160a01b031685876040516145059190614b5f565b60006040518083038185875af1925050503d8060008114614542576040519150601f19603f3d011682016040523d82523d6000602084013e614547565b606091505b509150915061455887838387614563565b979650505050505050565b606083156145d25782516000036145cb576001600160a01b0385163b6145cb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161052d565b5081614480565b61448083838151156145e75781518083602001fd5b8060405162461bcd60e51b815260040161052d9190614b7b565b828054828255906000526020600020908101928215614656579160200282015b8281111561465657825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614621565b506146629291506146a1565b5090565b828054828255906000526020600020908101928215614656579160200282015b82811115614656578251825591602001919060010190614686565b5b8082111561466257600081556001016146a2565b600081518084526020808501945080840160005b838110156146ef5781516001600160a01b0316875295820195908201906001016146ca565b509495945050505050565b600081518084526020808501945080840160005b838110156146ef5781518752958201959082019060010161470e565b60808152600061473d60808301876146b6565b828103602084015261474f81876146fa565b9050828103604084015261476381866146b6565b9050828103606084015261455881856146fa565b6001600160a01b0391909116815260200190565b60006020828403121561479d57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156147e2576147e26147a4565b604052919050565b60006001600160401b03821115614803576148036147a4565b5060051b60200190565b6001600160a01b03811681146131c757600080fd5b600082601f83011261483357600080fd5b81356020614848614843836147ea565b6147ba565b82815260059290921b8401810191818101908684111561486757600080fd5b8286015b84811015614882578035835291830191830161486b565b509695505050505050565b80151581146131c757600080fd5b80356148a68161488d565b919050565b6000806000606084860312156148c057600080fd5b83356001600160401b03808211156148d757600080fd5b818601915086601f8301126148eb57600080fd5b813560206148fb614843836147ea565b82815260059290921b8401810191818101908a84111561491a57600080fd5b948201945b838610156149415785356149328161480d565b8252948201949082019061491f565b9750508701359250508082111561495757600080fd5b5061496486828701614822565b9250506149736040850161489b565b90509250925092565b60006020828403121561498e57600080fd5b813561429d8161480d565b600080604083850312156149ac57600080fd5b50508035926020909101359150565b6080815260006149ce60808301876146fa565b856020840152846040840152828103606084015261455881856146fa565b6000602082840312156149fe57600080fd5b815161429d8161480d565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561428657614286614a1f565b600060018201614a5a57614a5a614a1f565b5060010190565b604081526000614a7460408301856146b6565b8281036020840152614a8681856146fa565b95945050505050565b808202811582820484141761428657614286614a1f565b600060208284031215614ab857600080fd5b5051919050565b600082614adc57634e487b7160e01b600052601260045260246000fd5b500490565b60008060408385031215614af457600080fd5b505080516020909101519092909150565b6001600160a01b03929092168252602082015260400190565b600060208284031215614b3057600080fd5b815161429d8161488d565b60005b83811015614b56578181015183820152602001614b3e565b50506000910152565b60008251614b71818460208701614b3b565b9190910192915050565b6020815260008251806020840152614b9a816040850160208701614b3b565b601f01601f1916919091016040019291505056fe5a69766f6559444c3a3a75706461746550726f746f636f6c4561726e696e67735a69766f6559444c3a3a757064617465526563697069656e74732829207265635a69766f6559444c3a3a757064617465526563697069656e747328292070726f5a69766f6559444c3a3a7570646174654469737472696275746564417373657468321aac2dd94c71686ec859379a0cfd0108e54b95764276b3a39ef1ca7cbe52a2646970667358221220cd374d31267796f176a19c437040cfb30ec05cfc682092cd88934be1abf399c364736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da66000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
-----Decoded View---------------
Arg [0] : _GBL (address): 0xEa537eB0bBcC7783bDF7c595bF9371984583dA66
Arg [1] : _distributedAsset (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000ea537eb0bbcc7783bdf7c595bf9371984583da66
Arg [1] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.