Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 359 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Redeem | 20538455 | 99 days ago | IN | 0 ETH | 0.00029941 | ||||
Redeem | 20538413 | 99 days ago | IN | 0 ETH | 0.00007796 | ||||
Redeem | 20496757 | 105 days ago | IN | 0 ETH | 0.00014165 | ||||
Redeem | 20166667 | 151 days ago | IN | 0 ETH | 0.00019994 | ||||
Redeem | 20157425 | 152 days ago | IN | 0 ETH | 0.00024532 | ||||
Redeem | 20157199 | 152 days ago | IN | 0 ETH | 0.00019998 | ||||
Redeem | 20152329 | 153 days ago | IN | 0 ETH | 0.00023665 | ||||
Redeem | 20152304 | 153 days ago | IN | 0 ETH | 0.00022794 | ||||
Redeem | 20123545 | 157 days ago | IN | 0 ETH | 0.00034751 | ||||
Redeem | 20108448 | 159 days ago | IN | 0 ETH | 0.00036575 | ||||
Redeem | 19999758 | 174 days ago | IN | 0 ETH | 0.0005429 | ||||
Redeem | 19948674 | 181 days ago | IN | 0 ETH | 0.00077107 | ||||
Redeem | 19890213 | 189 days ago | IN | 0 ETH | 0.0005134 | ||||
Redeem | 19890180 | 189 days ago | IN | 0 ETH | 0.00064083 | ||||
Redeem | 19890128 | 189 days ago | IN | 0 ETH | 0.00053008 | ||||
Redeem | 19874778 | 192 days ago | IN | 0 ETH | 0.00052946 | ||||
Redeem | 19853273 | 195 days ago | IN | 0 ETH | 0.00029258 | ||||
Redeem | 19853261 | 195 days ago | IN | 0 ETH | 0.00031778 | ||||
Redeem | 19785670 | 204 days ago | IN | 0 ETH | 0.00059066 | ||||
Redeem | 19779142 | 205 days ago | IN | 0 ETH | 0.00039165 | ||||
Redeem | 19779074 | 205 days ago | IN | 0 ETH | 0.00052269 | ||||
Redeem | 19778852 | 205 days ago | IN | 0 ETH | 0.00049092 | ||||
Redeem | 19763424 | 207 days ago | IN | 0 ETH | 0.00078524 | ||||
Redeem | 19743028 | 210 days ago | IN | 0 ETH | 0.00038737 | ||||
Redeem | 19694194 | 217 days ago | IN | 0 ETH | 0.00051674 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Divider
Compiler Version
v0.8.11+commit.d7f03943
Optimization Enabled:
Yes with 1500 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.11; // External references import { Pausable } from "@openzeppelin/contracts/security/Pausable.sol"; import { ERC20 } from "@rari-capital/solmate/src/tokens/ERC20.sol"; import { SafeTransferLib } from "@rari-capital/solmate/src/utils/SafeTransferLib.sol"; import { ReentrancyGuard } from "@rari-capital/solmate/src/utils/ReentrancyGuard.sol"; import { DateTime } from "./external/DateTime.sol"; import { FixedMath } from "./external/FixedMath.sol"; // Internal references import { Errors } from "@sense-finance/v1-utils/src/libs/Errors.sol"; import { Levels } from "@sense-finance/v1-utils/src/libs/Levels.sol"; import { Trust } from "@sense-finance/v1-utils/src/Trust.sol"; import { YT } from "./tokens/YT.sol"; import { Token } from "./tokens/Token.sol"; import { BaseAdapter as Adapter } from "./adapters/BaseAdapter.sol"; /// @title Sense Divider: Divide Assets in Two /// @author fedealconada + jparklev /// @notice You can use this contract to issue, combine, and redeem Sense ERC20 Principal and Yield Tokens contract Divider is Trust, ReentrancyGuard, Pausable { using SafeTransferLib for ERC20; using FixedMath for uint256; using Levels for uint256; /* ========== PUBLIC CONSTANTS ========== */ /// @notice Buffer before and after the actual maturity in which only the sponsor can settle the Series uint256 public constant SPONSOR_WINDOW = 3 hours; /// @notice Buffer after the sponsor window in which anyone can settle the Series uint256 public constant SETTLEMENT_WINDOW = 3 hours; /// @notice 5% issuance fee cap uint256 public constant ISSUANCE_FEE_CAP = 0.05e18; /* ========== PUBLIC MUTABLE STORAGE ========== */ address public periphery; /// @notice Sense community multisig address public immutable cup; /// @notice Principal/Yield tokens deployer address public immutable tokenHandler; /// @notice Permissionless flag bool public permissionless; /// @notice Guarded launch flag bool public guarded = true; /// @notice Number of adapters (including turned off) uint248 public adapterCounter; /// @notice adapter ID -> adapter address mapping(uint256 => address) public adapterAddresses; /// @notice adapter data mapping(address => AdapterMeta) public adapterMeta; /// @notice adapter -> maturity -> Series mapping(address => mapping(uint256 => Series)) public series; /// @notice adapter -> maturity -> user -> lscale (last scale) mapping(address => mapping(uint256 => mapping(address => uint256))) public lscales; /* ========== DATA STRUCTURES ========== */ struct Series { // Principal ERC20 token address pt; // Timestamp of series initialization uint48 issuance; // Yield ERC20 token address yt; // % of underlying principal initially reserved for Yield uint96 tilt; // Actor who initialized the Series address sponsor; // Tracks fees due to the series' settler uint256 reward; // Scale at issuance uint256 iscale; // Scale at maturity uint256 mscale; // Max scale value from this series' lifetime uint256 maxscale; } struct AdapterMeta { // Adapter ID uint248 id; // Adapter enabled/disabled bool enabled; // Max amount of Target allowed to be issued uint256 guard; // Adapter level uint248 level; } constructor(address _cup, address _tokenHandler) Trust(msg.sender) { cup = _cup; tokenHandler = _tokenHandler; } /* ========== MUTATIVE FUNCTIONS ========== */ /// @notice Enable an adapter /// @dev when permissionless is disabled, only the Periphery can onboard adapters /// @dev after permissionless is enabled, anyone can onboard adapters /// @param adapter Adapter's address function addAdapter(address adapter) external whenNotPaused { if (!permissionless && msg.sender != periphery) revert Errors.OnlyPermissionless(); if (adapterMeta[adapter].id > 0 && !adapterMeta[adapter].enabled) revert Errors.InvalidAdapter(); _setAdapter(adapter, true); } /// @notice Initializes a new Series /// @dev Deploys two ERC20 contracts, one for PTs and the other one for YTs /// @dev Transfers some fixed amount of stake asset to this contract /// @param adapter Adapter to associate with the Series /// @param maturity Maturity date for the new Series, in units of unix time /// @param sponsor Sponsor of the Series that puts up a token stake and receives the issuance fees function initSeries( address adapter, uint256 maturity, address sponsor ) external nonReentrant whenNotPaused returns (address pt, address yt) { if (periphery != msg.sender) revert Errors.OnlyPeriphery(); if (!adapterMeta[adapter].enabled) revert Errors.InvalidAdapter(); if (_exists(adapter, maturity)) revert Errors.DuplicateSeries(); if (!_isValid(adapter, maturity)) revert Errors.InvalidMaturity(); // Transfer stake asset stake from caller to adapter (address target, address stake, uint256 stakeSize) = Adapter(adapter).getStakeAndTarget(); // Deploy Principal & Yield Tokens for this new Series (pt, yt) = TokenHandler(tokenHandler).deploy(adapter, adapterMeta[adapter].id, maturity); // Initialize the new Series struct uint256 scale = Adapter(adapter).scale(); series[adapter][maturity].pt = pt; series[adapter][maturity].issuance = uint48(block.timestamp); series[adapter][maturity].yt = yt; series[adapter][maturity].tilt = uint96(Adapter(adapter).tilt()); series[adapter][maturity].sponsor = sponsor; series[adapter][maturity].iscale = scale; series[adapter][maturity].maxscale = scale; ERC20(stake).safeTransferFrom(msg.sender, adapter, stakeSize); emit SeriesInitialized(adapter, maturity, pt, yt, sponsor, target); } /// @notice Settles a Series and transfers the settlement reward to the caller /// @dev The Series' sponsor has a grace period where only they can settle the Series /// @dev After that, the reward becomes MEV /// @param adapter Adapter to associate with the Series /// @param maturity Maturity date for the new Series function settleSeries(address adapter, uint256 maturity) external nonReentrant whenNotPaused { if (!adapterMeta[adapter].enabled) revert Errors.InvalidAdapter(); if (!_exists(adapter, maturity)) revert Errors.SeriesDoesNotExist(); if (_settled(adapter, maturity)) revert Errors.AlreadySettled(); if (!_canBeSettled(adapter, maturity)) revert Errors.OutOfWindowBoundaries(); // The maturity scale value is all a Series needs for us to consider it "settled" uint256 mscale = Adapter(adapter).scale(); series[adapter][maturity].mscale = mscale; if (mscale > series[adapter][maturity].maxscale) { series[adapter][maturity].maxscale = mscale; } // Reward the caller for doing the work of settling the Series at around the correct time (address target, address stake, uint256 stakeSize) = Adapter(adapter).getStakeAndTarget(); ERC20(target).safeTransferFrom(adapter, msg.sender, series[adapter][maturity].reward); ERC20(stake).safeTransferFrom(adapter, msg.sender, stakeSize); emit SeriesSettled(adapter, maturity, msg.sender); } /// @notice Mint Principal & Yield Tokens of a specific Series /// @param adapter Adapter address for the Series /// @param maturity Maturity date for the Series [unix time] /// @param tBal Balance of Target to deposit /// @dev The balance of PTs and YTs minted will be the same value in units of underlying (less fees) function issue( address adapter, uint256 maturity, uint256 tBal ) external nonReentrant whenNotPaused returns (uint256 uBal) { if (!adapterMeta[adapter].enabled) revert Errors.InvalidAdapter(); if (!_exists(adapter, maturity)) revert Errors.SeriesDoesNotExist(); if (_settled(adapter, maturity)) revert Errors.IssueOnSettle(); uint256 level = adapterMeta[adapter].level; if (level.issueRestricted() && msg.sender != adapter) revert Errors.IssuanceRestricted(); ERC20 target = ERC20(Adapter(adapter).target()); // Take the issuance fee out of the deposited Target, and put it towards the settlement reward uint256 issuanceFee = Adapter(adapter).ifee(); if (issuanceFee > ISSUANCE_FEE_CAP) revert Errors.IssuanceFeeCapExceeded(); uint256 fee = tBal.fmul(issuanceFee); unchecked { // Safety: bounded by the Target's total token supply series[adapter][maturity].reward += fee; } uint256 tBalSubFee = tBal - fee; // Ensure the caller won't hit the issuance cap with this action unchecked { // Safety: bounded by the Target's total token supply if (guarded && target.balanceOf(adapter) + tBal > adapterMeta[address(adapter)].guard) revert Errors.GuardCapReached(); } // Update values on adapter Adapter(adapter).notify(msg.sender, tBalSubFee, true); uint256 scale = level.collectDisabled() ? series[adapter][maturity].iscale : Adapter(adapter).scale(); // Determine the amount of Underlying equal to the Target being sent in (the principal) uBal = tBalSubFee.fmul(scale); // If the caller has not collected on YT before, use the current scale, otherwise // use the harmonic mean of the last and the current scale value lscales[adapter][maturity][msg.sender] = lscales[adapter][maturity][msg.sender] == 0 ? scale : _reweightLScale( adapter, maturity, YT(series[adapter][maturity].yt).balanceOf(msg.sender), uBal, msg.sender, scale ); // Mint equal amounts of PT and YT Token(series[adapter][maturity].pt).mint(msg.sender, uBal); YT(series[adapter][maturity].yt).mint(msg.sender, uBal); target.safeTransferFrom(msg.sender, adapter, tBal); emit Issued(adapter, maturity, uBal, msg.sender); } /// @notice Reconstitute Target by burning PT and YT /// @dev Explicitly burns YTs before maturity, and implicitly does it at/after maturity through `_collect()` /// @param adapter Adapter address for the Series /// @param maturity Maturity date for the Series /// @param uBal Balance of PT and YT to burn function combine( address adapter, uint256 maturity, uint256 uBal ) external nonReentrant whenNotPaused returns (uint256 tBal) { if (!adapterMeta[adapter].enabled) revert Errors.InvalidAdapter(); if (!_exists(adapter, maturity)) revert Errors.SeriesDoesNotExist(); uint256 level = adapterMeta[adapter].level; if (level.combineRestricted() && msg.sender != adapter) revert Errors.CombineRestricted(); // Burn the PT Token(series[adapter][maturity].pt).burn(msg.sender, uBal); // Collect whatever excess is due uint256 collected = _collect(msg.sender, adapter, maturity, uBal, uBal, address(0)); uint256 cscale = series[adapter][maturity].mscale; bool settled = _settled(adapter, maturity); if (!settled) { // If it's not settled, then YT won't be burned automatically in `_collect()` YT(series[adapter][maturity].yt).burn(msg.sender, uBal); // If collect has been restricted, use the initial scale, otherwise use the current scale cscale = level.collectDisabled() ? series[adapter][maturity].iscale : lscales[adapter][maturity][msg.sender]; } // Convert from units of Underlying to units of Target tBal = uBal.fdiv(cscale); ERC20(Adapter(adapter).target()).safeTransferFrom(adapter, msg.sender, tBal); // Notify only when Series is not settled as when it is, the _collect() call above would trigger a _redeemYT which will call notify if (!settled) Adapter(adapter).notify(msg.sender, tBal, false); unchecked { // Safety: bounded by the Target's total token supply tBal += collected; } emit Combined(adapter, maturity, tBal, msg.sender); } /// @notice Burn PT of a Series once it's been settled /// @dev The balance of redeemable Target is a function of the change in Scale /// @param adapter Adapter address for the Series /// @param maturity Maturity date for the Series /// @param uBal Amount of PT to burn, which should be equivalent to the amount of Underlying owed to the caller function redeem( address adapter, uint256 maturity, uint256 uBal ) external nonReentrant whenNotPaused returns (uint256 tBal) { // If a Series is settled, we know that it must have existed as well, so that check is unnecessary if (!_settled(adapter, maturity)) revert Errors.NotSettled(); uint256 level = adapterMeta[adapter].level; if (level.redeemRestricted() && msg.sender == adapter) revert Errors.RedeemRestricted(); // Burn the caller's PT Token(series[adapter][maturity].pt).burn(msg.sender, uBal); // Principal Token holder's share of the principal = (1 - part of the principal that belongs to Yield) uint256 zShare = FixedMath.WAD - series[adapter][maturity].tilt; // If Principal Token are at a loss and Yield have some principal to help cover the shortfall, // take what we can from Yield Token's principal if (series[adapter][maturity].mscale.fdiv(series[adapter][maturity].maxscale) >= zShare) { tBal = (uBal * zShare) / series[adapter][maturity].mscale; } else { tBal = uBal.fdiv(series[adapter][maturity].maxscale); } if (!level.redeemHookDisabled()) { Adapter(adapter).onRedeem(uBal, series[adapter][maturity].mscale, series[adapter][maturity].maxscale, tBal); } ERC20(Adapter(adapter).target()).safeTransferFrom(adapter, msg.sender, tBal); emit PTRedeemed(adapter, maturity, tBal); } function collect( address usr, address adapter, uint256 maturity, uint256 uBalTransfer, address to ) external nonReentrant onlyYT(adapter, maturity) whenNotPaused returns (uint256 collected) { uint256 uBal = YT(msg.sender).balanceOf(usr); return _collect(usr, adapter, maturity, uBal, uBalTransfer > 0 ? uBalTransfer : uBal, to); } /// @notice Collect YT excess before, at, or after maturity /// @dev If `to` is set, we copy the lscale value from usr to this address /// @param usr User who's collecting for their YTs /// @param adapter Adapter address for the Series /// @param maturity Maturity date for the Series /// @param uBal yield Token balance /// @param uBalTransfer original transfer value /// @param to address to set the lscale value from usr function _collect( address usr, address adapter, uint256 maturity, uint256 uBal, uint256 uBalTransfer, address to ) internal returns (uint256 collected) { if (!_exists(adapter, maturity)) revert Errors.SeriesDoesNotExist(); // If the adapter is disabled, its Yield Token can only collect // if associated Series has been settled, which implies that an admin // has backfilled it if (!adapterMeta[adapter].enabled && !_settled(adapter, maturity)) revert Errors.InvalidAdapter(); Series memory _series = series[adapter][maturity]; // Get the scale value from the last time this holder collected (default to maturity) uint256 lscale = lscales[adapter][maturity][usr]; uint256 level = adapterMeta[adapter].level; if (level.collectDisabled()) { // If this Series has been settled, we ensure everyone's YT will // collect yield accrued since issuance if (_settled(adapter, maturity)) { lscale = series[adapter][maturity].iscale; // If the Series is not settled, we ensure no collections can happen } else { return 0; } } // If the Series has been settled, this should be their last collect, so redeem the user's Yield Tokens for them if (_settled(adapter, maturity)) { _redeemYT(usr, adapter, maturity, uBal); } else { // If we're not settled and we're past maturity + the sponsor window, // anyone can settle this Series so revert until someone does if (block.timestamp > maturity + SPONSOR_WINDOW) { revert Errors.CollectNotSettled(); // Otherwise, this is a valid pre-settlement collect and we need to determine the scale value } else { uint256 cscale = Adapter(adapter).scale(); // If this is larger than the largest scale we've seen for this Series, use it if (cscale > _series.maxscale) { _series.maxscale = cscale; lscales[adapter][maturity][usr] = cscale; // If not, use the previously noted max scale value } else { lscales[adapter][maturity][usr] = _series.maxscale; } } } // Determine how much underlying has accrued since the last time this user collected, in units of Target. // (Or take the last time as issuance if they haven't yet) // // Reminder: `Underlying / Scale = Target` // So the following equation is saying, for some amount of Underlying `u`: // "Balance of Target that equaled `u` at the last collection _minus_ Target that equals `u` now" // // Because maxscale must be increasing, the Target balance needed to equal `u` decreases, and that "excess" // is what Yield holders are collecting uint256 tBalNow = uBal.fdivUp(_series.maxscale); // preventive round-up towards the protocol uint256 tBalPrev = uBal.fdiv(lscale); unchecked { collected = tBalPrev > tBalNow ? tBalPrev - tBalNow : 0; } ERC20(Adapter(adapter).target()).safeTransferFrom(adapter, usr, collected); Adapter(adapter).notify(usr, collected, false); // Distribute reward tokens // If this collect is a part of a token transfer to another address, set the receiver's // last collection to a synthetic scale weighted based on the scale on their last collect, // the time elapsed, and the current scale if (to != address(0)) { uint256 ytBal = YT(_series.yt).balanceOf(to); // If receiver holds yields, we set lscale to a computed "synthetic" lscales value that, // for the updated yield balance, still assigns the correct amount of yield. lscales[adapter][maturity][to] = ytBal > 0 ? _reweightLScale(adapter, maturity, ytBal, uBalTransfer, to, _series.maxscale) : _series.maxscale; uint256 tBalTransfer = uBalTransfer.fdiv(_series.maxscale); Adapter(adapter).notify(usr, tBalTransfer, false); Adapter(adapter).notify(to, tBalTransfer, true); } series[adapter][maturity] = _series; emit Collected(adapter, maturity, collected); } /// @notice calculate the harmonic mean of the current scale and the last scale, /// weighted by amounts associated with each function _reweightLScale( address adapter, uint256 maturity, uint256 ytBal, uint256 uBal, address receiver, uint256 scale ) internal view returns (uint256) { // Target Decimals * 18 Decimals [from fdiv] / (Target Decimals * 18 Decimals [from fdiv] / 18 Decimals) // = 18 Decimals, which is the standard for scale values return (ytBal + uBal).fdiv((ytBal.fdiv(lscales[adapter][maturity][receiver]) + uBal.fdiv(scale))); } function _redeemYT( address usr, address adapter, uint256 maturity, uint256 uBal ) internal { // Burn the users's YTs YT(series[adapter][maturity].yt).burn(usr, uBal); // Default principal for a YT uint256 tBal = 0; // Principal Token holder's share of the principal = (1 - part of the principal that belongs to Yield Tokens) uint256 zShare = FixedMath.WAD - series[adapter][maturity].tilt; // If PTs are at a loss and YTs had their principal cut to help cover the shortfall, // calculate how much YTs have left if (series[adapter][maturity].mscale.fdiv(series[adapter][maturity].maxscale) >= zShare) { tBal = uBal.fdiv(series[adapter][maturity].maxscale) - (uBal * zShare) / series[adapter][maturity].mscale; ERC20(Adapter(adapter).target()).safeTransferFrom(adapter, usr, tBal); } // Always notify the Adapter of the full Target balance that will no longer // have its rewards distributed Adapter(adapter).notify(usr, uBal.fdivUp(series[adapter][maturity].maxscale), false); emit YTRedeemed(adapter, maturity, tBal); } /* ========== ADMIN ========== */ /// @notice Enable or disable a adapter /// @param adapter Adapter's address /// @param isOn Flag setting this adapter to enabled or disabled function setAdapter(address adapter, bool isOn) public requiresTrust { _setAdapter(adapter, isOn); } /// @notice Set adapter's guard /// @param adapter Adapter address /// @param cap The max target that can be deposited on the Adapter function setGuard(address adapter, uint256 cap) external requiresTrust { adapterMeta[adapter].guard = cap; emit GuardChanged(adapter, cap); } /// @notice Set guarded mode /// @param _guarded bool function setGuarded(bool _guarded) external requiresTrust { guarded = _guarded; emit GuardedChanged(_guarded); } /// @notice Set periphery's contract /// @param _periphery Target address function setPeriphery(address _periphery) external requiresTrust { periphery = _periphery; emit PeripheryChanged(_periphery); } /// @notice Set paused flag /// @param _paused boolean function setPaused(bool _paused) external requiresTrust { _paused ? _pause() : _unpause(); } /// @notice Set permissioless mode /// @param _permissionless bool function setPermissionless(bool _permissionless) external requiresTrust { permissionless = _permissionless; emit PermissionlessChanged(_permissionless); } /// @notice Backfill a Series' Scale value at maturity if keepers failed to settle it /// @param adapter Adapter's address /// @param maturity Maturity date for the Series /// @param mscale Value to set as the Series' Scale value at maturity /// @param _usrs Values to set on lscales mapping /// @param _lscales Values to set on lscales mapping function backfillScale( address adapter, uint256 maturity, uint256 mscale, address[] calldata _usrs, uint256[] calldata _lscales ) external requiresTrust { if (!_exists(adapter, maturity)) revert Errors.SeriesDoesNotExist(); uint256 cutoff = maturity + SPONSOR_WINDOW + SETTLEMENT_WINDOW; // Admin can never backfill before maturity if (block.timestamp <= cutoff) revert Errors.OutOfWindowBoundaries(); // Set user's last scale values the Series (needed for the `collect` method) for (uint256 i = 0; i < _usrs.length; i++) { lscales[adapter][maturity][_usrs[i]] = _lscales[i]; } if (mscale > 0) { Series memory _series = series[adapter][maturity]; // Set the maturity scale for the Series (needed for `redeem` methods) series[adapter][maturity].mscale = mscale; if (mscale > _series.maxscale) { series[adapter][maturity].maxscale = mscale; } (address target, address stake, uint256 stakeSize) = Adapter(adapter).getStakeAndTarget(); address stakeDst = adapterMeta[adapter].enabled ? cup : _series.sponsor; ERC20(target).safeTransferFrom(adapter, cup, _series.reward); series[adapter][maturity].reward = 0; ERC20(stake).safeTransferFrom(adapter, stakeDst, stakeSize); } emit Backfilled(adapter, maturity, mscale, _usrs, _lscales); } /* ========== INTERNAL VIEWS ========== */ function _exists(address adapter, uint256 maturity) internal view returns (bool) { return series[adapter][maturity].pt != address(0); } function _settled(address adapter, uint256 maturity) internal view returns (bool) { return series[adapter][maturity].mscale > 0; } function _canBeSettled(address adapter, uint256 maturity) internal view returns (bool) { uint256 cutoff = maturity + SPONSOR_WINDOW + SETTLEMENT_WINDOW; // If the sender is the sponsor for the Series if (msg.sender == series[adapter][maturity].sponsor) { return maturity - SPONSOR_WINDOW <= block.timestamp && cutoff >= block.timestamp; } else { return maturity + SPONSOR_WINDOW < block.timestamp && cutoff >= block.timestamp; } } function _isValid(address adapter, uint256 maturity) internal view returns (bool) { (uint256 minm, uint256 maxm) = Adapter(adapter).getMaturityBounds(); if (maturity < block.timestamp + minm || maturity > block.timestamp + maxm) return false; (, , uint256 day, uint256 hour, uint256 minute, uint256 second) = DateTime.timestampToDateTime(maturity); if (hour != 0 || minute != 0 || second != 0) return false; uint256 mode = Adapter(adapter).mode(); if (mode == 0) { return day == 1; } if (mode == 1) { return DateTime.getDayOfWeek(maturity) == 1; } return false; } /* ========== INTERNAL UTILS ========== */ function _setAdapter(address adapter, bool isOn) internal { AdapterMeta memory am = adapterMeta[adapter]; if (am.enabled == isOn) revert Errors.ExistingValue(); am.enabled = isOn; // If this adapter is being added for the first time if (isOn && am.id == 0) { am.id = ++adapterCounter; adapterAddresses[am.id] = adapter; } // Set level and target (can only be done once); am.level = uint248(Adapter(adapter).level()); adapterMeta[adapter] = am; emit AdapterChanged(adapter, am.id, isOn); } /* ========== PUBLIC GETTERS ========== */ /// @notice Returns address of Principal Token function pt(address adapter, uint256 maturity) public view returns (address) { return series[adapter][maturity].pt; } /// @notice Returns address of Yield Token function yt(address adapter, uint256 maturity) public view returns (address) { return series[adapter][maturity].yt; } function mscale(address adapter, uint256 maturity) public view returns (uint256) { return series[adapter][maturity].mscale; } /* ========== MODIFIERS ========== */ modifier onlyYT(address adapter, uint256 maturity) { if (series[adapter][maturity].yt != msg.sender) revert Errors.OnlyYT(); _; } /* ========== LOGS ========== */ /// @notice Admin event Backfilled( address indexed adapter, uint256 indexed maturity, uint256 mscale, address[] _usrs, uint256[] _lscales ); event GuardChanged(address indexed adapter, uint256 cap); event AdapterChanged(address indexed adapter, uint256 indexed id, bool indexed isOn); event PeripheryChanged(address indexed periphery); /// @notice Series lifecycle /// *---- beginning event SeriesInitialized( address adapter, uint256 indexed maturity, address pt, address yt, address indexed sponsor, address indexed target ); /// -***- middle event Issued(address indexed adapter, uint256 indexed maturity, uint256 balance, address indexed sender); event Combined(address indexed adapter, uint256 indexed maturity, uint256 balance, address indexed sender); event Collected(address indexed adapter, uint256 indexed maturity, uint256 collected); /// ----* end event SeriesSettled(address indexed adapter, uint256 indexed maturity, address indexed settler); event PTRedeemed(address indexed adapter, uint256 indexed maturity, uint256 redeemed); event YTRedeemed(address indexed adapter, uint256 indexed maturity, uint256 redeemed); /// *----* misc event GuardedChanged(bool indexed guarded); event PermissionlessChanged(bool indexed permissionless); } contract TokenHandler is Trust { /// @notice Program state address public divider; constructor() Trust(msg.sender) {} function init(address _divider) external requiresTrust { if (divider != address(0)) revert Errors.AlreadyInitialized(); divider = _divider; } function deploy( address adapter, uint248 id, uint256 maturity ) external returns (address pt, address yt) { if (msg.sender != divider) revert Errors.OnlyDivider(); ERC20 target = ERC20(Adapter(adapter).target()); uint8 decimals = target.decimals(); string memory symbol = target.symbol(); (string memory d, string memory m, string memory y) = DateTime.toDateString(maturity); string memory date = DateTime.format(maturity); string memory datestring = string(abi.encodePacked(d, "-", m, "-", y)); string memory adapterId = DateTime.uintToString(id); pt = address( new Token( string(abi.encodePacked(date, " ", symbol, " Sense Principal Token, A", adapterId)), string(abi.encodePacked("sP-", symbol, ":", datestring, ":", adapterId)), decimals, divider ) ); yt = address( new YT( adapter, maturity, string(abi.encodePacked(date, " ", symbol, " Sense Yield Token, A", adapterId)), string(abi.encodePacked("sY-", symbol, ":", datestring, ":", adapterId)), decimals, divider ) ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*/////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*/////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*/////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*/////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*/////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*/////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @author Modified from Gnosis (https://github.com/gnosis/gp-v2-contracts/blob/main/src/contracts/libraries/GPv2SafeERC20.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. library SafeTransferLib { /*/////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool callStatus; assembly { // Transfer the ETH and store if it succeeded or not. callStatus := call(gas(), to, amount, 0, 0, 0, 0) } require(callStatus, "ETH_TRANSFER_FAILED"); } /*/////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "from" argument. mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 100 because the calldata length is 4 + 32 * 3. callStatus := call(gas(), token, 0, freeMemoryPointer, 100, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 68 because the calldata length is 4 + 32 * 2. callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 68 because the calldata length is 4 + 32 * 2. callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "APPROVE_FAILED"); } /*/////////////////////////////////////////////////////////////// INTERNAL HELPER LOGIC //////////////////////////////////////////////////////////////*/ function didLastOptionalReturnCallSucceed(bool callStatus) private pure returns (bool success) { assembly { // Get how many bytes the call returned. let returnDataSize := returndatasize() // If the call reverted: if iszero(callStatus) { // Copy the revert message into memory. returndatacopy(0, 0, returnDataSize) // Revert with the same message. revert(0, returnDataSize) } switch returnDataSize case 32 { // Copy the return data into memory. returndatacopy(0, 0, returnDataSize) // Set success to whether it returned true. success := iszero(iszero(mload(0))) } case 0 { // There was no return data. success := 1 } default { // It returned some malformed input. success := 0 } } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Gas optimized reentrancy protection for smart contracts. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol) abstract contract ReentrancyGuard { uint256 private reentrancyStatus = 1; modifier nonReentrant() { require(reentrancyStatus == 1, "REENTRANCY"); reentrancyStatus = 2; _; reentrancyStatus = 1; } }
pragma solidity 0.8.11; /// @author Taken from: https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary library DateTime { uint256 constant SECONDS_PER_DAY = 24 * 60 * 60; uint256 constant SECONDS_PER_HOUR = 60 * 60; uint256 constant SECONDS_PER_MINUTE = 60; int256 constant OFFSET19700101 = 2440588; function timestampToDate(uint256 timestamp) internal pure returns ( uint256 year, uint256 month, uint256 day ) { (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY); } function timestampToDateTime(uint256 timestamp) internal pure returns ( uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second ) { (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY); uint256 secs = timestamp % SECONDS_PER_DAY; hour = secs / SECONDS_PER_HOUR; secs = secs % SECONDS_PER_HOUR; minute = secs / SECONDS_PER_MINUTE; second = secs % SECONDS_PER_MINUTE; } function toDateString(uint256 _timestamp) internal pure returns ( string memory d, string memory m, string memory y ) { (uint256 year, uint256 month, uint256 day) = timestampToDate(_timestamp); d = uintToString(day); m = uintToString(month); y = uintToString(year); // append a 0 to numbers < 10 so we should, e.g, 01 instead of just 1 if (day < 10) d = string(abi.encodePacked("0", d)); if (month < 10) m = string(abi.encodePacked("0", m)); } function format(uint256 _timestamp) internal pure returns (string memory datestring) { string[12] memory months = [ "Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec" ]; (uint256 year, uint256 month, uint256 day) = timestampToDate(_timestamp); uint256 last = day % 10; string memory suffix = "th"; if (day < 11 || day > 20) { if (last == 1) suffix = "st"; if (last == 2) suffix = "nd"; if (last == 3) suffix = "rd"; } return string(abi.encodePacked(uintToString(day), suffix, " ", months[month - 1], " ", uintToString(year))); } function getDayOfWeek(uint256 timestamp) internal pure returns (uint256 dayOfWeek) { uint256 _days = timestamp / SECONDS_PER_DAY; dayOfWeek = ((_days + 3) % 7) + 1; } /// Taken from https://stackoverflow.com/questions/47129173/how-to-convert-uint-to-string-in-solidity function uintToString(uint256 _i) internal pure returns (string memory _uintAsString) { if (_i == 0) return "0"; uint256 j = _i; uint256 len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint256 k = len; while (_i != 0) { k = k - 1; uint8 temp = (48 + uint8(_i - (_i / 10) * 10)); bytes1 b1 = bytes1(temp); bstr[k] = b1; _i /= 10; } return string(bstr); } // ------------------------------------------------------------------------ // Calculate the number of days from 1970/01/01 to year/month/day using // the date conversion algorithm from // http://aa.usno.navy.mil/faq/docs/JD_Formula.php // and subtracting the offset 2440588 so that 1970/01/01 is day 0 // // days = day // - 32075 // + 1461 * (year + 4800 + (month - 14) / 12) / 4 // + 367 * (month - 2 - (month - 14) / 12 * 12) / 12 // - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4 // - offset // ------------------------------------------------------------------------ function _daysFromDate( uint256 year, uint256 month, uint256 day ) internal pure returns (uint256 _days) { require(year >= 1970); int256 _year = int256(year); int256 _month = int256(month); int256 _day = int256(day); int256 __days = _day - 32075 + (1461 * (_year + 4800 + (_month - 14) / 12)) / 4 + (367 * (_month - 2 - ((_month - 14) / 12) * 12)) / 12 - (3 * ((_year + 4900 + (_month - 14) / 12) / 100)) / 4 - OFFSET19700101; _days = uint256(__days); } // ------------------------------------------------------------------------ // Calculate year/month/day from the number of days since 1970/01/01 using // the date conversion algorithm from // http://aa.usno.navy.mil/faq/docs/JD_Formula.php // and adding the offset 2440588 so that 1970/01/01 is day 0 // // int L = days + 68569 + offset // int N = 4 * L / 146097 // L = L - (146097 * N + 3) / 4 // year = 4000 * (L + 1) / 1461001 // L = L - 1461 * year / 4 + 31 // month = 80 * L / 2447 // dd = L - 2447 * month / 80 // L = month / 11 // month = month + 2 - 12 * L // year = 100 * (N - 49) + year + L // ------------------------------------------------------------------------ function _daysToDate(uint256 _days) internal pure returns ( uint256 year, uint256 month, uint256 day ) { int256 __days = int256(_days); int256 L = __days + 68569 + OFFSET19700101; int256 N = (4 * L) / 146097; L = L - (146097 * N + 3) / 4; int256 _year = (4000 * (L + 1)) / 1461001; L = L - (1461 * _year) / 4 + 31; int256 _month = (80 * L) / 2447; int256 _day = L - (2447 * _month) / 80; L = _month / 11; _month = _month + 2 - 12 * L; _year = 100 * (N - 49) + _year + L; year = uint256(_year); month = uint256(_month); day = uint256(_day); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.11; /// @title Fixed point arithmetic library /// @author Taken from https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol library FixedMath { uint256 internal constant WAD = 1e18; uint256 internal constant RAY = 1e27; function fmul( uint256 x, uint256 y, uint256 baseUnit ) internal pure returns (uint256) { return mulDivDown(x, y, baseUnit); // Equivalent to (x * y) / baseUnit rounded down. } function fmul(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. } function fmulUp( uint256 x, uint256 y, uint256 baseUnit ) internal pure returns (uint256) { return mulDivUp(x, y, baseUnit); // Equivalent to (x * y) / baseUnit rounded up. } function fmulUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. } function fdiv( uint256 x, uint256 y, uint256 baseUnit ) internal pure returns (uint256) { return mulDivDown(x, baseUnit, y); // Equivalent to (x * baseUnit) / y rounded down. } function fdiv(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. } function fdivUp( uint256 x, uint256 y, uint256 baseUnit ) internal pure returns (uint256) { return mulDivUp(x, baseUnit, y); // Equivalent to (x * baseUnit) / y rounded up. } function fdivUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. } function mulDivDown( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // Divide z by the denominator. z := div(z, denominator) } } function mulDivUp( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // First, divide z - 1 by the denominator and add 1. // We allow z - 1 to underflow if z is 0, because we multiply the // end result by 0 if z is zero, ensuring we return 0 if z is zero. z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1)) } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.4; library Errors { // Auth error CombineRestricted(); error IssuanceRestricted(); error NotAuthorized(); error OnlyYT(); error OnlyDivider(); error OnlyPeriphery(); error OnlyPermissionless(); error RedeemRestricted(); error Untrusted(); // Adapters error TokenNotSupported(); error FlashCallbackFailed(); error InvalidMaturityOffsets(); error SenderNotEligible(); error TargetMismatch(); error TargetNotSupported(); // Divider error AlreadySettled(); error CollectNotSettled(); error GuardCapReached(); error IssuanceFeeCapExceeded(); error IssueOnSettle(); error NotSettled(); // Input & validations error AlreadyInitialized(); error DuplicateSeries(); error ExistingValue(); error InvalidAdapter(); error InvalidMaturity(); error InvalidParam(); error OutOfWindowBoundaries(); error SeriesDoesNotExist(); error SwapTooSmall(); error TargetParamsNotSet(); error PoolParamsNotSet(); error PTParamsNotSet(); // Periphery error FactoryNotSupported(); error FlashBorrowFailed(); error FlashUntrustedBorrower(); error FlashUntrustedLoanInitiator(); error UnexpectedSwapAmount(); // Fuse error AdapterNotSet(); error FailedBecomeAdmin(); error FailedAddTargetMarket(); error FailedToAddPTMarket(); error FailedAddLpMarket(); error OracleNotReady(); error PoolAlreadyDeployed(); error PoolNotDeployed(); error PoolNotSet(); error SeriesNotQueued(); error TargetExists(); error TargetNotInFuse(); // Tokens error MintFailed(); error RedeemFailed(); error TransferFailed(); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.7.0; library Levels { uint256 private constant _INIT_BIT = 0x1; uint256 private constant _ISSUE_BIT = 0x2; uint256 private constant _COMBINE_BIT = 0x4; uint256 private constant _COLLECT_BIT = 0x8; uint256 private constant _REDEEM_BIT = 0x10; uint256 private constant _REDEEM_HOOK_BIT = 0x20; function initRestricted(uint256 level) internal pure returns (bool) { return level & _INIT_BIT != _INIT_BIT; } function issueRestricted(uint256 level) internal pure returns (bool) { return level & _ISSUE_BIT != _ISSUE_BIT; } function combineRestricted(uint256 level) internal pure returns (bool) { return level & _COMBINE_BIT != _COMBINE_BIT; } function collectDisabled(uint256 level) internal pure returns (bool) { return level & _COLLECT_BIT != _COLLECT_BIT; } function redeemRestricted(uint256 level) internal pure returns (bool) { return level & _REDEEM_BIT != _REDEEM_BIT; } function redeemHookDisabled(uint256 level) internal pure returns (bool) { return level & _REDEEM_HOOK_BIT != _REDEEM_HOOK_BIT; } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.7.0; /// @notice Ultra minimal authorization logic for smart contracts. /// @author From https://github.com/Rari-Capital/solmate/blob/fab107565a51674f3a3b5bfdaacc67f6179b1a9b/src/auth/Trust.sol abstract contract Trust { event UserTrustUpdated(address indexed user, bool trusted); mapping(address => bool) public isTrusted; constructor(address initialUser) { isTrusted[initialUser] = true; emit UserTrustUpdated(initialUser, true); } function setIsTrusted(address user, bool trusted) public virtual requiresTrust { isTrusted[user] = trusted; emit UserTrustUpdated(user, trusted); } modifier requiresTrust() { require(isTrusted[msg.sender], "UNTRUSTED"); _; } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.11; // Internal references import { Divider } from "../Divider.sol"; import { Token } from "./Token.sol"; /// @title Yield Token /// @notice Strips off excess before every transfer contract YT is Token { address public immutable adapter; address public immutable divider; uint256 public immutable maturity; constructor( address _adapter, uint256 _maturity, string memory _name, string memory _symbol, uint8 _decimals, address _divider ) Token(_name, _symbol, _decimals, _divider) { adapter = _adapter; maturity = _maturity; divider = _divider; } function collect() external returns (uint256 _collected) { return Divider(divider).collect(msg.sender, adapter, maturity, 0, address(0)); } function transfer(address to, uint256 value) public override returns (bool) { Divider(divider).collect(msg.sender, adapter, maturity, value, to); return super.transfer(to, value); } function transferFrom( address from, address to, uint256 value ) public override returns (bool) { if (value > 0) Divider(divider).collect(from, adapter, maturity, value, to); return super.transferFrom(from, to, value); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.11; // External references import { ERC20 } from "@rari-capital/solmate/src/tokens/ERC20.sol"; // Internal references import { Trust } from "@sense-finance/v1-utils/src/Trust.sol"; /// @title Base Token contract Token is ERC20, Trust { constructor( string memory _name, string memory _symbol, uint8 _decimals, address _trusted ) ERC20(_name, _symbol, _decimals) Trust(_trusted) {} /// @param usr The address to send the minted tokens /// @param amount The amount to be minted function mint(address usr, uint256 amount) public requiresTrust { _mint(usr, amount); } /// @param usr The address from where to burn tokens from /// @param amount The amount to be burned function burn(address usr, uint256 amount) public requiresTrust { _burn(usr, amount); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.11; // External references import { ERC20 } from "@rari-capital/solmate/src/tokens/ERC20.sol"; import { SafeTransferLib } from "@rari-capital/solmate/src/utils/SafeTransferLib.sol"; import { IERC3156FlashLender } from "../external/flashloan/IERC3156FlashLender.sol"; import { IERC3156FlashBorrower } from "../external/flashloan/IERC3156FlashBorrower.sol"; // Internal references import { Divider } from "../Divider.sol"; import { Errors } from "@sense-finance/v1-utils/src/libs/Errors.sol"; /// @title Assign value to Target tokens abstract contract BaseAdapter is IERC3156FlashLender { using SafeTransferLib for ERC20; /* ========== CONSTANTS ========== */ bytes32 public constant CALLBACK_SUCCESS = keccak256("ERC3156FlashBorrower.onFlashLoan"); /* ========== PUBLIC IMMUTABLES ========== */ /// @notice Sense core Divider address address public immutable divider; /// @notice Target token to divide address public immutable target; /// @notice Underlying for the Target address public immutable underlying; /// @notice Oracle address address public immutable oracle; /// @notice Token to stake at issuance address public immutable stake; /// @notice Amount to stake at issuance uint256 public immutable stakeSize; /// @notice Min maturity (seconds after block.timstamp) uint256 public immutable minm; /// @notice Max maturity (seconds after block.timstamp) uint256 public immutable maxm; /// @notice 0 for monthly, 1 for weekly uint256 public immutable mode; /// @notice Issuance fee uint256 public immutable ifee; /// @notice WAD number representing the percentage of the total /// principal that's set aside for Yield Tokens (e.g. 0.1e18 means that 10% of the principal is reserved). /// @notice If `0`, it means no principal is set aside for Yield Tokens uint256 public immutable tilt; /// @notice The number this function returns will be used to determine its access by checking for binary /// digits using the following scheme: <onRedeem(y/n)><collect(y/n)><combine(y/n)><issue(y/n)> /// (e.g. 0101 enables `collect` and `issue`, but not `combine`) uint256 public immutable level; /* ========== METADATA STORAGE ========== */ string public name; string public symbol; constructor( address _divider, address _target, address _underlying, address _oracle, uint256 _ifee, address _stake, uint256 _stakeSize, uint256 _minm, uint256 _maxm, uint256 _mode, uint256 _tilt, uint256 _level ) { // Sanity check if (_minm >= _maxm) revert Errors.InvalidMaturityOffsets(); divider = _divider; target = _target; underlying = _underlying; oracle = _oracle; ifee = _ifee; stake = _stake; stakeSize = _stakeSize; minm = _minm; maxm = _maxm; mode = _mode; tilt = _tilt; name = string(abi.encodePacked(ERC20(_target).name(), " Adapter")); symbol = string(abi.encodePacked(ERC20(_target).symbol(), "-adapter")); level = _level; ERC20(_target).approve(_divider, type(uint256).max); ERC20(_stake).approve(_divider, type(uint256).max); } /// @notice Loan `amount` target to `receiver`, and takes it back after the callback. /// @param receiver The contract receiving target, needs to implement the /// `onFlashLoan(address user, address adapter, uint256 maturity, uint256 amount)` interface. /// @param amount The amount of target lent. /// @param data (encoded adapter address, maturity and YT amount the use has sent in) function flashLoan( IERC3156FlashBorrower receiver, address, /* fee */ uint256 amount, bytes calldata data ) external returns (bool) { if (Divider(divider).periphery() != msg.sender) revert Errors.OnlyPeriphery(); ERC20(target).safeTransfer(address(receiver), amount); bytes32 keccak = IERC3156FlashBorrower(receiver).onFlashLoan(msg.sender, target, amount, 0, data); if (keccak != CALLBACK_SUCCESS) revert Errors.FlashCallbackFailed(); ERC20(target).safeTransferFrom(address(receiver), address(this), amount); return true; } /* ========== REQUIRED VALUE GETTERS ========== */ /// @notice Calculate and return this adapter's Scale value for the current timestamp. To be overriden by child contracts /// @dev For some Targets, such as cTokens, this is simply the exchange rate, or `supply cToken / supply underlying` /// @dev For other Targets, such as AMM LP shares, specialized logic will be required /// @dev This function _must_ return a WAD number representing the current exchange rate /// between the Target and the Underlying. /// @return value WAD Scale value function scale() external virtual returns (uint256); /// @notice Cached scale value getter /// @dev For situations where you need scale from a view function function scaleStored() external view virtual returns (uint256); /// @notice Returns the current price of the underlying in ETH terms function getUnderlyingPrice() external view virtual returns (uint256); /* ========== REQUIRED UTILITIES ========== */ /// @notice Deposits underlying `amount`in return for target. Must be overriden by child contracts /// @param amount Underlying amount /// @return amount of target returned function wrapUnderlying(uint256 amount) external virtual returns (uint256); /// @notice Deposits target `amount`in return for underlying. Must be overriden by child contracts /// @param amount Target amount /// @return amount of underlying returned function unwrapTarget(uint256 amount) external virtual returns (uint256); function flashFee(address token, uint256) external view returns (uint256) { if (token != target) revert Errors.TokenNotSupported(); return 0; } function maxFlashLoan(address token) external view override returns (uint256) { return ERC20(token).balanceOf(address(this)); } /* ========== OPTIONAL HOOKS ========== */ /// @notice Notification whenever the Divider adds or removes Target function notify( address, /* usr */ uint256, /* amt */ bool /* join */ ) public virtual { return; } /// @notice Hook called whenever a user redeems PT function onRedeem( uint256, /* uBal */ uint256, /* mscale */ uint256, /* maxscale */ uint256 /* tBal */ ) public virtual { return; } /* ========== PUBLIC STORAGE ACCESSORS ========== */ function getMaturityBounds() external view returns (uint256, uint256) { return (minm, maxm); } function getStakeAndTarget() external view returns ( address, address, uint256 ) { return (target, stake, stakeSize); } }
// SPDX-License-Identifier: MIT 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; } }
pragma solidity ^0.8.0; import "./IERC3156FlashBorrower.sol"; interface IERC3156FlashLender { /// @dev The amount of currency available to be lent. /// @param token The loan currency. /// @return The amount of `token` that can be borrowed. function maxFlashLoan(address token) external view returns (uint256); /// @dev The fee to be charged for a given loan. /// @param token The loan currency. /// @param amount The amount of tokens lent. /// @return The amount of `token` to be charged for the loan, on top of the returned principal. function flashFee(address token, uint256 amount) external view returns (uint256); /// @dev Initiate a flash loan. /// @param receiver The receiver of the tokens in the loan, and the receiver of the callback. /// @param token The loan currency. /// @param amount The amount of tokens lent. /// @param data Arbitrary data structure, intended to contain user-defined parameters. function flashLoan( IERC3156FlashBorrower receiver, address token, uint256 amount, bytes calldata data ) external returns (bool); }
pragma solidity ^0.8.0; interface IERC3156FlashBorrower { /// @dev Receive a flash loan. /// @param initiator The initiator of the loan. /// @param token The loan currency. /// @param amount The amount of tokens lent. /// @param fee The additional amount of tokens to repay. /// @param data Arbitrary data structure, intended to contain user-defined parameters. /// @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan" function onFlashLoan( address initiator, address token, uint256 amount, uint256 fee, bytes calldata data ) external returns (bytes32); }
{ "optimizer": { "enabled": true, "runs": 1500 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_cup","type":"address"},{"internalType":"address","name":"_tokenHandler","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadySettled","type":"error"},{"inputs":[],"name":"CollectNotSettled","type":"error"},{"inputs":[],"name":"CombineRestricted","type":"error"},{"inputs":[],"name":"DuplicateSeries","type":"error"},{"inputs":[],"name":"ExistingValue","type":"error"},{"inputs":[],"name":"GuardCapReached","type":"error"},{"inputs":[],"name":"InvalidAdapter","type":"error"},{"inputs":[],"name":"InvalidMaturity","type":"error"},{"inputs":[],"name":"IssuanceFeeCapExceeded","type":"error"},{"inputs":[],"name":"IssuanceRestricted","type":"error"},{"inputs":[],"name":"IssueOnSettle","type":"error"},{"inputs":[],"name":"NotSettled","type":"error"},{"inputs":[],"name":"OnlyPeriphery","type":"error"},{"inputs":[],"name":"OnlyPermissionless","type":"error"},{"inputs":[],"name":"OnlyYT","type":"error"},{"inputs":[],"name":"OutOfWindowBoundaries","type":"error"},{"inputs":[],"name":"RedeemRestricted","type":"error"},{"inputs":[],"name":"SeriesDoesNotExist","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"adapter","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"isOn","type":"bool"}],"name":"AdapterChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"adapter","type":"address"},{"indexed":true,"internalType":"uint256","name":"maturity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mscale","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"_usrs","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"_lscales","type":"uint256[]"}],"name":"Backfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"adapter","type":"address"},{"indexed":true,"internalType":"uint256","name":"maturity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collected","type":"uint256"}],"name":"Collected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"adapter","type":"address"},{"indexed":true,"internalType":"uint256","name":"maturity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"Combined","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"adapter","type":"address"},{"indexed":false,"internalType":"uint256","name":"cap","type":"uint256"}],"name":"GuardChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"guarded","type":"bool"}],"name":"GuardedChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"adapter","type":"address"},{"indexed":true,"internalType":"uint256","name":"maturity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"Issued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"adapter","type":"address"},{"indexed":true,"internalType":"uint256","name":"maturity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeemed","type":"uint256"}],"name":"PTRedeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"periphery","type":"address"}],"name":"PeripheryChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"permissionless","type":"bool"}],"name":"PermissionlessChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"adapter","type":"address"},{"indexed":true,"internalType":"uint256","name":"maturity","type":"uint256"},{"indexed":false,"internalType":"address","name":"pt","type":"address"},{"indexed":false,"internalType":"address","name":"yt","type":"address"},{"indexed":true,"internalType":"address","name":"sponsor","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"}],"name":"SeriesInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"adapter","type":"address"},{"indexed":true,"internalType":"uint256","name":"maturity","type":"uint256"},{"indexed":true,"internalType":"address","name":"settler","type":"address"}],"name":"SeriesSettled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"trusted","type":"bool"}],"name":"UserTrustUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"adapter","type":"address"},{"indexed":true,"internalType":"uint256","name":"maturity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeemed","type":"uint256"}],"name":"YTRedeemed","type":"event"},{"inputs":[],"name":"ISSUANCE_FEE_CAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SETTLEMENT_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SPONSOR_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"adapterAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adapterCounter","outputs":[{"internalType":"uint248","name":"","type":"uint248"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"adapterMeta","outputs":[{"internalType":"uint248","name":"id","type":"uint248"},{"internalType":"bool","name":"enabled","type":"bool"},{"internalType":"uint256","name":"guard","type":"uint256"},{"internalType":"uint248","name":"level","type":"uint248"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"}],"name":"addAdapter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"mscale","type":"uint256"},{"internalType":"address[]","name":"_usrs","type":"address[]"},{"internalType":"uint256[]","name":"_lscales","type":"uint256[]"}],"name":"backfillScale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"usr","type":"address"},{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"uBalTransfer","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"collect","outputs":[{"internalType":"uint256","name":"collected","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"uBal","type":"uint256"}],"name":"combine","outputs":[{"internalType":"uint256","name":"tBal","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cup","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guarded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"address","name":"sponsor","type":"address"}],"name":"initSeries","outputs":[{"internalType":"address","name":"pt","type":"address"},{"internalType":"address","name":"yt","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isTrusted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"tBal","type":"uint256"}],"name":"issue","outputs":[{"internalType":"uint256","name":"uBal","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"lscales","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"maturity","type":"uint256"}],"name":"mscale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periphery","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permissionless","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"maturity","type":"uint256"}],"name":"pt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"uBal","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"tBal","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"series","outputs":[{"internalType":"address","name":"pt","type":"address"},{"internalType":"uint48","name":"issuance","type":"uint48"},{"internalType":"address","name":"yt","type":"address"},{"internalType":"uint96","name":"tilt","type":"uint96"},{"internalType":"address","name":"sponsor","type":"address"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"iscale","type":"uint256"},{"internalType":"uint256","name":"mscale","type":"uint256"},{"internalType":"uint256","name":"maxscale","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"bool","name":"isOn","type":"bool"}],"name":"setAdapter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"cap","type":"uint256"}],"name":"setGuard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_guarded","type":"bool"}],"name":"setGuarded","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"trusted","type":"bool"}],"name":"setIsTrusted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_periphery","type":"address"}],"name":"setPeriphery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_permissionless","type":"bool"}],"name":"setPermissionless","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"maturity","type":"uint256"}],"name":"settleSeries","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"uint256","name":"maturity","type":"uint256"}],"name":"yt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c0604052600180556002805460ff60b01b1916600160b01b1790553480156200002857600080fd5b5060405162004823380380620048238339810160408190526200004b91620000dc565b3360008181526020818152604091829020805460ff19166001908117909155915191825282917fe95aec380cae16330d146d5499ef7db6f3657e477104a733e771bc09e500d986910160405180910390a2506002805460ff191690556001600160a01b039182166080521660a05262000114565b80516001600160a01b0381168114620000d757600080fd5b919050565b60008060408385031215620000f057600080fd5b620000fb83620000bf565b91506200010b60208401620000bf565b90509250929050565b60805160a0516146d46200014f600039600081816103c10152610f2b015260008181610457015281816122ae01526122d601526146d46000f3fe608060405234801561001057600080fd5b506004361061020b5760003560e01c806372f7a0301161012a578063a4141638116100bd578063c9eb4f981161008c578063d10eb4b911610071578063d10eb4b914610671578063dfe5ef48146106a7578063f2d63d0e146106ba57600080fd5b8063c9eb4f981461064b578063d10c16a91461065e57600080fd5b8063a4141638146105e7578063aeb22934146105fa578063ba89bebd1461060d578063c5a067e31461062057600080fd5b806395197d30116100f957806395197d301461056457806396d648791461059d578063a1256f9f146105c0578063a131ad74146105d457600080fd5b806372f7a030146104fc57806375708a591461051057806377aace1a146105235780637c9170381461053b57600080fd5b8063332f6465116101a2578063574e779511610171578063574e7795146104ac5780635c975abb146104bf5780635fa0cc0a146104d657806360d54d41146104e957600080fd5b8063332f64651461043f5780633ad10beb146104525780633deb6cae1461037d5780633e3972ee1461047957600080fd5b806316c38b3c116101de57806316c38b3c146103a95780631b3d6e87146103bc5780632b83cccd146103fb5780632f9cd8541461040e57600080fd5b80630891d30a146102105780630cbe8db1146103085780630fe0554d1461037d5780631393916a14610394575b600080fd5b61029461021e36600461402c565b6006602081815260009384526040808520909152918352912080546001820154600283015460038401546004850154600586015495909601546001600160a01b0380861697600160a01b9687900465ffffffffffff1697828716979096046bffffffffffffffffffffffff169591909416939189565b604080516001600160a01b039a8b16815265ffffffffffff90991660208a0152968916968801969096526bffffffffffffffffffffffff909416606087015295909116608085015260a084015260c083019390935260e0820192909252610100810191909152610120015b60405180910390f35b61034e610316366004614058565b6005602052600090815260409020805460018201546002909201546001600160f81b0380831693600160f81b90930460ff1692911684565b604080516001600160f81b039586168152931515602085015283019190915290911660608201526080016102ff565b610386612a3081565b6040519081526020016102ff565b6103a76103a236600461408a565b6106c8565b005b6103a76103b73660046140bf565b610776565b6103e37f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102ff565b6103866104093660046140da565b6107d9565b61038661041c36600461410f565b600760209081526000938452604080852082529284528284209052825290205481565b6103a761044d36600461408a565b610c4a565b6103e37f000000000000000000000000000000000000000000000000000000000000000081565b61048c61048736600461410f565b610ca3565b604080516001600160a01b039384168152929091166020830152016102ff565b6103e36104ba36600461402c565b611280565b60025460ff165b60405190151581526020016102ff565b6103a76104e436600461402c565b6112b0565b6103a76104f7366004614058565b61134b565b6002546104c690600160b01b900460ff1681565b6103a761051e3660046140bf565b61146b565b6002546103e39061010090046001600160a01b031681565b6103e3610549366004614151565b6004602052600090815260409020546001600160a01b031681565b61038661057236600461402c565b6001600160a01b03919091166000908152600660209081526040808320938352929052206005015490565b6104c66105ab366004614058565b60006020819052908152604090205460ff1681565b6002546104c690600160a81b900460ff1681565b6103866105e236600461416a565b61151a565b6103a76105f536600461402c565b6116a8565b6103a7610608366004614058565b611a07565b61038661061b3660046140da565b611abb565b600354610633906001600160f81b031681565b6040516001600160f81b0390911681526020016102ff565b6103a76106593660046140bf565b611f0b565b6103a761066c366004614215565b611fba565b6103e361067f36600461402c565b6001600160a01b03918216600090815260066020908152604080832093835292905220541690565b6103866106b53660046140da565b6123cd565b61038666b1a2bc2ec5000081565b3360009081526020819052604090205460ff166107185760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b60448201526064015b60405180910390fd5b6001600160a01b03821660008181526020818152604091829020805460ff191685151590811790915591519182527fe95aec380cae16330d146d5499ef7db6f3657e477104a733e771bc09e500d98691015b60405180910390a25050565b3360009081526020819052604090205460ff166107c15760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b806107d1576107ce612b60565b50565b6107ce612bfc565b600060015460011461081a5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b600260015561082b60025460ff1690565b1561086b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6001600160a01b03841660009081526006602090815260408083208684529091529020600501546108c8576040517fba329a9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0384166000908152600560205260409020600201546001600160f81b03166108fb816010908116141590565b801561090f5750336001600160a01b038616145b15610946576040517f9ad6d35d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03858116600090815260066020908152604080832088845290915290819020549051632770a7eb60e21b815233600482015260248101869052911690639dc29fac90604401600060405180830381600087803b1580156109ac57600080fd5b505af11580156109c0573d6000803e3d6000fd5b505050506001600160a01b0385166000908152600660209081526040808320878452909152812060010154610a1290600160a01b90046bffffffffffffffffffffffff16670de0b6b3a76400006142c1565b6001600160a01b03871660009081526006602081815260408084208a8552909152909120908101546005909101549192508291610a4e91612c77565b10610a95576001600160a01b0386166000908152600660209081526040808320888452909152902060050154610a8482866142d8565b610a8e919061430d565b9250610ac9565b6001600160a01b03861660009081526006602081815260408084208985529091529091200154610ac6908590612c77565b92505b60208083161415610b80576001600160a01b03861660008181526006602081815260408084208a855290915291829020600581015491015491517f14282f580000000000000000000000000000000000000000000000000000000081526004810188905260248101919091526044810191909152606481018590526314282f5890608401600060405180830381600087803b158015610b6757600080fd5b505af1158015610b7b573d6000803e3d6000fd5b505050505b610bf9863385896001600160a01b031663d4b839926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be89190614321565b6001600160a01b0316929190612c93565b84866001600160a01b03167f2d0320e3c19b591925fca7a3012a905faf26dead7f53eb9c4c72744f04bde98085604051610c3591815260200190565b60405180910390a35050600180559392505050565b3360009081526020819052604090205460ff16610c955760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b610c9f8282612d49565b5050565b600080600154600114610ce55760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b6002600155610cf660025460ff1690565b15610d365760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b60025461010090046001600160a01b03163314610d7f576040517ffb02114900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516600090815260056020526040902054600160f81b900460ff16610dbf5760405163fbf66df160e01b815260040160405180910390fd5b6001600160a01b0380861660009081526006602090815260408083208884529091529020541615610e1c576040517fd309d88400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e268585612f99565b610e5c576040517fc7a682c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000876001600160a01b03166327b327d06040518163ffffffff1660e01b8152600401606060405180830381865afa158015610e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec3919061433e565b6001600160a01b038b8116600081815260056020526040908190205490517fafd3adb000000000000000000000000000000000000000000000000000000000815260048101929092526001600160f81b03166024820152604481018c905293965091945092507f0000000000000000000000000000000000000000000000000000000000000000169063afd3adb09060640160408051808303816000875af1158015610f73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f979190614381565b80955081965050506000886001600160a01b031663f51e181a6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610fe1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100591906143bb565b905085600660008b6001600160a01b03166001600160a01b0316815260200190815260200160002060008a815260200190815260200160002060000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555042600660008b6001600160a01b03166001600160a01b0316815260200190815260200160002060008a815260200190815260200160002060000160146101000a81548165ffffffffffff021916908365ffffffffffff16021790555084600660008b6001600160a01b03166001600160a01b0316815260200190815260200160002060008a815260200190815260200160002060010160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550886001600160a01b031663c39a3b296040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118191906143bb565b6001600160a01b038a811660009081526006602081815260408084208e85529091529091206001810180548416600160a01b6bffffffffffffffffffffffff9690961695909502949094179093556002830180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168b84161790556004830184905591909101829055611219908416338b85612c93565b604080516001600160a01b038b811682528881166020830152878116828401529151868316928a16918b917f1f35e8bec0a1a6f4c72b2ae05a4b8fdc78d03eab2dc742fab6ae238201c8189b9181900360600190a450506001805550919590945092505050565b6001600160a01b038083166000908152600660209081526040808320858452909152902060010154165b92915050565b3360009081526020819052604090205460ff166112fb5760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b6001600160a01b03821660008181526005602052604090819020600101839055517ff16a3457e9b9a5c31fda410fd95ed37234eafeb546daeb8a99f8895f94bf8fee9061076a9084815260200190565b60025460ff16156113915760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b600254600160a81b900460ff161580156113bb575060025461010090046001600160a01b03163314155b156113f2576040517f8719352c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166000908152600560205260409020546001600160f81b03161580159061144257506001600160a01b038116600090815260056020526040902054600160f81b900460ff16155b156114605760405163fbf66df160e01b815260040160405180910390fd5b6107ce816001612d49565b3360009081526020819052604090205460ff166114b65760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b600280547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b831515908102919091179091556040517f44a4c963afeb7bcec3494bbd13068371938a27639a9a9a7bac56c11777fd410990600090a250565b600060015460011461155b5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b600260019081556001600160a01b038087166000908152600660209081526040808320898452909152902090910154869186911633146115c7576040517fb114ba9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460ff161561160d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6040516370a0823160e01b81526001600160a01b038916600482015260009033906370a0823190602401602060405180830381865afa158015611654573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167891906143bb565b90506116978989898460008b1161168f5785611691565b8a5b8a613129565b600180559998505050505050505050565b6001546001146116e75760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b60026001556116f860025460ff1690565b156117385760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6001600160a01b038216600090815260056020526040902054600160f81b900460ff166117785760405163fbf66df160e01b815260040160405180910390fd5b6001600160a01b038083166000908152600660209081526040808320858452909152902054166117bb57604051631760174360e01b815260040160405180910390fd5b6001600160a01b038216600090815260066020908152604080832084845290915290206005015415611819576040517f560ff90000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611823828261396f565b61184057604051634296f34160e11b815260040160405180910390fd5b6000826001600160a01b031663f51e181a6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a691906143bb565b6001600160a01b0384166000908152600660208181526040808420878552909152909120600581018390550154909150811115611906576001600160a01b0383166000908152600660208181526040808420868552909152909120018190555b6000806000856001600160a01b03166327b327d06040518163ffffffff1660e01b8152600401606060405180830381865afa158015611949573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196d919061433e565b6001600160a01b03808a1660009081526006602090815260408083208c845290915290206003015493965091945092506119ae919085169088903390612c93565b6119c36001600160a01b038316873384612c93565b604051339086906001600160a01b038916907fd1426f892f3cce4b1085d051aa4be26da2192d8db075f55bc75f185d38ea624b90600090a450506001805550505050565b3360009081526020819052604090205460ff16611a525760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b600280547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b038416908102919091179091556040517f1deeec14e500a86432231bf144d0a12a439494bd11662a44a7e49d868451e74b90600090a250565b6000600154600114611afc5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b6002600155611b0d60025460ff1690565b15611b4d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6001600160a01b038416600090815260056020526040902054600160f81b900460ff16611b8d5760405163fbf66df160e01b815260040160405180910390fd5b6001600160a01b03808516600090815260066020908152604080832087845290915290205416611bd057604051631760174360e01b815260040160405180910390fd5b6001600160a01b0384166000908152600560205260409020600201546001600160f81b0316611c03816004908116141590565b8015611c185750336001600160a01b03861614155b15611c4f576040517f66bed65200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03858116600090815260066020908152604080832088845290915290819020549051632770a7eb60e21b815233600482015260248101869052911690639dc29fac90604401600060405180830381600087803b158015611cb557600080fd5b505af1158015611cc9573d6000803e3d6000fd5b505050506000611cde33878787886000613129565b6001600160a01b038716600090815260066020908152604080832089845290915290206005015490915080151580611df8576001600160a01b0388811660009081526006602090815260408083208b845290915290819020600101549051632770a7eb60e21b815233600482015260248101899052911690639dc29fac90604401600060405180830381600087803b158015611d7957600080fd5b505af1158015611d8d573d6000803e3d6000fd5b5050505060088085161415611dcd576001600160a01b03881660009081526007602090815260408083208a84528252808320338452909152902054611df5565b6001600160a01b03881660009081526006602090815260408083208a84529091529020600401545b91505b611e028683612c77565b9450611e488833878b6001600160a01b031663d4b839926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bc4573d6000803e3d6000fd5b80611eb557604051635a424b9560e11b815233600482015260248101869052600060448201526001600160a01b0389169063b484972a90606401600060405180830381600087803b158015611e9c57600080fd5b505af1158015611eb0573d6000803e3d6000fd5b505050505b60405194830180865294339088906001600160a01b038b16907fc93ef223012fd8a42ae087bcd98f3ea6c91a3596f56fb683451dda1abc5b695c9060200160405180910390a45050600180555090949350505050565b3360009081526020819052604090205460ff16611f565760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b600280547fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff16600160b01b831515908102919091179091556040517fdbcdd9941cbf70eec96e3ddaf2d230966f8224f1b7ec8af263cb8ca4803dfe6f90600090a250565b3360009081526020819052604090205460ff166120055760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b6001600160a01b0380881660009081526006602090815260408083208a84529091529020541661204857604051631760174360e01b815260040160405180910390fd5b6000612a3061205781896143d4565b61206191906143d4565b905080421161208357604051634296f34160e11b815260040160405180910390fd5b60005b84811015612120578383828181106120a0576120a06143ec565b6001600160a01b038c1660009081526007602090815260408083208e84528252822092029390930135929091508888858181106120df576120df6143ec565b90506020020160208101906120f49190614058565b6001600160a01b031681526020810191909152604001600020558061211881614402565b915050612086565b508515612379576001600160a01b0388811660009081526006602081815260408084208c855280835281852082516101208101845281548089168252600160a01b9081900465ffffffffffff16828701526001830154808a16958301959095529093046bffffffffffffffffffffffff16606084015260028101549096166080830152600386015460a0830152600486015460c083015260058601805460e084015295909301546101008201908152938c9052919052918890555187111561220b576001600160a01b03891660009081526006602081815260408084208c8552909152909120018790555b60008060008b6001600160a01b03166327b327d06040518163ffffffff1660e01b8152600401606060405180830381865afa15801561224e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612272919061433e565b6001600160a01b038f16600090815260056020526040812054939650919450925090600160f81b900460ff166122ac5784608001516122ce565b7f00000000000000000000000000000000000000000000000000000000000000005b90506123148d7f00000000000000000000000000000000000000000000000000000000000000008760a00151876001600160a01b0316612c93909392919063ffffffff16565b6000600660008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008e8152602001908152602001600020600301819055506123738d8284866001600160a01b0316612c93909392919063ffffffff16565b50505050505b86886001600160a01b03167f9f7c9b961af682670e128c89a9a1d940800d7c3d7693ab5608f21dd2c04d740f88888888886040516123bb95949392919061441d565b60405180910390a35050505050505050565b600060015460011461240e5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b600260015561241f60025460ff1690565b1561245f5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6001600160a01b038416600090815260056020526040902054600160f81b900460ff1661249f5760405163fbf66df160e01b815260040160405180910390fd5b6001600160a01b038085166000908152600660209081526040808320878452909152902054166124e257604051631760174360e01b815260040160405180910390fd5b6001600160a01b038416600090815260066020908152604080832086845290915290206005015415612540576040517f0de7115500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0384166000908152600560205260409020600201546001600160f81b0316612573816002908116141590565b80156125885750336001600160a01b03861614155b156125bf576040517f8159f88400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000856001600160a01b031663d4b839926040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126239190614321565b90506000866001600160a01b031663b8c15a9f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612665573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268991906143bb565b905066b1a2bc2ec500008111156126cc576040517f2e68f33400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006126d886836139fe565b6001600160a01b03891660009081526006602090815260408083208b8452909152812060030180548301905590915061271182886142c1565b600254909150600160b01b900460ff1680156127af57506001600160a01b03898116600081815260056020526040908190206001015490516370a0823160e01b81526004810192909252918991908716906370a0823190602401602060405180830381865afa158015612788573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ac91906143bb565b01115b156127e6576040517f6493914000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051635a424b9560e11b815233600482015260248101829052600160448201526001600160a01b038a169063b484972a90606401600060405180830381600087803b15801561283557600080fd5b505af1158015612849573d6000803e3d6000fd5b50600092505050600880871614156128c457896001600160a01b031663f51e181a6040518163ffffffff1660e01b81526004016020604051808303816000875af115801561289b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128bf91906143bb565b6128ec565b6001600160a01b038a1660009081526006602090815260408083208c84529091529020600401545b90506128f882826139fe565b6001600160a01b038b1660009081526007602090815260408083208d84528252808320338452909152902054909750156129ca576001600160a01b038a811660009081526006602090815260408083208d8452909152908190206001015490516370a0823160e01b81523360048201526129c5928d928d929116906370a0823190602401602060405180830381865afa158015612999573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129bd91906143bb565b8a3386613a13565b6129cc565b805b6001600160a01b038b811660008181526007602090815260408083208f845282528083203380855290835281842096909655928252600681528282208e835290528190205490516340c10f1960e01b81526004810193909352602483018a905216906340c10f1990604401600060405180830381600087803b158015612a5157600080fd5b505af1158015612a65573d6000803e3d6000fd5b505050506001600160a01b038a811660009081526006602090815260408083208d8452909152908190206001015490516340c10f1960e01b8152336004820152602481018a90529116906340c10f1990604401600060405180830381600087803b158015612ad257600080fd5b505af1158015612ae6573d6000803e3d6000fd5b50612b00925050506001600160a01b038616338c8b612c93565b336001600160a01b0316898b6001600160a01b03167ff75041e6352580ba937fde3a7ff5ff99bd178f75ac104184f85e3abbaaa44fef8a604051612b4691815260200190565b60405180910390a450506001805550929695505050505050565b60025460ff16612bb25760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161070f565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60025460ff1615612c425760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612bdf3390565b6000612c8c83670de0b6b3a764000084613a80565b9392505050565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526001600160a01b038416602482015282604482015260008060648360008a5af1915050612cf681613a9f565b612d425760405162461bcd60e51b815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000604482015260640161070f565b5050505050565b6001600160a01b038216600090815260056020908152604091829020825160808101845281546001600160f81b038082168352600160f81b90910460ff16151593820184905260018301549482019490945260029091015490921660608301528215151415612de4576040517fe2be007400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115801560208301528290612e01575080516001600160f81b0316155b15612e835760038054600090612e1f906001600160f81b03166144c1565b82546001600160f81b039182166101009390930a8381029202191617909155808252600090815260046020526040902080546001600160a01b0385167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790555b826001600160a01b0316636fd5ae156040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ee591906143bb565b6001600160f81b03908116606083019081526001600160a01b03851660008181526005602090815260408083208751928801511515600160f81b029287169283178155818801516001820155945160029095018054959096167fff000000000000000000000000000000000000000000000000000000000000009590951694909417909455915185151593927f0a8660585b632de44cbf81e54e8c01c5bbd8737072677676865a86948c57975991a4505050565b6000806000846001600160a01b03166364c56e3c6040518163ffffffff1660e01b81526004016040805180830381865afa158015612fdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fff91906144e8565b909250905061300e82426143d4565b841080613023575061302081426143d4565b84115b15613033576000925050506112aa565b60008060008061304288613ae6565b9550955095509550505082600014158061305b57508115155b8061306557508015155b1561307957600096505050505050506112aa565b6000896001600160a01b031663295a52126040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130dd91906143bb565b9050806130f657846001149750505050505050506112aa565b80600114156131195761310889613b5a565b6001149750505050505050506112aa565b5060009998505050505050505050565b6001600160a01b03808616600090815260066020908152604080832088845290915281205490911661316e57604051631760174360e01b815260040160405180910390fd5b6001600160a01b038616600090815260056020526040902054600160f81b900460ff161580156131c257506001600160a01b0386166000908152600660209081526040808320888452909152902060050154155b156131e05760405163fbf66df160e01b815260040160405180910390fd5b6001600160a01b0386811660008181526006602081815260408084208b8552825280842081516101208101835281548089168252600160a01b9081900465ffffffffffff16828601526001830154808a1683860152046bffffffffffffffffffffffff16606082015260028083015489166080830152600383015460a0830152600483015460c083015260058084015460e08401529290950154610100820152868652600784528286208d87528452828620978f1686529683528185205495855290915290912001546001600160f81b03811690600890811614613324576001600160a01b03891660009081526006602090815260408083208b845290915290206005015415613318576001600160a01b03891660009081526006602090815260408083208b84529091529020600401549150613324565b60009350505050613965565b6001600160a01b03891660009081526006602090815260408083208b8452909152902060050154156133615761335c8a8a8a8a613b8e565b6134be565b61336d612a30896143d4565b4211156133a6576040517f1c221a6900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000896001600160a01b031663f51e181a6040518163ffffffff1660e01b81526004016020604051808303816000875af11580156133e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061340c91906143bb565b90508361010001518111156134585761010084018190526001600160a01b03808b1660009081526007602090815260408083208d84528252808320938f168352929052208190556134bc565b836101000151600760008c6001600160a01b03166001600160a01b0316815260200190815260200160002060008b815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020819055505b505b60006134d884610100015189613e6090919063ffffffff16565b905060006134e68985612c77565b90508181116134f65760006134fa565b8181035b95506135408b8d888e6001600160a01b031663d4b839926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bc4573d6000803e3d6000fd5b604051635a424b9560e11b81526001600160a01b038d8116600483015260248201889052600060448301528c169063b484972a90606401600060405180830381600087803b15801561359157600080fd5b505af11580156135a5573d6000803e3d6000fd5b505050506001600160a01b038716156137cf5760408086015190516370a0823160e01b81526001600160a01b03898116600483015260009216906370a0823190602401602060405180830381865afa158015613605573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061362991906143bb565b90506000811161363e57856101000151613651565b6136518c8c838c8c8b6101000151613a13565b600760008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d815260200190815260200160002060008a6001600160a01b03166001600160a01b031681526020019081526020016000208190555060006136c88761010001518b612c7790919063ffffffff16565b90508c6001600160a01b031663b484972a8f8360006040518463ffffffff1660e01b8152600401613719939291906001600160a01b0393909316835260208301919091521515604082015260600190565b600060405180830381600087803b15801561373357600080fd5b505af1158015613747573d6000803e3d6000fd5b505050508c6001600160a01b031663b484972a8a8360016040518463ffffffff1660e01b815260040161379a939291906001600160a01b0393909316835260208301919091521515604082015260600190565b600060405180830381600087803b1580156137b457600080fd5b505af11580156137c8573d6000803e3d6000fd5b5050505050505b84600660008d6001600160a01b03166001600160a01b0316815260200190815260200160002060008c815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548165ffffffffffff021916908365ffffffffffff16021790555060408201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160010160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060808201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a0820151816003015560c0820151816004015560e082015181600501556101008201518160060155905050898b6001600160a01b03167f8f0c3d4726e2d22ccf850efced91f2d0c1bea40229449223d795a6cff32762368860405161395791815260200190565b60405180910390a350505050505b9695505050505050565b600080612a3061397f81856143d4565b61398991906143d4565b6001600160a01b038581166000908152600660209081526040808320888452909152902060020154919250163314156139df57426139c9612a30856142c1565b111580156139d75750428110155b9150506112aa565b426139ec612a30856143d4565b1080156139d7575042111590506112aa565b6000612c8c8383670de0b6b3a7640000613a80565b6000613a75613a228584612c77565b6001600160a01b03808a1660009081526007602090815260408083208c8452825280832093891683529290522054613a5b908890612c77565b613a6591906143d4565b613a6f86886143d4565b90612c77565b979650505050505050565b828202811515841585830485141716613a9857600080fd5b0492915050565b60003d82613ab157806000803e806000fd5b8060208114613ac9578015613ada5760009250613adf565b816000803e60005115159250613adf565b600192505b5050919050565b60008080808080613b02613afd620151808961430d565b613e75565b919750955093506000613b18620151808961450c565b9050613b26610e108261430d565b9350613b34610e108261450c565b9050613b41603c8261430d565b9250613b4e603c8261450c565b91505091939550919395565b600080613b6a620151808461430d565b90506007613b798260036143d4565b613b83919061450c565b612c8c9060016143d4565b6001600160a01b03838116600090815260066020908152604080832086845290915290819020600101549051632770a7eb60e21b8152868316600482015260248101849052911690639dc29fac90604401600060405180830381600087803b158015613bf957600080fd5b505af1158015613c0d573d6000803e3d6000fd5b505050506001600160a01b03831660009081526006602090815260408083208584529091528120600101548190613c6190600160a01b90046bffffffffffffffffffffffff16670de0b6b3a76400006142c1565b6001600160a01b0386166000908152600660208181526040808420898552909152909120908101546005909101549192508291613c9d91612c77565b10613d5e576001600160a01b0385166000908152600660209081526040808320878452909152902060050154613cd382856142d8565b613cdd919061430d565b6001600160a01b03861660009081526006602081815260408084208985529091529091200154613d0e908590612c77565b613d1891906142c1565b9150613d5e858784886001600160a01b031663d4b839926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bc4573d6000803e3d6000fd5b6001600160a01b0385166000818152600660208181526040808420898552909152909120015463b484972a908890613d97908790613e60565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260006044820152606401600060405180830381600087803b158015613dfc57600080fd5b505af1158015613e10573d6000803e3d6000fd5b5050505083856001600160a01b03167f8faabbddb6c4302d219d23d550839874e08536d5b8d2522f3ffa1e2ca054896e84604051613e5091815260200190565b60405180910390a3505050505050565b6000612c8c83670de0b6b3a764000084613fe9565b60008080838162253d8c613e8c8362010bd9614520565b613e969190614520565b9050600062023ab1613ea9836004614578565b613eb39190614618565b90506004613ec48262023ab1614578565b613ecf906003614520565b613ed99190614618565b613ee39083614646565b9150600062164b09613ef6846001614520565b613f0290610fa0614578565b613f0c9190614618565b90506004613f1c826105b5614578565b613f269190614618565b613f309084614646565b613f3b90601f614520565b9250600061098f613f4d856050614578565b613f579190614618565b905060006050613f698361098f614578565b613f739190614618565b613f7d9086614646565b9050613f8a600b83614618565b9450613f9785600c614578565b613fa2836002614520565b613fac9190614646565b91508483613fbb603187614646565b613fc6906064614578565b613fd09190614520565b613fda9190614520565b9a919950975095505050505050565b82820281151584158583048514171661400157600080fd5b6001826001830304018115150290509392505050565b6001600160a01b03811681146107ce57600080fd5b6000806040838503121561403f57600080fd5b823561404a81614017565b946020939093013593505050565b60006020828403121561406a57600080fd5b8135612c8c81614017565b8035801515811461408557600080fd5b919050565b6000806040838503121561409d57600080fd5b82356140a881614017565b91506140b660208401614075565b90509250929050565b6000602082840312156140d157600080fd5b612c8c82614075565b6000806000606084860312156140ef57600080fd5b83356140fa81614017565b95602085013595506040909401359392505050565b60008060006060848603121561412457600080fd5b833561412f81614017565b925060208401359150604084013561414681614017565b809150509250925092565b60006020828403121561416357600080fd5b5035919050565b600080600080600060a0868803121561418257600080fd5b853561418d81614017565b9450602086013561419d81614017565b9350604086013592506060860135915060808601356141bb81614017565b809150509295509295909350565b60008083601f8401126141db57600080fd5b50813567ffffffffffffffff8111156141f357600080fd5b6020830191508360208260051b850101111561420e57600080fd5b9250929050565b600080600080600080600060a0888a03121561423057600080fd5b873561423b81614017565b96506020880135955060408801359450606088013567ffffffffffffffff8082111561426657600080fd5b6142728b838c016141c9565b909650945060808a013591508082111561428b57600080fd5b506142988a828b016141c9565b989b979a50959850939692959293505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156142d3576142d36142ab565b500390565b60008160001904831182151516156142f2576142f26142ab565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261431c5761431c6142f7565b500490565b60006020828403121561433357600080fd5b8151612c8c81614017565b60008060006060848603121561435357600080fd5b835161435e81614017565b602085015190935061436f81614017565b80925050604084015190509250925092565b6000806040838503121561439457600080fd5b825161439f81614017565b60208401519092506143b081614017565b809150509250929050565b6000602082840312156143cd57600080fd5b5051919050565b600082198211156143e7576143e76142ab565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415614416576144166142ab565b5060010190565b85815260606020808301829052908201859052600090869060808401835b8881101561446957833561444e81614017565b6001600160a01b03168252928201929082019060010161443b565b5084810360408601528581527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8611156144a257600080fd5b8560051b92508287838301376000920101908152979650505050505050565b60006001600160f81b03808316818114156144de576144de6142ab565b6001019392505050565b600080604083850312156144fb57600080fd5b505080516020909101519092909150565b60008261451b5761451b6142f7565b500690565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561455a5761455a6142ab565b82600160ff1b038412811615614572576145726142ab565b50500190565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156145b9576145b96142ab565b600160ff1b60008712868205881281841616156145d8576145d86142ab565b600087129250878205871284841616156145f4576145f46142ab565b8785058712818416161561460a5761460a6142ab565b505050929093029392505050565b600082614627576146276142f7565b600160ff1b821460001984141615614641576146416142ab565b500590565b600080831283600160ff1b01831281151615614664576146646142ab565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018313811615614698576146986142ab565b5050039056fea26469706673582212201608dc09d634f2a3435bbf512920073c47d3124354b7178fdd56cf0c0d86b1a264736f6c634300080b00330000000000000000000000006c4f62b3187bc7e8a8f948bb50abec694719d8d30000000000000000000000004933494b4070c01bffbd3c53c1e44a3d9d95dd8e
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061020b5760003560e01c806372f7a0301161012a578063a4141638116100bd578063c9eb4f981161008c578063d10eb4b911610071578063d10eb4b914610671578063dfe5ef48146106a7578063f2d63d0e146106ba57600080fd5b8063c9eb4f981461064b578063d10c16a91461065e57600080fd5b8063a4141638146105e7578063aeb22934146105fa578063ba89bebd1461060d578063c5a067e31461062057600080fd5b806395197d30116100f957806395197d301461056457806396d648791461059d578063a1256f9f146105c0578063a131ad74146105d457600080fd5b806372f7a030146104fc57806375708a591461051057806377aace1a146105235780637c9170381461053b57600080fd5b8063332f6465116101a2578063574e779511610171578063574e7795146104ac5780635c975abb146104bf5780635fa0cc0a146104d657806360d54d41146104e957600080fd5b8063332f64651461043f5780633ad10beb146104525780633deb6cae1461037d5780633e3972ee1461047957600080fd5b806316c38b3c116101de57806316c38b3c146103a95780631b3d6e87146103bc5780632b83cccd146103fb5780632f9cd8541461040e57600080fd5b80630891d30a146102105780630cbe8db1146103085780630fe0554d1461037d5780631393916a14610394575b600080fd5b61029461021e36600461402c565b6006602081815260009384526040808520909152918352912080546001820154600283015460038401546004850154600586015495909601546001600160a01b0380861697600160a01b9687900465ffffffffffff1697828716979096046bffffffffffffffffffffffff169591909416939189565b604080516001600160a01b039a8b16815265ffffffffffff90991660208a0152968916968801969096526bffffffffffffffffffffffff909416606087015295909116608085015260a084015260c083019390935260e0820192909252610100810191909152610120015b60405180910390f35b61034e610316366004614058565b6005602052600090815260409020805460018201546002909201546001600160f81b0380831693600160f81b90930460ff1692911684565b604080516001600160f81b039586168152931515602085015283019190915290911660608201526080016102ff565b610386612a3081565b6040519081526020016102ff565b6103a76103a236600461408a565b6106c8565b005b6103a76103b73660046140bf565b610776565b6103e37f0000000000000000000000004933494b4070c01bffbd3c53c1e44a3d9d95dd8e81565b6040516001600160a01b0390911681526020016102ff565b6103866104093660046140da565b6107d9565b61038661041c36600461410f565b600760209081526000938452604080852082529284528284209052825290205481565b6103a761044d36600461408a565b610c4a565b6103e37f0000000000000000000000006c4f62b3187bc7e8a8f948bb50abec694719d8d381565b61048c61048736600461410f565b610ca3565b604080516001600160a01b039384168152929091166020830152016102ff565b6103e36104ba36600461402c565b611280565b60025460ff165b60405190151581526020016102ff565b6103a76104e436600461402c565b6112b0565b6103a76104f7366004614058565b61134b565b6002546104c690600160b01b900460ff1681565b6103a761051e3660046140bf565b61146b565b6002546103e39061010090046001600160a01b031681565b6103e3610549366004614151565b6004602052600090815260409020546001600160a01b031681565b61038661057236600461402c565b6001600160a01b03919091166000908152600660209081526040808320938352929052206005015490565b6104c66105ab366004614058565b60006020819052908152604090205460ff1681565b6002546104c690600160a81b900460ff1681565b6103866105e236600461416a565b61151a565b6103a76105f536600461402c565b6116a8565b6103a7610608366004614058565b611a07565b61038661061b3660046140da565b611abb565b600354610633906001600160f81b031681565b6040516001600160f81b0390911681526020016102ff565b6103a76106593660046140bf565b611f0b565b6103a761066c366004614215565b611fba565b6103e361067f36600461402c565b6001600160a01b03918216600090815260066020908152604080832093835292905220541690565b6103866106b53660046140da565b6123cd565b61038666b1a2bc2ec5000081565b3360009081526020819052604090205460ff166107185760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b60448201526064015b60405180910390fd5b6001600160a01b03821660008181526020818152604091829020805460ff191685151590811790915591519182527fe95aec380cae16330d146d5499ef7db6f3657e477104a733e771bc09e500d98691015b60405180910390a25050565b3360009081526020819052604090205460ff166107c15760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b806107d1576107ce612b60565b50565b6107ce612bfc565b600060015460011461081a5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b600260015561082b60025460ff1690565b1561086b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6001600160a01b03841660009081526006602090815260408083208684529091529020600501546108c8576040517fba329a9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0384166000908152600560205260409020600201546001600160f81b03166108fb816010908116141590565b801561090f5750336001600160a01b038616145b15610946576040517f9ad6d35d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03858116600090815260066020908152604080832088845290915290819020549051632770a7eb60e21b815233600482015260248101869052911690639dc29fac90604401600060405180830381600087803b1580156109ac57600080fd5b505af11580156109c0573d6000803e3d6000fd5b505050506001600160a01b0385166000908152600660209081526040808320878452909152812060010154610a1290600160a01b90046bffffffffffffffffffffffff16670de0b6b3a76400006142c1565b6001600160a01b03871660009081526006602081815260408084208a8552909152909120908101546005909101549192508291610a4e91612c77565b10610a95576001600160a01b0386166000908152600660209081526040808320888452909152902060050154610a8482866142d8565b610a8e919061430d565b9250610ac9565b6001600160a01b03861660009081526006602081815260408084208985529091529091200154610ac6908590612c77565b92505b60208083161415610b80576001600160a01b03861660008181526006602081815260408084208a855290915291829020600581015491015491517f14282f580000000000000000000000000000000000000000000000000000000081526004810188905260248101919091526044810191909152606481018590526314282f5890608401600060405180830381600087803b158015610b6757600080fd5b505af1158015610b7b573d6000803e3d6000fd5b505050505b610bf9863385896001600160a01b031663d4b839926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be89190614321565b6001600160a01b0316929190612c93565b84866001600160a01b03167f2d0320e3c19b591925fca7a3012a905faf26dead7f53eb9c4c72744f04bde98085604051610c3591815260200190565b60405180910390a35050600180559392505050565b3360009081526020819052604090205460ff16610c955760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b610c9f8282612d49565b5050565b600080600154600114610ce55760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b6002600155610cf660025460ff1690565b15610d365760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b60025461010090046001600160a01b03163314610d7f576040517ffb02114900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516600090815260056020526040902054600160f81b900460ff16610dbf5760405163fbf66df160e01b815260040160405180910390fd5b6001600160a01b0380861660009081526006602090815260408083208884529091529020541615610e1c576040517fd309d88400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e268585612f99565b610e5c576040517fc7a682c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000876001600160a01b03166327b327d06040518163ffffffff1660e01b8152600401606060405180830381865afa158015610e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec3919061433e565b6001600160a01b038b8116600081815260056020526040908190205490517fafd3adb000000000000000000000000000000000000000000000000000000000815260048101929092526001600160f81b03166024820152604481018c905293965091945092507f0000000000000000000000004933494b4070c01bffbd3c53c1e44a3d9d95dd8e169063afd3adb09060640160408051808303816000875af1158015610f73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f979190614381565b80955081965050506000886001600160a01b031663f51e181a6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610fe1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100591906143bb565b905085600660008b6001600160a01b03166001600160a01b0316815260200190815260200160002060008a815260200190815260200160002060000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555042600660008b6001600160a01b03166001600160a01b0316815260200190815260200160002060008a815260200190815260200160002060000160146101000a81548165ffffffffffff021916908365ffffffffffff16021790555084600660008b6001600160a01b03166001600160a01b0316815260200190815260200160002060008a815260200190815260200160002060010160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550886001600160a01b031663c39a3b296040518163ffffffff1660e01b8152600401602060405180830381865afa15801561115d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118191906143bb565b6001600160a01b038a811660009081526006602081815260408084208e85529091529091206001810180548416600160a01b6bffffffffffffffffffffffff9690961695909502949094179093556002830180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168b84161790556004830184905591909101829055611219908416338b85612c93565b604080516001600160a01b038b811682528881166020830152878116828401529151868316928a16918b917f1f35e8bec0a1a6f4c72b2ae05a4b8fdc78d03eab2dc742fab6ae238201c8189b9181900360600190a450506001805550919590945092505050565b6001600160a01b038083166000908152600660209081526040808320858452909152902060010154165b92915050565b3360009081526020819052604090205460ff166112fb5760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b6001600160a01b03821660008181526005602052604090819020600101839055517ff16a3457e9b9a5c31fda410fd95ed37234eafeb546daeb8a99f8895f94bf8fee9061076a9084815260200190565b60025460ff16156113915760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b600254600160a81b900460ff161580156113bb575060025461010090046001600160a01b03163314155b156113f2576040517f8719352c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381166000908152600560205260409020546001600160f81b03161580159061144257506001600160a01b038116600090815260056020526040902054600160f81b900460ff16155b156114605760405163fbf66df160e01b815260040160405180910390fd5b6107ce816001612d49565b3360009081526020819052604090205460ff166114b65760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b600280547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b831515908102919091179091556040517f44a4c963afeb7bcec3494bbd13068371938a27639a9a9a7bac56c11777fd410990600090a250565b600060015460011461155b5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b600260019081556001600160a01b038087166000908152600660209081526040808320898452909152902090910154869186911633146115c7576040517fb114ba9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460ff161561160d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6040516370a0823160e01b81526001600160a01b038916600482015260009033906370a0823190602401602060405180830381865afa158015611654573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167891906143bb565b90506116978989898460008b1161168f5785611691565b8a5b8a613129565b600180559998505050505050505050565b6001546001146116e75760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b60026001556116f860025460ff1690565b156117385760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6001600160a01b038216600090815260056020526040902054600160f81b900460ff166117785760405163fbf66df160e01b815260040160405180910390fd5b6001600160a01b038083166000908152600660209081526040808320858452909152902054166117bb57604051631760174360e01b815260040160405180910390fd5b6001600160a01b038216600090815260066020908152604080832084845290915290206005015415611819576040517f560ff90000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611823828261396f565b61184057604051634296f34160e11b815260040160405180910390fd5b6000826001600160a01b031663f51e181a6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a691906143bb565b6001600160a01b0384166000908152600660208181526040808420878552909152909120600581018390550154909150811115611906576001600160a01b0383166000908152600660208181526040808420868552909152909120018190555b6000806000856001600160a01b03166327b327d06040518163ffffffff1660e01b8152600401606060405180830381865afa158015611949573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196d919061433e565b6001600160a01b03808a1660009081526006602090815260408083208c845290915290206003015493965091945092506119ae919085169088903390612c93565b6119c36001600160a01b038316873384612c93565b604051339086906001600160a01b038916907fd1426f892f3cce4b1085d051aa4be26da2192d8db075f55bc75f185d38ea624b90600090a450506001805550505050565b3360009081526020819052604090205460ff16611a525760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b600280547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b038416908102919091179091556040517f1deeec14e500a86432231bf144d0a12a439494bd11662a44a7e49d868451e74b90600090a250565b6000600154600114611afc5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b6002600155611b0d60025460ff1690565b15611b4d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6001600160a01b038416600090815260056020526040902054600160f81b900460ff16611b8d5760405163fbf66df160e01b815260040160405180910390fd5b6001600160a01b03808516600090815260066020908152604080832087845290915290205416611bd057604051631760174360e01b815260040160405180910390fd5b6001600160a01b0384166000908152600560205260409020600201546001600160f81b0316611c03816004908116141590565b8015611c185750336001600160a01b03861614155b15611c4f576040517f66bed65200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03858116600090815260066020908152604080832088845290915290819020549051632770a7eb60e21b815233600482015260248101869052911690639dc29fac90604401600060405180830381600087803b158015611cb557600080fd5b505af1158015611cc9573d6000803e3d6000fd5b505050506000611cde33878787886000613129565b6001600160a01b038716600090815260066020908152604080832089845290915290206005015490915080151580611df8576001600160a01b0388811660009081526006602090815260408083208b845290915290819020600101549051632770a7eb60e21b815233600482015260248101899052911690639dc29fac90604401600060405180830381600087803b158015611d7957600080fd5b505af1158015611d8d573d6000803e3d6000fd5b5050505060088085161415611dcd576001600160a01b03881660009081526007602090815260408083208a84528252808320338452909152902054611df5565b6001600160a01b03881660009081526006602090815260408083208a84529091529020600401545b91505b611e028683612c77565b9450611e488833878b6001600160a01b031663d4b839926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bc4573d6000803e3d6000fd5b80611eb557604051635a424b9560e11b815233600482015260248101869052600060448201526001600160a01b0389169063b484972a90606401600060405180830381600087803b158015611e9c57600080fd5b505af1158015611eb0573d6000803e3d6000fd5b505050505b60405194830180865294339088906001600160a01b038b16907fc93ef223012fd8a42ae087bcd98f3ea6c91a3596f56fb683451dda1abc5b695c9060200160405180910390a45050600180555090949350505050565b3360009081526020819052604090205460ff16611f565760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b600280547fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff16600160b01b831515908102919091179091556040517fdbcdd9941cbf70eec96e3ddaf2d230966f8224f1b7ec8af263cb8ca4803dfe6f90600090a250565b3360009081526020819052604090205460ff166120055760405162461bcd60e51b8152602060048201526009602482015268155395149554d5115160ba1b604482015260640161070f565b6001600160a01b0380881660009081526006602090815260408083208a84529091529020541661204857604051631760174360e01b815260040160405180910390fd5b6000612a3061205781896143d4565b61206191906143d4565b905080421161208357604051634296f34160e11b815260040160405180910390fd5b60005b84811015612120578383828181106120a0576120a06143ec565b6001600160a01b038c1660009081526007602090815260408083208e84528252822092029390930135929091508888858181106120df576120df6143ec565b90506020020160208101906120f49190614058565b6001600160a01b031681526020810191909152604001600020558061211881614402565b915050612086565b508515612379576001600160a01b0388811660009081526006602081815260408084208c855280835281852082516101208101845281548089168252600160a01b9081900465ffffffffffff16828701526001830154808a16958301959095529093046bffffffffffffffffffffffff16606084015260028101549096166080830152600386015460a0830152600486015460c083015260058601805460e084015295909301546101008201908152938c9052919052918890555187111561220b576001600160a01b03891660009081526006602081815260408084208c8552909152909120018790555b60008060008b6001600160a01b03166327b327d06040518163ffffffff1660e01b8152600401606060405180830381865afa15801561224e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612272919061433e565b6001600160a01b038f16600090815260056020526040812054939650919450925090600160f81b900460ff166122ac5784608001516122ce565b7f0000000000000000000000006c4f62b3187bc7e8a8f948bb50abec694719d8d35b90506123148d7f0000000000000000000000006c4f62b3187bc7e8a8f948bb50abec694719d8d38760a00151876001600160a01b0316612c93909392919063ffffffff16565b6000600660008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008e8152602001908152602001600020600301819055506123738d8284866001600160a01b0316612c93909392919063ffffffff16565b50505050505b86886001600160a01b03167f9f7c9b961af682670e128c89a9a1d940800d7c3d7693ab5608f21dd2c04d740f88888888886040516123bb95949392919061441d565b60405180910390a35050505050505050565b600060015460011461240e5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161070f565b600260015561241f60025460ff1690565b1561245f5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6001600160a01b038416600090815260056020526040902054600160f81b900460ff1661249f5760405163fbf66df160e01b815260040160405180910390fd5b6001600160a01b038085166000908152600660209081526040808320878452909152902054166124e257604051631760174360e01b815260040160405180910390fd5b6001600160a01b038416600090815260066020908152604080832086845290915290206005015415612540576040517f0de7115500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0384166000908152600560205260409020600201546001600160f81b0316612573816002908116141590565b80156125885750336001600160a01b03861614155b156125bf576040517f8159f88400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000856001600160a01b031663d4b839926040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126239190614321565b90506000866001600160a01b031663b8c15a9f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612665573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268991906143bb565b905066b1a2bc2ec500008111156126cc576040517f2e68f33400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006126d886836139fe565b6001600160a01b03891660009081526006602090815260408083208b8452909152812060030180548301905590915061271182886142c1565b600254909150600160b01b900460ff1680156127af57506001600160a01b03898116600081815260056020526040908190206001015490516370a0823160e01b81526004810192909252918991908716906370a0823190602401602060405180830381865afa158015612788573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ac91906143bb565b01115b156127e6576040517f6493914000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051635a424b9560e11b815233600482015260248101829052600160448201526001600160a01b038a169063b484972a90606401600060405180830381600087803b15801561283557600080fd5b505af1158015612849573d6000803e3d6000fd5b50600092505050600880871614156128c457896001600160a01b031663f51e181a6040518163ffffffff1660e01b81526004016020604051808303816000875af115801561289b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128bf91906143bb565b6128ec565b6001600160a01b038a1660009081526006602090815260408083208c84529091529020600401545b90506128f882826139fe565b6001600160a01b038b1660009081526007602090815260408083208d84528252808320338452909152902054909750156129ca576001600160a01b038a811660009081526006602090815260408083208d8452909152908190206001015490516370a0823160e01b81523360048201526129c5928d928d929116906370a0823190602401602060405180830381865afa158015612999573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129bd91906143bb565b8a3386613a13565b6129cc565b805b6001600160a01b038b811660008181526007602090815260408083208f845282528083203380855290835281842096909655928252600681528282208e835290528190205490516340c10f1960e01b81526004810193909352602483018a905216906340c10f1990604401600060405180830381600087803b158015612a5157600080fd5b505af1158015612a65573d6000803e3d6000fd5b505050506001600160a01b038a811660009081526006602090815260408083208d8452909152908190206001015490516340c10f1960e01b8152336004820152602481018a90529116906340c10f1990604401600060405180830381600087803b158015612ad257600080fd5b505af1158015612ae6573d6000803e3d6000fd5b50612b00925050506001600160a01b038616338c8b612c93565b336001600160a01b0316898b6001600160a01b03167ff75041e6352580ba937fde3a7ff5ff99bd178f75ac104184f85e3abbaaa44fef8a604051612b4691815260200190565b60405180910390a450506001805550929695505050505050565b60025460ff16612bb25760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161070f565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60025460ff1615612c425760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161070f565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612bdf3390565b6000612c8c83670de0b6b3a764000084613a80565b9392505050565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526001600160a01b038416602482015282604482015260008060648360008a5af1915050612cf681613a9f565b612d425760405162461bcd60e51b815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000604482015260640161070f565b5050505050565b6001600160a01b038216600090815260056020908152604091829020825160808101845281546001600160f81b038082168352600160f81b90910460ff16151593820184905260018301549482019490945260029091015490921660608301528215151415612de4576040517fe2be007400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115801560208301528290612e01575080516001600160f81b0316155b15612e835760038054600090612e1f906001600160f81b03166144c1565b82546001600160f81b039182166101009390930a8381029202191617909155808252600090815260046020526040902080546001600160a01b0385167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790555b826001600160a01b0316636fd5ae156040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ee591906143bb565b6001600160f81b03908116606083019081526001600160a01b03851660008181526005602090815260408083208751928801511515600160f81b029287169283178155818801516001820155945160029095018054959096167fff000000000000000000000000000000000000000000000000000000000000009590951694909417909455915185151593927f0a8660585b632de44cbf81e54e8c01c5bbd8737072677676865a86948c57975991a4505050565b6000806000846001600160a01b03166364c56e3c6040518163ffffffff1660e01b81526004016040805180830381865afa158015612fdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fff91906144e8565b909250905061300e82426143d4565b841080613023575061302081426143d4565b84115b15613033576000925050506112aa565b60008060008061304288613ae6565b9550955095509550505082600014158061305b57508115155b8061306557508015155b1561307957600096505050505050506112aa565b6000896001600160a01b031663295a52126040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130dd91906143bb565b9050806130f657846001149750505050505050506112aa565b80600114156131195761310889613b5a565b6001149750505050505050506112aa565b5060009998505050505050505050565b6001600160a01b03808616600090815260066020908152604080832088845290915281205490911661316e57604051631760174360e01b815260040160405180910390fd5b6001600160a01b038616600090815260056020526040902054600160f81b900460ff161580156131c257506001600160a01b0386166000908152600660209081526040808320888452909152902060050154155b156131e05760405163fbf66df160e01b815260040160405180910390fd5b6001600160a01b0386811660008181526006602081815260408084208b8552825280842081516101208101835281548089168252600160a01b9081900465ffffffffffff16828601526001830154808a1683860152046bffffffffffffffffffffffff16606082015260028083015489166080830152600383015460a0830152600483015460c083015260058084015460e08401529290950154610100820152868652600784528286208d87528452828620978f1686529683528185205495855290915290912001546001600160f81b03811690600890811614613324576001600160a01b03891660009081526006602090815260408083208b845290915290206005015415613318576001600160a01b03891660009081526006602090815260408083208b84529091529020600401549150613324565b60009350505050613965565b6001600160a01b03891660009081526006602090815260408083208b8452909152902060050154156133615761335c8a8a8a8a613b8e565b6134be565b61336d612a30896143d4565b4211156133a6576040517f1c221a6900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000896001600160a01b031663f51e181a6040518163ffffffff1660e01b81526004016020604051808303816000875af11580156133e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061340c91906143bb565b90508361010001518111156134585761010084018190526001600160a01b03808b1660009081526007602090815260408083208d84528252808320938f168352929052208190556134bc565b836101000151600760008c6001600160a01b03166001600160a01b0316815260200190815260200160002060008b815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020819055505b505b60006134d884610100015189613e6090919063ffffffff16565b905060006134e68985612c77565b90508181116134f65760006134fa565b8181035b95506135408b8d888e6001600160a01b031663d4b839926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bc4573d6000803e3d6000fd5b604051635a424b9560e11b81526001600160a01b038d8116600483015260248201889052600060448301528c169063b484972a90606401600060405180830381600087803b15801561359157600080fd5b505af11580156135a5573d6000803e3d6000fd5b505050506001600160a01b038716156137cf5760408086015190516370a0823160e01b81526001600160a01b03898116600483015260009216906370a0823190602401602060405180830381865afa158015613605573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061362991906143bb565b90506000811161363e57856101000151613651565b6136518c8c838c8c8b6101000151613a13565b600760008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008d815260200190815260200160002060008a6001600160a01b03166001600160a01b031681526020019081526020016000208190555060006136c88761010001518b612c7790919063ffffffff16565b90508c6001600160a01b031663b484972a8f8360006040518463ffffffff1660e01b8152600401613719939291906001600160a01b0393909316835260208301919091521515604082015260600190565b600060405180830381600087803b15801561373357600080fd5b505af1158015613747573d6000803e3d6000fd5b505050508c6001600160a01b031663b484972a8a8360016040518463ffffffff1660e01b815260040161379a939291906001600160a01b0393909316835260208301919091521515604082015260600190565b600060405180830381600087803b1580156137b457600080fd5b505af11580156137c8573d6000803e3d6000fd5b5050505050505b84600660008d6001600160a01b03166001600160a01b0316815260200190815260200160002060008c815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548165ffffffffffff021916908365ffffffffffff16021790555060408201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160010160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060808201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a0820151816003015560c0820151816004015560e082015181600501556101008201518160060155905050898b6001600160a01b03167f8f0c3d4726e2d22ccf850efced91f2d0c1bea40229449223d795a6cff32762368860405161395791815260200190565b60405180910390a350505050505b9695505050505050565b600080612a3061397f81856143d4565b61398991906143d4565b6001600160a01b038581166000908152600660209081526040808320888452909152902060020154919250163314156139df57426139c9612a30856142c1565b111580156139d75750428110155b9150506112aa565b426139ec612a30856143d4565b1080156139d7575042111590506112aa565b6000612c8c8383670de0b6b3a7640000613a80565b6000613a75613a228584612c77565b6001600160a01b03808a1660009081526007602090815260408083208c8452825280832093891683529290522054613a5b908890612c77565b613a6591906143d4565b613a6f86886143d4565b90612c77565b979650505050505050565b828202811515841585830485141716613a9857600080fd5b0492915050565b60003d82613ab157806000803e806000fd5b8060208114613ac9578015613ada5760009250613adf565b816000803e60005115159250613adf565b600192505b5050919050565b60008080808080613b02613afd620151808961430d565b613e75565b919750955093506000613b18620151808961450c565b9050613b26610e108261430d565b9350613b34610e108261450c565b9050613b41603c8261430d565b9250613b4e603c8261450c565b91505091939550919395565b600080613b6a620151808461430d565b90506007613b798260036143d4565b613b83919061450c565b612c8c9060016143d4565b6001600160a01b03838116600090815260066020908152604080832086845290915290819020600101549051632770a7eb60e21b8152868316600482015260248101849052911690639dc29fac90604401600060405180830381600087803b158015613bf957600080fd5b505af1158015613c0d573d6000803e3d6000fd5b505050506001600160a01b03831660009081526006602090815260408083208584529091528120600101548190613c6190600160a01b90046bffffffffffffffffffffffff16670de0b6b3a76400006142c1565b6001600160a01b0386166000908152600660208181526040808420898552909152909120908101546005909101549192508291613c9d91612c77565b10613d5e576001600160a01b0385166000908152600660209081526040808320878452909152902060050154613cd382856142d8565b613cdd919061430d565b6001600160a01b03861660009081526006602081815260408084208985529091529091200154613d0e908590612c77565b613d1891906142c1565b9150613d5e858784886001600160a01b031663d4b839926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bc4573d6000803e3d6000fd5b6001600160a01b0385166000818152600660208181526040808420898552909152909120015463b484972a908890613d97908790613e60565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260006044820152606401600060405180830381600087803b158015613dfc57600080fd5b505af1158015613e10573d6000803e3d6000fd5b5050505083856001600160a01b03167f8faabbddb6c4302d219d23d550839874e08536d5b8d2522f3ffa1e2ca054896e84604051613e5091815260200190565b60405180910390a3505050505050565b6000612c8c83670de0b6b3a764000084613fe9565b60008080838162253d8c613e8c8362010bd9614520565b613e969190614520565b9050600062023ab1613ea9836004614578565b613eb39190614618565b90506004613ec48262023ab1614578565b613ecf906003614520565b613ed99190614618565b613ee39083614646565b9150600062164b09613ef6846001614520565b613f0290610fa0614578565b613f0c9190614618565b90506004613f1c826105b5614578565b613f269190614618565b613f309084614646565b613f3b90601f614520565b9250600061098f613f4d856050614578565b613f579190614618565b905060006050613f698361098f614578565b613f739190614618565b613f7d9086614646565b9050613f8a600b83614618565b9450613f9785600c614578565b613fa2836002614520565b613fac9190614646565b91508483613fbb603187614646565b613fc6906064614578565b613fd09190614520565b613fda9190614520565b9a919950975095505050505050565b82820281151584158583048514171661400157600080fd5b6001826001830304018115150290509392505050565b6001600160a01b03811681146107ce57600080fd5b6000806040838503121561403f57600080fd5b823561404a81614017565b946020939093013593505050565b60006020828403121561406a57600080fd5b8135612c8c81614017565b8035801515811461408557600080fd5b919050565b6000806040838503121561409d57600080fd5b82356140a881614017565b91506140b660208401614075565b90509250929050565b6000602082840312156140d157600080fd5b612c8c82614075565b6000806000606084860312156140ef57600080fd5b83356140fa81614017565b95602085013595506040909401359392505050565b60008060006060848603121561412457600080fd5b833561412f81614017565b925060208401359150604084013561414681614017565b809150509250925092565b60006020828403121561416357600080fd5b5035919050565b600080600080600060a0868803121561418257600080fd5b853561418d81614017565b9450602086013561419d81614017565b9350604086013592506060860135915060808601356141bb81614017565b809150509295509295909350565b60008083601f8401126141db57600080fd5b50813567ffffffffffffffff8111156141f357600080fd5b6020830191508360208260051b850101111561420e57600080fd5b9250929050565b600080600080600080600060a0888a03121561423057600080fd5b873561423b81614017565b96506020880135955060408801359450606088013567ffffffffffffffff8082111561426657600080fd5b6142728b838c016141c9565b909650945060808a013591508082111561428b57600080fd5b506142988a828b016141c9565b989b979a50959850939692959293505050565b634e487b7160e01b600052601160045260246000fd5b6000828210156142d3576142d36142ab565b500390565b60008160001904831182151516156142f2576142f26142ab565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261431c5761431c6142f7565b500490565b60006020828403121561433357600080fd5b8151612c8c81614017565b60008060006060848603121561435357600080fd5b835161435e81614017565b602085015190935061436f81614017565b80925050604084015190509250925092565b6000806040838503121561439457600080fd5b825161439f81614017565b60208401519092506143b081614017565b809150509250929050565b6000602082840312156143cd57600080fd5b5051919050565b600082198211156143e7576143e76142ab565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415614416576144166142ab565b5060010190565b85815260606020808301829052908201859052600090869060808401835b8881101561446957833561444e81614017565b6001600160a01b03168252928201929082019060010161443b565b5084810360408601528581527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8611156144a257600080fd5b8560051b92508287838301376000920101908152979650505050505050565b60006001600160f81b03808316818114156144de576144de6142ab565b6001019392505050565b600080604083850312156144fb57600080fd5b505080516020909101519092909150565b60008261451b5761451b6142f7565b500690565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561455a5761455a6142ab565b82600160ff1b038412811615614572576145726142ab565b50500190565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156145b9576145b96142ab565b600160ff1b60008712868205881281841616156145d8576145d86142ab565b600087129250878205871284841616156145f4576145f46142ab565b8785058712818416161561460a5761460a6142ab565b505050929093029392505050565b600082614627576146276142f7565b600160ff1b821460001984141615614641576146416142ab565b500590565b600080831283600160ff1b01831281151615614664576146646142ab565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018313811615614698576146986142ab565b5050039056fea26469706673582212201608dc09d634f2a3435bbf512920073c47d3124354b7178fdd56cf0c0d86b1a264736f6c634300080b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006c4f62b3187bc7e8a8f948bb50abec694719d8d30000000000000000000000004933494b4070c01bffbd3c53c1e44a3d9d95dd8e
-----Decoded View---------------
Arg [0] : _cup (address): 0x6C4f62b3187bC7e8A8f948Bb50ABec694719D8d3
Arg [1] : _tokenHandler (address): 0x4933494b4070c01bfFBd3c53C1E44A3d9d95DD8e
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000006c4f62b3187bc7e8a8f948bb50abec694719d8d3
Arg [1] : 0000000000000000000000004933494b4070c01bffbd3c53c1e44a3d9d95dd8e
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.