More Info
Private Name Tags
ContractCreator:
Sponsored
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x6102e060 | 30486593 | 777 days ago | IN | Create: YearnTempusPool | 0 FTM | 1.10479586 |
Latest 3 internal transactions
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
30486593 | 777 days ago | Contract Creation | 0 FTM | |||
30486593 | 777 days ago | Contract Creation | 0 FTM | |||
30486593 | 777 days ago | Contract Creation | 0 FTM |
Loading...
Loading
Contract Name:
YearnTempusPool
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 100000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "../TempusPool.sol"; import "../protocols/yearn/IYearnVaultV2.sol"; import "../utils/UntrustedERC20.sol"; import "../math/Fixed256xVar.sol"; contract YearnTempusPool is TempusPool { using SafeERC20 for IERC20; using UntrustedERC20 for IERC20; using Fixed256xVar for uint256; IYearnVaultV2 private immutable yearnVault; bytes32 public constant override protocolName = "Yearn"; constructor( IYearnVaultV2 vault, address controller, uint256 maturity, uint256 estYield, TokenData memory principalsData, TokenData memory yieldsData, FeesConfig memory maxFeeSetup ) TempusPool( address(vault), vault.token(), controller, maturity, vault.pricePerShare(), 10**(IERC20Metadata(vault.token()).decimals()), estYield, principalsData, yieldsData, maxFeeSetup ) { require(vault.decimals() == IERC20Metadata(vault.token()).decimals(), "Decimals precision mismatch"); yearnVault = vault; } function depositToUnderlying(uint256 amountBT) internal override assertTransferBT(amountBT) returns (uint256 mintedYBT) { // ETH deposits are not accepted, because it is rejected in the controller assert(msg.value == 0); uint256 ybtBefore = balanceOfYBT(); // Deposit to Yearn Vault IERC20(backingToken).safeIncreaseAllowance(address(yearnVault), amountBT); yearnVault.deposit(amountBT); mintedYBT = balanceOfYBT() - ybtBefore; } function withdrawFromUnderlyingProtocol(uint256 yieldBearingTokensAmount, address recipient) internal override assertTransferYBT(yieldBearingTokensAmount, 1) returns (uint256 backingTokenAmount) { return yearnVault.withdraw(yieldBearingTokensAmount, recipient); } /// @return Updated current Interest Rate with the same precision as the BackingToken function updateInterestRate() public view override returns (uint256) { return yearnVault.pricePerShare(); } /// @return Stored Interest Rate with the same precision as the BackingToken function currentInterestRate() public view override returns (uint256) { return yearnVault.pricePerShare(); } function numAssetsPerYieldToken(uint256 yieldTokens, uint256 rate) public view override returns (uint256) { return yieldTokens.mulfV(rate, exchangeRateONE); } function numYieldTokensPerAsset(uint256 backingTokens, uint256 rate) public view override returns (uint256) { return backingTokens.divfV(rate, exchangeRateONE); } /// @dev The rate precision always matches the BackingToken's precision function interestRateToSharePrice(uint256 interestRate) internal pure override returns (uint256) { return interestRate; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "./ITempusPool.sol"; import "./token/PrincipalShare.sol"; import "./token/YieldShare.sol"; import "./math/Fixed256xVar.sol"; import "./utils/Ownable.sol"; import "./utils/UntrustedERC20.sol"; import "./utils/Versioned.sol"; /// @dev helper struct to store name and symbol for the token struct TokenData { string name; string symbol; } /// @author The tempus.finance team /// @title Implementation of Tempus Pool abstract contract TempusPool is ITempusPool, ReentrancyGuard, Ownable, Versioned { using SafeERC20 for IERC20; using UntrustedERC20 for IERC20; using Fixed256xVar for uint256; uint256 public constant override maximumNegativeYieldDuration = 7 days; address public immutable override yieldBearingToken; address public immutable override backingToken; uint256 public immutable override startTime; uint256 public immutable override maturityTime; uint256 public override exceptionalHaltTime = type(uint256).max; uint256 public immutable override initialInterestRate; uint256 public override maturityInterestRate; uint256 public immutable exchangeRateONE; uint256 public immutable yieldBearingONE; uint256 public immutable override backingTokenONE; IPoolShare public immutable override principalShare; IPoolShare public immutable override yieldShare; address public immutable override controller; uint256 private immutable initialEstimatedYield; FeesConfig private feesConfig; uint256 public immutable override maxDepositFee; uint256 public immutable override maxEarlyRedeemFee; uint256 public immutable override maxMatureRedeemFee; uint256 public override totalFees; /// Timestamp when the negative yield period was entered. uint256 private negativeYieldStartTime; /// Constructs Pool with underlying token, start and maturity date /// @param _yieldBearingToken Yield Bearing Token, such as cDAI or aUSDC /// @param _backingToken backing token (or zero address if ETH) /// @param ctrl The authorized TempusController of the pool /// @param maturity maturity time of this pool /// @param initInterestRate initial interest rate of the pool /// @param exchangeRateOne 1.0 expressed in exchange rate decimal precision /// @param estimatedFinalYield estimated yield for the whole lifetime of the pool /// @param principalsData Tempus Principals name and symbol /// @param yieldsData Tempus Yields name and symbol /// @param maxFeeSetup Maximum fee percentages that this pool can have, /// values in Yield Bearing Token precision constructor( address _yieldBearingToken, address _backingToken, address ctrl, uint256 maturity, uint256 initInterestRate, uint256 exchangeRateOne, uint256 estimatedFinalYield, TokenData memory principalsData, TokenData memory yieldsData, FeesConfig memory maxFeeSetup ) Versioned(1, 0, 0) { require(maturity > block.timestamp, "maturityTime is after startTime"); require(ctrl != address(0), "controller can not be zero"); require(initInterestRate > 0, "initInterestRate can not be zero"); require(estimatedFinalYield > 0, "estimatedFinalYield can not be zero"); require(_yieldBearingToken != address(0), "YBT can not be zero"); yieldBearingToken = _yieldBearingToken; backingToken = _backingToken; controller = ctrl; startTime = block.timestamp; maturityTime = maturity; initialInterestRate = initInterestRate; exchangeRateONE = exchangeRateOne; yieldBearingONE = 10**ERC20(_yieldBearingToken).decimals(); initialEstimatedYield = estimatedFinalYield; maxDepositFee = maxFeeSetup.depositPercent; maxEarlyRedeemFee = maxFeeSetup.earlyRedeemPercent; maxMatureRedeemFee = maxFeeSetup.matureRedeemPercent; uint8 backingDecimals = _backingToken != address(0) ? IERC20Metadata(_backingToken).decimals() : 18; backingTokenONE = 10**backingDecimals; principalShare = new PrincipalShare(this, principalsData.name, principalsData.symbol, backingDecimals); yieldShare = new YieldShare(this, yieldsData.name, yieldsData.symbol, backingDecimals); } modifier onlyController() { require(msg.sender == controller, "Only callable by TempusController"); _; } /// @dev Deposits backing tokens into the underlying protocol /// @param amountBT Amount of BackingTokens to deposit /// @return mintedYBT Amount of minted Yield Bearing Tokens function depositToUnderlying(uint256 amountBT) internal virtual returns (uint256 mintedYBT); /// @dev Utility for checking YBT balance of this contract function balanceOfYBT() internal view returns (uint256) { return IERC20(yieldBearingToken).balanceOf(address(this)); } /// @dev Utility for checking BT balance of this contract function balanceOfBT() internal view returns (uint256) { return IERC20(backingToken).balanceOf(address(this)); } /// @dev Asserts all of the Backing Tokens are transferred during this operation modifier assertTransferBT(uint256 amountBT) { uint256 btBefore = balanceOfBT(); _; uint256 remainingBT = amountBT - (btBefore - balanceOfBT()); assert(remainingBT == 0); } /// @dev Asserts all of the Yield Bearing Tokens are transferred during this operation (allowing some room for rounding errors) modifier assertTransferYBT(uint256 amountYBT, uint256 errorThreshold) { uint256 ybtBefore = balanceOfYBT(); _; uint256 transferredAmount = (ybtBefore - balanceOfYBT()); uint256 untransferredAmount = (transferredAmount > amountYBT) ? (transferredAmount - amountYBT) : (amountYBT - transferredAmount); assert(untransferredAmount <= errorThreshold); } function withdrawFromUnderlyingProtocol(uint256 amount, address recipient) internal virtual returns (uint256 backingTokenAmount); function matured() public view override returns (bool) { return (block.timestamp >= maturityTime) || (block.timestamp >= exceptionalHaltTime); } function getFeesConfig() external view override returns (FeesConfig memory) { return feesConfig; } function setFeesConfig(FeesConfig calldata newFeesConfig) external override onlyOwner { require(newFeesConfig.depositPercent <= maxDepositFee, "Deposit fee percent > max"); require(newFeesConfig.earlyRedeemPercent <= maxEarlyRedeemFee, "Early redeem fee percent > max"); require(newFeesConfig.matureRedeemPercent <= maxMatureRedeemFee, "Mature redeem fee percent > max"); feesConfig = newFeesConfig; } function transferFees(address recipient) external override nonReentrant onlyOwner { uint256 amount = totalFees; totalFees = 0; IERC20 token = IERC20(yieldBearingToken); token.safeTransfer(recipient, amount); } function onDepositBacking(uint256 backingTokenAmount, address recipient) external payable override onlyController returns ( uint256 mintedShares, uint256 depositedYBT, uint256 fee, uint256 rate ) { // Enforced by the controller. assert(backingTokenAmount > 0); depositedYBT = depositToUnderlying(backingTokenAmount); assert(depositedYBT > 0); (mintedShares, , fee, rate) = mintShares(depositedYBT, recipient); } function onDepositYieldBearing(uint256 yieldTokenAmount, address recipient) external override onlyController returns ( uint256 mintedShares, uint256 depositedBT, uint256 fee, uint256 rate ) { // Enforced by the controller. assert(yieldTokenAmount > 0); (mintedShares, depositedBT, fee, rate) = mintShares(yieldTokenAmount, recipient); } /// @param yieldTokenAmount YBT amount in YBT decimal precision /// @param recipient address to which shares will be minted function mintShares(uint256 yieldTokenAmount, address recipient) private returns ( uint256 mintedShares, uint256 depositedBT, uint256 fee, uint256 rate ) { rate = updateInterestRate(); (bool hasMatured, bool hasNegativeYield) = validateInterestRate(rate); require(!hasMatured, "Maturity reached."); require(!hasNegativeYield, "Negative yield!"); // Collect fees if they are set, reducing the number of tokens for the sender // thus leaving more YBT in the TempusPool than there are minted TPS/TYS uint256 tokenAmount = yieldTokenAmount; uint256 depositFees = feesConfig.depositPercent; if (depositFees != 0) { fee = tokenAmount.mulfV(depositFees, yieldBearingONE); tokenAmount -= fee; totalFees += fee; } // Issue appropriate shares depositedBT = numAssetsPerYieldToken(tokenAmount, rate); mintedShares = numSharesToMint(depositedBT, rate); PrincipalShare(address(principalShare)).mint(recipient, mintedShares); YieldShare(address(yieldShare)).mint(recipient, mintedShares); } function redeemToBacking( address from, uint256 principalAmount, uint256 yieldAmount, address recipient ) external payable override onlyController returns ( uint256 redeemedYieldTokens, uint256 redeemedBackingTokens, uint256 fee, uint256 rate ) { (redeemedYieldTokens, fee, rate) = burnShares(from, principalAmount, yieldAmount); redeemedBackingTokens = withdrawFromUnderlyingProtocol(redeemedYieldTokens, recipient); } function redeem( address from, uint256 principalAmount, uint256 yieldAmount, address recipient ) external override onlyController returns ( uint256 redeemedYieldTokens, uint256 fee, uint256 rate ) { (redeemedYieldTokens, fee, rate) = burnShares(from, principalAmount, yieldAmount); redeemedYieldTokens = IERC20(yieldBearingToken).untrustedTransfer(recipient, redeemedYieldTokens); } function finalize() public override { if (matured() && maturityInterestRate == 0) { maturityInterestRate = updateInterestRate(); } } function burnShares( address from, uint256 principalAmount, uint256 yieldAmount ) private returns ( uint256 redeemedYieldTokens, uint256 fee, uint256 interestRate ) { require(IERC20(address(principalShare)).balanceOf(from) >= principalAmount, "Insufficient principals."); require(IERC20(address(yieldShare)).balanceOf(from) >= yieldAmount, "Insufficient yields."); uint256 currentRate = updateInterestRate(); (bool hasMatured, ) = validateInterestRate(currentRate); if (hasMatured) { finalize(); } else { // Redeeming prior to maturity is only allowed in equal amounts. require(principalAmount == yieldAmount, "Inequal redemption not allowed before maturity."); } // Burn the appropriate shares PrincipalShare(address(principalShare)).burnFrom(from, principalAmount); YieldShare(address(yieldShare)).burnFrom(from, yieldAmount); (redeemedYieldTokens, , fee, interestRate) = getRedemptionAmounts(principalAmount, yieldAmount, currentRate); totalFees += fee; } function getRedemptionAmounts( uint256 principalAmount, uint256 yieldAmount, uint256 currentRate ) private view returns ( uint256 redeemableYieldTokens, uint256 redeemableBackingTokens, uint256 redeemFeeAmount, uint256 interestRate ) { interestRate = effectiveRate(currentRate); if (interestRate < initialInterestRate) { redeemableBackingTokens = (principalAmount * interestRate) / initialInterestRate; } else { uint256 rateDiff = interestRate - initialInterestRate; // this is expressed in percent with exchangeRate precision uint256 yieldPercent = rateDiff.divfV(initialInterestRate, exchangeRateONE); uint256 redeemAmountFromYieldShares = yieldAmount.mulfV(yieldPercent, exchangeRateONE); redeemableBackingTokens = principalAmount + redeemAmountFromYieldShares; // after maturity, all additional yield is being collected as fee if (matured() && currentRate > interestRate) { uint256 additionalYieldRate = currentRate - interestRate; uint256 feeBackingAmount = yieldAmount.mulfV( additionalYieldRate.mulfV(initialInterestRate, exchangeRateONE), exchangeRateONE ); redeemFeeAmount = numYieldTokensPerAsset(feeBackingAmount, currentRate); } } redeemableYieldTokens = numYieldTokensPerAsset(redeemableBackingTokens, currentRate); uint256 redeemFeePercent = matured() ? feesConfig.matureRedeemPercent : feesConfig.earlyRedeemPercent; if (redeemFeePercent != 0) { uint256 regularRedeemFee = redeemableYieldTokens.mulfV(redeemFeePercent, yieldBearingONE); redeemableYieldTokens -= regularRedeemFee; redeemFeeAmount += regularRedeemFee; redeemableBackingTokens = numAssetsPerYieldToken(redeemableYieldTokens, currentRate); } } function effectiveRate(uint256 currentRate) private view returns (uint256) { if (matured() && maturityInterestRate != 0) { return (currentRate < maturityInterestRate) ? currentRate : maturityInterestRate; } else { return currentRate; } } /// @dev Calculates current yield - since beginning of the pool /// @notice Includes principal, so in case of 5% yield it returns 1.05 /// @param interestRate Current interest rate of the underlying protocol /// @return Current yield relative to 1, such as 1.05 (+5%) or 0.97 (-3%) function currentYield(uint256 interestRate) private view returns (uint256) { return effectiveRate(interestRate).divfV(initialInterestRate, exchangeRateONE); } function currentYield() private returns (uint256) { return currentYield(updateInterestRate()); } function currentYieldStored() private view returns (uint256) { return currentYield(currentInterestRate()); } function estimatedYieldStored() private view returns (uint256) { return estimatedYield(currentYieldStored()); } /// @dev Calculates estimated yield at maturity /// @notice Includes principal, so in case of 5% yield it returns 1.05 /// @param yieldCurrent Current yield - since beginning of the pool /// @return Estimated yield at maturity relative to 1, such as 1.05 (+5%) or 0.97 (-3%) function estimatedYield(uint256 yieldCurrent) private view returns (uint256) { if (matured()) { return yieldCurrent; } uint256 currentTime = block.timestamp; uint256 timeToMaturity; uint256 poolDuration; unchecked { timeToMaturity = (maturityTime > currentTime) ? (maturityTime - currentTime) : 0; poolDuration = maturityTime - startTime; } uint256 timeLeft = timeToMaturity.divfV(poolDuration, exchangeRateONE); return yieldCurrent + timeLeft.mulfV(initialEstimatedYield, exchangeRateONE); } /// pricePerYield = currentYield * (estimatedYield - 1) / (estimatedYield) /// Return value decimal precision in backing token precision function pricePerYieldShare(uint256 currYield, uint256 estYield) private view returns (uint256) { uint256 one = exchangeRateONE; // in case we have estimate for negative yield if (estYield < one) { return uint256(0); } uint256 yieldPrice = (estYield - one).mulfV(currYield, one).divfV(estYield, one); return interestRateToSharePrice(yieldPrice); } /// pricePerPrincipal = currentYield / estimatedYield /// Return value decimal precision in backing token precision function pricePerPrincipalShare(uint256 currYield, uint256 estYield) private view returns (uint256) { // in case we have estimate for negative yield if (estYield < exchangeRateONE) { return interestRateToSharePrice(currYield); } uint256 principalPrice = currYield.divfV(estYield, exchangeRateONE); return interestRateToSharePrice(principalPrice); } function pricePerYieldShare() external override returns (uint256) { uint256 yield = currentYield(); return pricePerYieldShare(yield, estimatedYield(yield)); } function pricePerYieldShareStored() external view override returns (uint256) { uint256 yield = currentYieldStored(); return pricePerYieldShare(yield, estimatedYield(yield)); } function pricePerPrincipalShare() external override returns (uint256) { uint256 yield = currentYield(); return pricePerPrincipalShare(yield, estimatedYield(yield)); } function pricePerPrincipalShareStored() external view override returns (uint256) { uint256 yield = currentYieldStored(); return pricePerPrincipalShare(yield, estimatedYield(yield)); } function numSharesToMint(uint256 depositedBT, uint256 currentRate) private view returns (uint256) { return (depositedBT * initialInterestRate) / currentRate; } function estimatedMintedShares(uint256 amount, bool isBackingToken) external view override returns (uint256) { uint256 currentRate = currentInterestRate(); uint256 depositedBT = isBackingToken ? amount : numAssetsPerYieldToken(amount, currentRate); return numSharesToMint(depositedBT, currentRate); } function estimatedRedeem( uint256 principals, uint256 yields, bool toBackingToken ) external view override returns (uint256) { uint256 currentRate = currentInterestRate(); (uint256 yieldTokens, uint256 backingTokens, , ) = getRedemptionAmounts(principals, yields, currentRate); return toBackingToken ? backingTokens : yieldTokens; } /// @dev This updates the internal tracking of negative yield periods, /// and returns the current status of maturity and interest rates. function validateInterestRate(uint256 rate) private returns (bool hasMatured, bool hasNegativeYield) { // Short circuit. No need for the below after maturity. if (matured()) { return (true, rate < initialInterestRate); } if (rate >= initialInterestRate) { // Reset period. negativeYieldStartTime = 0; return (false, false); } if (negativeYieldStartTime == 0) { // Entering a negative yield period. negativeYieldStartTime = block.timestamp; return (false, true); } if ((negativeYieldStartTime + maximumNegativeYieldDuration) <= block.timestamp) { // Already in a negative yield period, exceeding the duration. exceptionalHaltTime = block.timestamp; // It is considered matured now because exceptionalHaltTime is set. assert(matured()); return (true, true); } // Already in negative yield period, but not for long enough. return (false, true); } /// @dev This updates the underlying pool's interest rate /// It is done first thing before deposit/redeem to avoid arbitrage /// It is available to call publically to periodically update interest rates in cases of low volume /// @return Updated current Interest Rate, decimal precision depends on specific TempusPool implementation function updateInterestRate() public virtual override returns (uint256); /// @dev This returns the stored Interest Rate of the YBT (Yield Bearing Token) pool /// it is safe to call this after updateInterestRate() was called /// @return Stored Interest Rate, decimal precision depends on specific TempusPool implementation function currentInterestRate() public view virtual override returns (uint256); function numYieldTokensPerAsset(uint256 backingTokens, uint256 interestRate) public view virtual override returns (uint256); function numAssetsPerYieldToken(uint256 yieldTokens, uint256 interestRate) public view virtual override returns (uint256); /// @return Converts an interest rate decimal into a Principal/Yield Share decimal function interestRateToSharePrice(uint256 interestRate) internal view virtual returns (uint256); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.10; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; /*** @notice based on https://github.com/yearn/yearn-vaults/blob/main/contracts/Vault.vy */ interface IYearnVaultV2 is IERC20, IERC20Metadata { /// @dev Deposits an `amount` of underlying asset into the Vault, receiving in return overlying yTokens. /// - E.g. User deposits 100 DAI and gets in return 100 yDAI /// @param amount The amount to be deposited function deposit(uint256 amount) external returns (uint256); /// @dev withdraws shares from the vault on behalf of `msg.sender` /// @param maxShares How many shares to try and redeem for tokens. /// @param recipient The address to issue the shares in this Vault to. /// @return The quantity of tokens redeemed for `_shares`. function withdraw(uint256 maxShares, address recipient) external returns (uint256); /// @dev Returns the current price of a share of the Vault /// @return The price of a share of the Vault function pricePerShare() external view returns (uint256); /// @return The address of the underlying asset (e.g. - DAI/USDC) function token() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /// @title UntrustedERC20 /// @dev Wrappers around ERC20 transfer operators that return the actual amount /// transferred. This means they are usable with tokens, which charge a fee or royalty on transfer. library UntrustedERC20 { using SafeERC20 for IERC20; /// Transfer tokens to a recipient. /// @param token The ERC20 token. /// @param to The recipient. /// @param value The requested amount. /// @return The actual amount of tokens transferred. function untrustedTransfer( IERC20 token, address to, uint256 value ) internal returns (uint256) { uint256 startBalance = token.balanceOf(to); token.safeTransfer(to, value); return token.balanceOf(to) - startBalance; } /// Transfer tokens to a recipient. /// @param token The ERC20 token. /// @param from The sender. /// @param to The recipient. /// @param value The requested amount. /// @return The actual amount of tokens transferred. function untrustedTransferFrom( IERC20 token, address from, address to, uint256 value ) internal returns (uint256) { uint256 startBalance = token.balanceOf(to); token.safeTransferFrom(from, to, value); return token.balanceOf(to) - startBalance; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; /// @dev Fixed Point decimal math utils for variable decimal point precision /// on 256-bit wide numbers library Fixed256xVar { /// @dev Multiplies two variable precision fixed point decimal numbers /// @param one 1.0 expressed in the base precision of `a` and `b` /// @return result = a * b function mulfV( uint256 a, uint256 b, uint256 one ) internal pure returns (uint256) { // result is always truncated return (a * b) / one; } /// @dev Divides two variable precision fixed point decimal numbers /// @param one 1.0 expressed in the base precision of `a` and `b` /// @return result = a / b function divfV( uint256 a, uint256 b, uint256 one ) internal pure returns (uint256) { // result is always truncated return (a * one) / b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) private pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.6 <0.9.0; pragma abicoder v2; import "./token/IPoolShare.sol"; import "./utils/IOwnable.sol"; import "./utils/IVersioned.sol"; /// Setting and transferring of fees are restricted to the owner. interface ITempusFees is IOwnable { /// The fees are in terms of yield bearing token (YBT). struct FeesConfig { uint256 depositPercent; uint256 earlyRedeemPercent; uint256 matureRedeemPercent; } /// Returns the current fee configuration. function getFeesConfig() external view returns (FeesConfig memory); /// Replace the current fee configuration with a new one. /// By default all the fees are expected to be set to zero. /// @notice This function can only be called by the owner. function setFeesConfig(FeesConfig calldata newFeesConfig) external; /// @return Maximum possible fee percentage that can be set for deposit function maxDepositFee() external view returns (uint256); /// @return Maximum possible fee percentage that can be set for early redeem function maxEarlyRedeemFee() external view returns (uint256); /// @return Maximum possible fee percentage that can be set for mature redeem function maxMatureRedeemFee() external view returns (uint256); /// Accumulated fees available for withdrawal. function totalFees() external view returns (uint256); /// Transfers accumulated Yield Bearing Token (YBT) fees /// from this pool contract to `recipient`. /// @param recipient Address which will receive the specified amount of YBT /// @notice This function can only be called by the owner. function transferFees(address recipient) external; } /// All state changing operations are restricted to the controller. interface ITempusPool is ITempusFees, IVersioned { /// @return The name of underlying protocol, for example "Aave" for Aave protocol function protocolName() external view returns (bytes32); /// This token will be used as a token that user can deposit to mint same amounts /// of principal and interest shares. /// @return The underlying yield bearing token. function yieldBearingToken() external view returns (address); /// This is the address of the actual backing asset token /// in the case of ETH, this address will be 0 /// @return Address of the Backing Token function backingToken() external view returns (address); /// @return uint256 value of one backing token, in case of 18 decimals 1e18 function backingTokenONE() external view returns (uint256); /// @return This TempusPool's Tempus Principal Share (TPS) function principalShare() external view returns (IPoolShare); /// @return This TempusPool's Tempus Yield Share (TYS) function yieldShare() external view returns (IPoolShare); /// @return The TempusController address that is authorized to perform restricted actions function controller() external view returns (address); /// @return Start time of the pool. function startTime() external view returns (uint256); /// @return Maturity time of the pool. function maturityTime() external view returns (uint256); /// @return Time of exceptional halting of the pool. /// In case the pool is still in operation, this must return type(uint256).max. function exceptionalHaltTime() external view returns (uint256); /// @return The maximum allowed time (in seconds) to pass with negative yield. function maximumNegativeYieldDuration() external view returns (uint256); /// @return True if maturity has been reached and the pool was finalized. /// This also includes the case when maturity was triggered due to /// exceptional conditions (negative yield periods). function matured() external view returns (bool); /// Finalizes the pool. This can only happen on or after `maturityTime`. /// Once finalized depositing is not possible anymore, and the behaviour /// redemption will change. /// /// Can be called by anyone and can be called multiple times. function finalize() external; /// Yield bearing tokens deposit hook. /// @notice Deposit will fail if maturity has been reached. /// @notice This function can only be called by TempusController /// @notice This function assumes funds were already transferred to the TempusPool from the TempusController /// @param yieldTokenAmount Amount of yield bearing tokens to deposit in YieldToken decimal precision /// @param recipient Address which will receive Tempus Principal Shares (TPS) and Tempus Yield Shares (TYS) /// @return mintedShares Amount of TPS and TYS minted to `recipient` /// @return depositedBT The YBT value deposited, denominated as Backing Tokens /// @return fee The fee which was deducted (in terms of YBT) /// @return rate The interest rate at the time of the deposit function onDepositYieldBearing(uint256 yieldTokenAmount, address recipient) external returns ( uint256 mintedShares, uint256 depositedBT, uint256 fee, uint256 rate ); /// Backing tokens deposit hook. /// @notice Deposit will fail if maturity has been reached. /// @notice This function can only be called by TempusController /// @notice This function assumes funds were already transferred to the TempusPool from the TempusController /// @param backingTokenAmount amount of Backing Tokens to be deposited to underlying protocol in BackingToken decimal precision /// @param recipient Address which will receive Tempus Principal Shares (TPS) and Tempus Yield Shares (TYS) /// @return mintedShares Amount of TPS and TYS minted to `recipient` /// @return depositedYBT The BT value deposited, denominated as Yield Bearing Tokens /// @return fee The fee which was deducted (in terms of YBT) /// @return rate The interest rate at the time of the deposit function onDepositBacking(uint256 backingTokenAmount, address recipient) external payable returns ( uint256 mintedShares, uint256 depositedYBT, uint256 fee, uint256 rate ); /// Redeems yield bearing tokens from this TempusPool /// msg.sender will receive the YBT /// NOTE #1 Before maturity, principalAmount must equal to yieldAmount. /// NOTE #2 This function can only be called by TempusController /// @param from Address to redeem its Tempus Shares /// @param principalAmount Amount of Tempus Principal Shares (TPS) to redeem for YBT in PrincipalShare decimal precision /// @param yieldAmount Amount of Tempus Yield Shares (TYS) to redeem for YBT in YieldShare decimal precision /// @param recipient Address to which redeemed YBT will be sent /// @return redeemableYieldTokens Amount of Yield Bearing Tokens redeemed to `recipient` /// @return fee The fee which was deducted (in terms of YBT) /// @return rate The interest rate at the time of the redemption function redeem( address from, uint256 principalAmount, uint256 yieldAmount, address recipient ) external returns ( uint256 redeemableYieldTokens, uint256 fee, uint256 rate ); /// Redeems TPS+TYS held by msg.sender into backing tokens /// `msg.sender` must approve TPS and TYS amounts to this TempusPool. /// `msg.sender` will receive the backing tokens /// NOTE #1 Before maturity, principalAmount must equal to yieldAmount. /// NOTE #2 This function can only be called by TempusController /// @param from Address to redeem its Tempus Shares /// @param principalAmount Amount of Tempus Principal Shares (TPS) to redeem in PrincipalShare decimal precision /// @param yieldAmount Amount of Tempus Yield Shares (TYS) to redeem in YieldShare decimal precision /// @param recipient Address to which redeemed BT will be sent /// @return redeemableYieldTokens Amount of Backing Tokens redeemed to `recipient`, denominated in YBT /// @return redeemableBackingTokens Amount of Backing Tokens redeemed to `recipient` /// @return fee The fee which was deducted (in terms of YBT) /// @return rate The interest rate at the time of the redemption function redeemToBacking( address from, uint256 principalAmount, uint256 yieldAmount, address recipient ) external payable returns ( uint256 redeemableYieldTokens, uint256 redeemableBackingTokens, uint256 fee, uint256 rate ); /// Gets the estimated amount of Principals and Yields after a successful deposit /// @param amount Amount of BackingTokens or YieldBearingTokens that would be deposited /// @param isBackingToken If true, @param amount is in BackingTokens, otherwise YieldBearingTokens /// @return Amount of Principals (TPS) and Yields (TYS) in Principal/YieldShare decimal precision /// TPS and TYS are minted in 1:1 ratio, hence a single return value. function estimatedMintedShares(uint256 amount, bool isBackingToken) external view returns (uint256); /// Gets the estimated amount of YieldBearingTokens or BackingTokens received when calling `redeemXXX()` functions /// @param principals Amount of Principals (TPS) in PrincipalShare decimal precision /// @param yields Amount of Yields (TYS) in YieldShare decimal precision /// @param toBackingToken If true, redeem amount is estimated in BackingTokens instead of YieldBearingTokens /// @return Amount of YieldBearingTokens or BackingTokens in YBT/BT decimal precision function estimatedRedeem( uint256 principals, uint256 yields, bool toBackingToken ) external view returns (uint256); /// @dev This updates the underlying pool's interest rate /// It is done first thing before deposit/redeem to avoid arbitrage /// It is available to call publically to periodically update interest rates in cases of low volume /// @return Updated current Interest Rate, decimal precision depends on specific TempusPool implementation function updateInterestRate() external returns (uint256); /// @dev This returns the stored Interest Rate of the YBT (Yield Bearing Token) pool /// it is safe to call this after updateInterestRate() was called /// @return Stored Interest Rate, decimal precision depends on specific TempusPool implementation function currentInterestRate() external view returns (uint256); /// @return Initial interest rate of the underlying pool, /// decimal precision depends on specific TempusPool implementation function initialInterestRate() external view returns (uint256); /// @return Interest rate at maturity of the underlying pool (or 0 if maturity not reached yet) /// decimal precision depends on specific TempusPool implementation function maturityInterestRate() external view returns (uint256); /// @return Rate of one Tempus Yield Share expressed in Asset Tokens function pricePerYieldShare() external returns (uint256); /// @return Rate of one Tempus Principal Share expressed in Asset Tokens function pricePerPrincipalShare() external returns (uint256); /// Calculated with stored interest rates /// @return Rate of one Tempus Yield Share expressed in Asset Tokens, function pricePerYieldShareStored() external view returns (uint256); /// Calculated with stored interest rates /// @return Rate of one Tempus Principal Share expressed in Asset Tokens function pricePerPrincipalShareStored() external view returns (uint256); /// @dev This returns actual Backing Token amount for amount of YBT (Yield Bearing Tokens) /// For example, in case of Aave and Lido the result is 1:1, /// and for compound is `yieldTokens * currentInterestRate` /// @param yieldTokens Amount of YBT in YBT decimal precision /// @param interestRate The current interest rate /// @return Amount of Backing Tokens for specified @param yieldTokens function numAssetsPerYieldToken(uint256 yieldTokens, uint256 interestRate) external view returns (uint256); /// @dev This returns amount of YBT (Yield Bearing Tokens) that can be converted /// from @param backingTokens Backing Tokens /// @param backingTokens Amount of Backing Tokens in BT decimal precision /// @param interestRate The current interest rate /// @return Amount of YBT for specified @param backingTokens function numYieldTokensPerAsset(uint256 backingTokens, uint256 interestRate) external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "./PoolShare.sol"; /// @dev Token representing the principal shares of a pool. contract PrincipalShare is PoolShare { constructor( ITempusPool _pool, string memory name, string memory symbol, uint8 decimals ) PoolShare(ShareKind.Principal, _pool, name, symbol, decimals) {} // solhint-disable-previous-line no-empty-blocks function getPricePerFullShare() external override returns (uint256) { return pool.pricePerPrincipalShare(); } function getPricePerFullShareStored() external view override returns (uint256) { return pool.pricePerPrincipalShareStored(); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "./PoolShare.sol"; /// @dev Token representing the yield shares of a pool. contract YieldShare is PoolShare { constructor( ITempusPool _pool, string memory name, string memory symbol, uint8 decimals ) PoolShare(ShareKind.Yield, _pool, name, symbol, decimals) {} // solhint-disable-previous-line no-empty-blocks function getPricePerFullShare() external override returns (uint256) { return pool.pricePerYieldShare(); } function getPricePerFullShareStored() external view override returns (uint256) { return pool.pricePerYieldShareStored(); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; import "./IOwnable.sol"; /// Implements Ownable with a two step transfer of ownership abstract contract Ownable is IOwnable { address private _owner; address private _proposedOwner; /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _setOwner(msg.sender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual override returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == msg.sender, "Ownable: caller is not the owner"); _; } /** * @dev Proposes a transfer of ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _proposedOwner = newOwner; emit OwnershipProposed(_owner, _proposedOwner); } /** * @dev Accepts ownership of the contract by a proposed account. * Can only be called by the proposed owner. */ function acceptOwnership() public virtual override { require(msg.sender == _proposedOwner, "Ownable: Only proposed owner can accept ownership"); _setOwner(_proposedOwner); _proposedOwner = address(0); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.7.6 <0.9.0; import "./IVersioned.sol"; /// Implements versioning abstract contract Versioned is IVersioned { uint16 private immutable _major; uint16 private immutable _minor; uint16 private immutable _patch; constructor( uint16 major, uint16 minor, uint16 patch ) { _major = major; _minor = minor; _patch = patch; } function version() external view returns (Version memory) { return Version(_major, _minor, _patch); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.7.6 <0.9.0; import "../ITempusPool.sol"; /// Interface of Tokens representing the principal or yield shares of a pool. interface IPoolShare { enum ShareKind { Principal, Yield } /// @return The kind of the share. function kind() external view returns (ShareKind); /// @return The pool this share is part of. function pool() external view returns (ITempusPool); /// @dev Price per single share expressed in Backing Tokens of the underlying pool. /// This is for the purpose of TempusAMM api support. /// Example: exchanging Tempus Yield Share to DAI /// @return 1e18 decimal conversion rate per share function getPricePerFullShare() external returns (uint256); /// @return 1e18 decimal stored conversion rate per share function getPricePerFullShareStored() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.7.6 <0.9.0; /// Implements Ownable with a two step transfer of ownership interface IOwnable { /** * @dev Change of ownership proposed. * @param currentOwner The current owner. * @param proposedOwner The proposed owner. */ event OwnershipProposed(address indexed currentOwner, address indexed proposedOwner); /** * @dev Ownership transferred. * @param previousOwner The previous owner. * @param newOwner The new owner. */ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the current owner. */ function owner() external view returns (address); /** * @dev Proposes a transfer of ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) external; /** * @dev Accepts ownership of the contract by a proposed account. * Can only be called by the proposed owner. */ function acceptOwnership() external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.7.6 <0.9.0; pragma abicoder v2; /// Implements versioning interface IVersioned { struct Version { uint16 major; uint16 minor; uint16 patch; } /// @return The version of the contract. function version() external view returns (Version memory); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.10; import "./ERC20OwnerMintableToken.sol"; import "../ITempusPool.sol"; /// Token representing the principal or yield shares of a pool. abstract contract PoolShare is IPoolShare, ERC20OwnerMintableToken { /// The kind of the share. ShareKind public immutable override kind; /// The pool this share is part of. ITempusPool public immutable override pool; uint8 internal immutable tokenDecimals; constructor( ShareKind _kind, ITempusPool _pool, string memory name, string memory symbol, uint8 _decimals ) ERC20OwnerMintableToken(name, symbol) { kind = _kind; pool = _pool; tokenDecimals = _decimals; } function decimals() public view virtual override returns (uint8) { return tokenDecimals; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; /// This is a simplified implementation, but compatible with /// OpenZeppelin's ERC20Mintable and ERC20Burnable extensions. contract ERC20OwnerMintableToken is ERC20 { /// The manager who is allowed to mint and burn. address public immutable manager; constructor(string memory name, string memory symbol) ERC20(name, symbol) { manager = msg.sender; } /// Creates `amount` new tokens for `to`. /// @param account Recipient address to mint tokens to /// @param amount Number of tokens to mint function mint(address account, uint256 amount) external { require(msg.sender == manager, "mint: only manager can mint"); _mint(account, amount); } /// Destroys `amount` tokens from the caller. /// @param amount Number of tokens to burn. function burn(uint256 amount) external { require(msg.sender == manager, "burn: only manager can burn"); _burn(manager, amount); } /// Destroys `amount` tokens from `account`. /// @param account Source address to burn tokens from /// @param amount Number of tokens to burn function burnFrom(address account, uint256 amount) external { require(msg.sender == manager, "burn: only manager can burn"); _burn(account, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// 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; } }
{ "optimizer": { "enabled": true, "runs": 100000 }, "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":"contract IYearnVaultV2","name":"vault","type":"address"},{"internalType":"address","name":"controller","type":"address"},{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"estYield","type":"uint256"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"internalType":"struct TokenData","name":"principalsData","type":"tuple"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"internalType":"struct TokenData","name":"yieldsData","type":"tuple"},{"components":[{"internalType":"uint256","name":"depositPercent","type":"uint256"},{"internalType":"uint256","name":"earlyRedeemPercent","type":"uint256"},{"internalType":"uint256","name":"matureRedeemPercent","type":"uint256"}],"internalType":"struct ITempusFees.FeesConfig","name":"maxFeeSetup","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"currentOwner","type":"address"},{"indexed":true,"internalType":"address","name":"proposedOwner","type":"address"}],"name":"OwnershipProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"backingToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"backingTokenONE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentInterestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"isBackingToken","type":"bool"}],"name":"estimatedMintedShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"principals","type":"uint256"},{"internalType":"uint256","name":"yields","type":"uint256"},{"internalType":"bool","name":"toBackingToken","type":"bool"}],"name":"estimatedRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exceptionalHaltTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exchangeRateONE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getFeesConfig","outputs":[{"components":[{"internalType":"uint256","name":"depositPercent","type":"uint256"},{"internalType":"uint256","name":"earlyRedeemPercent","type":"uint256"},{"internalType":"uint256","name":"matureRedeemPercent","type":"uint256"}],"internalType":"struct ITempusFees.FeesConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialInterestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"matured","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maturityInterestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maturityTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDepositFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxEarlyRedeemFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMatureRedeemFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumNegativeYieldDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"yieldTokens","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"numAssetsPerYieldToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"backingTokens","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"numYieldTokensPerAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"backingTokenAmount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"onDepositBacking","outputs":[{"internalType":"uint256","name":"mintedShares","type":"uint256"},{"internalType":"uint256","name":"depositedYBT","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"yieldTokenAmount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"onDepositYieldBearing","outputs":[{"internalType":"uint256","name":"mintedShares","type":"uint256"},{"internalType":"uint256","name":"depositedBT","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pricePerPrincipalShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pricePerPrincipalShareStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pricePerYieldShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pricePerYieldShareStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"principalShare","outputs":[{"internalType":"contract IPoolShare","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolName","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"principalAmount","type":"uint256"},{"internalType":"uint256","name":"yieldAmount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"redeemedYieldTokens","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"principalAmount","type":"uint256"},{"internalType":"uint256","name":"yieldAmount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"redeemToBacking","outputs":[{"internalType":"uint256","name":"redeemedYieldTokens","type":"uint256"},{"internalType":"uint256","name":"redeemedBackingTokens","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"depositPercent","type":"uint256"},{"internalType":"uint256","name":"earlyRedeemPercent","type":"uint256"},{"internalType":"uint256","name":"matureRedeemPercent","type":"uint256"}],"internalType":"struct ITempusFees.FeesConfig","name":"newFeesConfig","type":"tuple"}],"name":"setFeesConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"transferFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateInterestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"components":[{"internalType":"uint16","name":"major","type":"uint16"},{"internalType":"uint16","name":"minor","type":"uint16"},{"internalType":"uint16","name":"patch","type":"uint16"}],"internalType":"struct IVersioned.Version","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yieldBearingONE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yieldBearingToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yieldShare","outputs":[{"internalType":"contract IPoolShare","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6102e06040526000196003553480156200001857600080fd5b5060405162006e9a38038062006e9a8339810160408190526200003b9162000998565b86876001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200007b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a1919062000a83565b87878a6001600160a01b03166399530b066040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000108919062000aaa565b8b6001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000147573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016d919062000a83565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001ab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001d1919062000ac4565b620001de90600a62000bfe565b600160008181558b918b918b918b9180620001f93362000779565b61ffff92831660805290821660a0521660c052428711620002615760405162461bcd60e51b815260206004820152601f60248201527f6d6174757269747954696d6520697320616674657220737461727454696d650060448201526064015b60405180910390fd5b6001600160a01b038816620002b95760405162461bcd60e51b815260206004820152601a60248201527f636f6e74726f6c6c65722063616e206e6f74206265207a65726f000000000000604482015260640162000258565b600086116200030b5760405162461bcd60e51b815260206004820181905260248201527f696e6974496e746572657374526174652063616e206e6f74206265207a65726f604482015260640162000258565b60008411620003695760405162461bcd60e51b815260206004820152602360248201527f657374696d6174656446696e616c5969656c642063616e206e6f74206265207a60448201526265726f60e81b606482015260840162000258565b6001600160a01b038a16620003c15760405162461bcd60e51b815260206004820152601360248201527f5942542063616e206e6f74206265207a65726f00000000000000000000000000604482015260640162000258565b6001600160a01b03808b1660e08190528a8216610100529089166102205242610120526101408890526101608790526101808690526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa15801562000432573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000458919062000ac4565b6200046590600a62000bfe565b6101a05261024084905280516102605260208101516102805260408101516102a05260006001600160a01b038a16620004a057601262000505565b896001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620004df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000505919062000ac4565b90506200051481600a62000bfe565b6101c052835160208501516040513092919084906200053390620007cb565b62000542949392919062000c3d565b604051809103906000f0801580156200055f573d6000803e3d6000fd5b506001600160a01b03166101e052825160208401516040513092919084906200058890620007d9565b62000597949392919062000c3d565b604051809103906000f080158015620005b4573d6000803e3d6000fd5b506001600160a01b0316610200816001600160a01b0316815250505050505050505050505050866001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000619573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200063f919062000a83565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200067d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006a3919062000ac4565b60ff16876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620006e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200070b919062000ac4565b60ff16146200075d5760405162461bcd60e51b815260206004820152601b60248201527f446563696d616c7320707265636973696f6e206d69736d617463680000000000604482015260640162000258565b5050506001600160a01b039093166102c0525062000c8c915050565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611748806200400a83390190565b611748806200575283390190565b6001600160a01b0381168114620007fd57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156200083b576200083b62000800565b60405290565b60005b838110156200085e57818101518382015260200162000844565b838111156200086e576000848401525b50505050565b600082601f8301126200088657600080fd5b81516001600160401b0380821115620008a357620008a362000800565b604051601f8301601f19908116603f01168101908282118183101715620008ce57620008ce62000800565b81604052838152866020858801011115620008e857600080fd5b620008fb84602083016020890162000841565b9695505050505050565b6000604082840312156200091857600080fd5b604080519081016001600160401b0380821183831017156200093e576200093e62000800565b8160405282935084519150808211156200095757600080fd5b620009658683870162000874565b835260208501519150808211156200097c57600080fd5b506200098b8582860162000874565b6020830152505092915050565b6000806000806000806000878903610120811215620009b657600080fd5b8851620009c381620007e7565b60208a0151909850620009d681620007e7565b60408a015160608b015160808c015192995090975095506001600160401b038082111562000a0357600080fd5b62000a118c838d0162000905565b955060a08b015191508082111562000a2857600080fd5b5062000a378b828c0162000905565b935050606060bf198201121562000a4d57600080fd5b5062000a5862000816565b60c0890151815260e08901516020820152610100909801516040890152509497939650919490939192565b60006020828403121562000a9657600080fd5b815162000aa381620007e7565b9392505050565b60006020828403121562000abd57600080fd5b5051919050565b60006020828403121562000ad757600080fd5b815160ff8116811462000aa357600080fd5b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000b4057816000190482111562000b245762000b2462000ae9565b8085161562000b3257918102915b93841c939080029062000b04565b509250929050565b60008262000b595750600162000bf8565b8162000b685750600062000bf8565b816001811462000b81576002811462000b8c5762000bac565b600191505062000bf8565b60ff84111562000ba05762000ba062000ae9565b50506001821b62000bf8565b5060208310610133831016604e8410600b841016171562000bd1575081810a62000bf8565b62000bdd838362000aff565b806000190482111562000bf45762000bf462000ae9565b0290505b92915050565b600062000aa360ff84168362000b48565b6000815180845262000c2981602086016020860162000841565b601f01601f19169290920160200192915050565b6001600160a01b038516815260806020820181905260009062000c639083018662000c0f565b828103604084015262000c77818662000c0f565b91505060ff8316606083015295945050505050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c05161314862000ec26000396000818161137801528181611f0901528181611f5d01526124210152600081816108ec01526110b9015260008181610328015261102b0152600081816108180152610fa0015260006117a60152600081816109aa01528181610a0d01528181610b9201528181610e2b0152611422015260008181610883015281816119d101528181611c5401526122850152600081816103fe015281816118b701528181611bae01526121dd015260006103710152600081816104db0152818161212e01526127cf0152600081816106bc0152818161125c015281816112920152818161177a015281816117c7015281816118030152818161183901528181611e4701528181612684015281816126b3015281816127370152818161275f015261284d01526000818161075901528181612589015281816125cb015281816125f30152818161263401528181612663015281816127160152818161282c0152818161288b01526128b401526000818161056f01528181610b22015281816116db0152818161170a01526117510152600081816106f001526117300152600081816104a701528181611ee701526129750152600081816103a501528181610aeb01528181610dc40152612a030152600061061f015260006105f5015260006105cb01526131486000f3fe6080604052600436106102d15760003560e01c806378e9792511610179578063b468d244116100d6578063e567e8691161008a578063f2fde38b11610064578063f2fde38b14610978578063f77c479114610998578063ff4c7e31146108c557600080fd5b8063e567e8691461090e578063e8a8cf6514610942578063e9c5ce281461096257600080fd5b8063ca9d2d55116100bb578063ca9d2d55146108a5578063ce76756f146108c5578063e34c4b6a146108da57600080fd5b8063b468d2441461034a578063c56c7a851461087157600080fd5b80638da5cb5b1161012d5780639d27d5fc116101125780639d27d5fc146107e6578063a8d1dbfb14610806578063af6934171461083a57600080fd5b80638da5cb5b1461079b578063960c6917146107c657600080fd5b806379ba50971161015e57806379ba5097146107325780638088e121146107475780638a425ea91461077b57600080fd5b806378e97925146106de57806378ec24ee1461071257600080fd5b806347e621b7116102325780634e289bdf116101e657806363dc4ef5116101c057806363dc4ef5146106775780636c8d4fa114610697578063757881fd146106aa57600080fd5b80634e289bdf146105475780634e8bfdaa1461055d57806354fd4d501461059157600080fd5b80634b009e06116102175780634b009e06146104fd5780634bb278f3146105305780634e18f3241461048057600080fd5b806347e621b71461049557806349d088c3146104c957600080fd5b80632d81f8381161028957806343bcfab61161026e57806343bcfab614610420578063454c87b31461045b5780634570452a1461048057600080fd5b80632d81f8381461039357806335083643146103ec57600080fd5b80632208ebbd116102ba5780632208ebbd146103165780632675323d1461034a5780632b532a971461035f57600080fd5b806313114a9d146102d65780631f796f7f146102ff575b600080fd5b3480156102e257600080fd5b506102ec60085481565b6040519081526020015b60405180910390f35b34801561030b57600080fd5b506102ec62093a8081565b34801561032257600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b34801561035657600080fd5b506102ec6109cc565b34801561036b57600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b34801561039f57600080fd5b506103c77f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f6565b3480156103f857600080fd5b506103c77f000000000000000000000000000000000000000000000000000000000000000081565b34801561042c57600080fd5b5061044061043b366004612dfd565b6109f1565b604080519384526020840192909252908201526060016102f6565b34801561046757600080fd5b50610470610b1e565b60405190151581526020016102f6565b34801561048c57600080fd5b506102ec610b56565b3480156104a157600080fd5b506103c77f000000000000000000000000000000000000000000000000000000000000000081565b3480156104d557600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b61051061050b366004612e43565b610b75565b6040805194855260208501939093529183015260608201526080016102f6565b34801561053c57600080fd5b50610545610c83565b005b34801561055357600080fd5b506102ec60035481565b34801561056957600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b34801561059d57600080fd5b5061064a604080516060810182526000808252602082018190529181019190915260405180606001604052807f000000000000000000000000000000000000000000000000000000000000000061ffff1681526020017f000000000000000000000000000000000000000000000000000000000000000061ffff1681526020017f000000000000000000000000000000000000000000000000000000000000000061ffff16815250905090565b60408051825161ffff908116825260208085015182169083015292820151909216908201526060016102f6565b34801561068357600080fd5b50610545610692366004612e6f565b610caa565b6105106106a5366004612dfd565b610e0e565b3480156106b657600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b3480156106ea57600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b34801561071e57600080fd5b5061054561072d366004612e8a565b610f01565b34801561073e57600080fd5b50610545611160565b34801561075357600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b34801561078757600080fd5b506102ec610796366004612ea2565b611253565b3480156107a757600080fd5b5060015473ffffffffffffffffffffffffffffffffffffffff166103c7565b3480156107d257600080fd5b506102ec6107e1366004612ea2565b611289565b3480156107f257600080fd5b506102ec610801366004612ed5565b6112b6565b34801561081257600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b34801561084657600080fd5b5061084f6112f0565b60408051825181526020808401519082015291810151908201526060016102f6565b34801561087d57600080fd5b506103c77f000000000000000000000000000000000000000000000000000000000000000081565b3480156108b157600080fd5b506102ec6108c0366004612f05565b611339565b3480156108d157600080fd5b506102ec611374565b3480156108e657600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000000081565b34801561091a57600080fd5b506102ec7f596561726e00000000000000000000000000000000000000000000000000000081565b34801561094e57600080fd5b5061051061095d366004612e43565b611405565b34801561096e57600080fd5b506102ec60045481565b34801561098457600080fd5b50610545610993366004612e6f565b6114f9565b3480156109a457600080fd5b506103c77f000000000000000000000000000000000000000000000000000000000000000081565b6000806109d76116b0565b90506109eb816109e6836116c2565b6117ff565b91505090565b600080803373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f6e6c792063616c6c61626c652062792054656d707573436f6e74726f6c6c6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610aca878787611869565b91945092509050610b1273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168585611cee565b92509450945094915050565b60007f000000000000000000000000000000000000000000000000000000000000000042101580610b5157506003544210155b905090565b600080610b616116b0565b90506109eb81610b70836116c2565b611e43565b60008080803373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f6e6c792063616c6c61626c652062792054656d707573436f6e74726f6c6c6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610ab6565b60008611610c4f57610c4f612f3e565b610c5886611ea4565b925060008311610c6a57610c6a612f3e565b610c74838661202c565b92999598509650909450505050565b610c8b610b1e565b8015610c975750600454155b15610ca857610ca4611374565b6004555b565b60026000541415610d17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ab6565b600260005533610d3c60015473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614610db9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ab6565b6008805460009091557f0000000000000000000000000000000000000000000000000000000000000000610e0473ffffffffffffffffffffffffffffffffffffffff821684846122f0565b5050600160005550565b60008080803373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610ed8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f6e6c792063616c6c61626c652062792054656d707573436f6e74726f6c6c6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610ab6565b610ee3888888611869565b91955092509050610ef484866123c4565b9250945094509450949050565b33610f2160015473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614610f9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ab6565b7f000000000000000000000000000000000000000000000000000000000000000081351115611029576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4465706f736974206665652070657263656e74203e206d6178000000000000006044820152606401610ab6565b7f0000000000000000000000000000000000000000000000000000000000000000816020013511156110b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4561726c792072656465656d206665652070657263656e74203e206d617800006044820152606401610ab6565b7f000000000000000000000000000000000000000000000000000000000000000081604001351115611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d61747572652072656465656d206665652070657263656e74203e206d6178006044820152606401610ab6565b8035600555602081013560065560400135600755565b505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314611207576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4f776e61626c653a204f6e6c792070726f706f736564206f776e65722063616e60448201527f20616363657074206f776e6572736869700000000000000000000000000000006064820152608401610ab6565b6002546112299073ffffffffffffffffffffffffffffffffffffffff166124e6565b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600061128083837f000000000000000000000000000000000000000000000000000000000000000061255d565b90505b92915050565b600061128083837f0000000000000000000000000000000000000000000000000000000000000000612574565b6000806112c1611374565b90506000836112d9576112d48583611289565b6112db565b845b90506112e78183612581565b95945050505050565b61131460405180606001604052806000815260200160008152602001600081525090565b5060408051606081018252600554815260065460208201526007549181019190915290565b600080611344611374565b90506000806113548787856125b8565b505091509150846113655781611367565b805b93505050505b9392505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166399530b066040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b519190612f6d565b60008080803373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f6e6c792063616c6c61626c652062792054656d707573436f6e74726f6c6c6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610ab6565b600086116114df576114df612f3e565b6114e9868661202c565b9299919850965090945092505050565b3361151960015473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614611596576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ab6565b73ffffffffffffffffffffffffffffffffffffffff8116611639576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610ab6565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600154604051919216907fb51454ce8c7f26becd312a46c4815553887f2ec876a0b8dc813b87f62edf6f8090600090a350565b6000610b516116bd611374565b612825565b60006116cc610b1e565b156116d5575090565b426000807f0000000000000000000000000000000000000000000000000000000000000000831061170757600061172b565b827f0000000000000000000000000000000000000000000000000000000000000000035b9150507f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000003600061179e83837f000000000000000000000000000000000000000000000000000000000000000061255d565b90506117eb817f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612574565b6117f59087612fb5565b9695505050505050565b60007f0000000000000000000000000000000000000000000000000000000000000000821015611830575081611283565b600061185d84847f000000000000000000000000000000000000000000000000000000000000000061255d565b9050805b949350505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526000918291829186917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156118fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119229190612f6d565b101561198a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e73756666696369656e74207072696e636970616c732e00000000000000006044820152606401610ab6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015285917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015611a1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a3e9190612f6d565b1015611aa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e73756666696369656e74207969656c64732e0000000000000000000000006044820152606401610ab6565b6000611ab0611374565b90506000611abd82612875565b5090508015611ad357611ace610c83565b611b62565b858714611b62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f496e657175616c20726564656d7074696f6e206e6f7420616c6c6f776564206260448201527f65666f7265206d617475726974792e00000000000000000000000000000000006064820152608401610ab6565b6040517f79cc679000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8981166004830152602482018990527f000000000000000000000000000000000000000000000000000000000000000016906379cc679090604401600060405180830381600087803b158015611bf257600080fd5b505af1158015611c06573d6000803e3d6000fd5b50506040517f79cc679000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152602482018a90527f00000000000000000000000000000000000000000000000000000000000000001692506379cc67909150604401600060405180830381600087803b158015611c9a57600080fd5b505af1158015611cae573d6000803e3d6000fd5b50505050611cbd8787846125b8565b6008805494995091975095508692909150600090611cdc908490612fb5565b92505081905550505093509350939050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015260009182918616906370a0823190602401602060405180830381865afa158015611d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d839190612f6d565b9050611da673ffffffffffffffffffffffffffffffffffffffff861685856122f0565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528291908716906370a0823190602401602060405180830381865afa158015611e15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e399190612f6d565b6112e79190612fcd565b60007f000000000000000000000000000000000000000000000000000000000000000080831015611e78576000915050611283565b6000611e9c8483611e958882611e8e8186612fcd565b9190612574565b919061255d565b9050806112e7565b6000816000611eb1612944565b90503415611ec157611ec1612f3e565b6000611ecb6129d2565b9050611f2e73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000087612a47565b6040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063b6b55f25906024016020604051808303816000875af1158015611fbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fdf9190612f6d565b5080611fe96129d2565b611ff39190612fcd565b9350506000612000612944565b61200a9083612fcd565b6120149084612fcd565b9050801561202457612024612f3e565b505050919050565b60008060008061203a611374565b905060008061204883612875565b9150915081156120b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4d6174757269747920726561636865642e0000000000000000000000000000006044820152606401610ab6565b801561211c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4e65676174697665207969656c642100000000000000000000000000000000006044820152606401610ab6565b600554889080156121785761215282827f0000000000000000000000000000000000000000000000000000000000000000612574565b955061215e8683612fcd565b915085600860008282546121729190612fb5565b90915550505b6121828286611289565b965061218e8786612581565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152602482018390529199507f0000000000000000000000000000000000000000000000000000000000000000909116906340c10f1990604401600060405180830381600087803b15801561222357600080fd5b505af1158015612237573d6000803e3d6000fd5b50506040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152602482018c90527f00000000000000000000000000000000000000000000000000000000000000001692506340c10f199150604401600060405180830381600087803b1580156122cb57600080fd5b505af11580156122df573d6000803e3d6000fd5b505050505050505092959194509250565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261115b9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612b4b565b600082600160006123d36129d2565b6040517ef714ce0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff87811660248301529192507f00000000000000000000000000000000000000000000000000000000000000009091169062f714ce906044016020604051808303816000875af115801561246b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248f9190612f6d565b9350600061249b6129d2565b6124a59083612fcd565b905060008482116124bf576124ba8286612fcd565b6124c9565b6124c98583612fcd565b9050838111156124db576124db612f3e565b505050505092915050565b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008261256a8386612fe4565b6118619190613021565b60008161256a8486612fe4565b6000816125ae7f000000000000000000000000000000000000000000000000000000000000000085612fe4565b6112809190613021565b6000806000806125c785612c57565b90507f000000000000000000000000000000000000000000000000000000000000000081101561262d577f000000000000000000000000000000000000000000000000000000000000000061261c8289612fe4565b6126269190613021565b9250612798565b60006126597f000000000000000000000000000000000000000000000000000000000000000083612fcd565b905060006126a8827f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061255d565b905060006126d789837f0000000000000000000000000000000000000000000000000000000000000000612574565b90506126e3818b612fb5565b95506126ed610b1e565b80156126f857508388115b15612794576000612709858a612fcd565b9050600061278361275b837f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612574565b8c907f0000000000000000000000000000000000000000000000000000000000000000612574565b905061278f818b611253565b965050505b5050505b6127a28386611253565b935060006127ae610b1e565b6127ba576006546127be565b6007545b9050801561281b5760006127f386837f0000000000000000000000000000000000000000000000000000000000000000612574565b90506127ff8187612fcd565b955061280b8185612fb5565b93506128178688611289565b9450505b5093509350935093565b60006112837f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000611e9585612c57565b600080612880610b1e565b156128b257506001927f0000000000000000000000000000000000000000000000000000000000000000909210919050565b7f000000000000000000000000000000000000000000000000000000000000000083106128e85750506000600981905591829150565b6009546128fe5750504260095550600090600190565b4262093a806009546129109190612fb5565b116129385742600355612921610b1e565b61292d5761292d612f3e565b506001928392509050565b50600092600192509050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a08231906024015b602060405180830381865afa1580156113e1573d6000803e3d6000fd5b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a08231906024016129b5565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015612abe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae29190612f6d565b612aec9190612fb5565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260448101829052909150612b459085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401612342565b50505050565b6000612bad826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612c8d9092919063ffffffff16565b80519091501561115b5780806020019051810190612bcb919061305c565b61115b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ab6565b6000612c61610b1e565b8015612c6e575060045415155b15612c84576004548210612c8457600454611283565b5090565b919050565b6060611861848460008585843b612d00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ab6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612d2991906130a5565b60006040518083038185875af1925050503d8060008114612d66576040519150601f19603f3d011682016040523d82523d6000602084013e612d6b565b606091505b5091509150612d7b828286612d86565b979650505050505050565b60608315612d9557508161136d565b825115612da55782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab691906130c1565b803573ffffffffffffffffffffffffffffffffffffffff81168114612c8857600080fd5b60008060008060808587031215612e1357600080fd5b612e1c85612dd9565b93506020850135925060408501359150612e3860608601612dd9565b905092959194509250565b60008060408385031215612e5657600080fd5b82359150612e6660208401612dd9565b90509250929050565b600060208284031215612e8157600080fd5b61128082612dd9565b600060608284031215612e9c57600080fd5b50919050565b60008060408385031215612eb557600080fd5b50508035926020909101359150565b8015158114612ed257600080fd5b50565b60008060408385031215612ee857600080fd5b823591506020830135612efa81612ec4565b809150509250929050565b600080600060608486031215612f1a57600080fd5b83359250602084013591506040840135612f3381612ec4565b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600060208284031215612f7f57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612fc857612fc8612f86565b500190565b600082821015612fdf57612fdf612f86565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561301c5761301c612f86565b500290565b600082613057577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561306e57600080fd5b815161136d81612ec4565b60005b8381101561309457818101518382015260200161307c565b83811115612b455750506000910152565b600082516130b7818460208701613079565b9190910192915050565b60208152600082518060208401526130e0816040850160208701613079565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212207c606cc259dd4c350ef1c5e4250b86620e3a91dbad3e9bf85924fbd9e362409c64736f6c634300080a00336101006040523480156200001257600080fd5b50604051620017483803806200174883398101604081905262000035916200023b565b60008484848482828181816003908051906020019062000057929190620000c8565b5080516200006d906004906020840190620000c8565b505033608052508691505060018111156200008c576200008c620002df565b60a0816001811115620000a357620000a3620002df565b9052506001600160a01b0390931660c052505060ff1660e05250620003329350505050565b828054620000d690620002f5565b90600052602060002090601f016020900481019282620000fa576000855562000145565b82601f106200011557805160ff191683800117855562000145565b8280016001018555821562000145579182015b828111156200014557825182559160200191906001019062000128565b506200015392915062000157565b5090565b5b8082111562000153576000815560010162000158565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200019657600080fd5b81516001600160401b0380821115620001b357620001b36200016e565b604051601f8301601f19908116603f01168101908282118183101715620001de57620001de6200016e565b81604052838152602092508683858801011115620001fb57600080fd5b600091505b838210156200021f578582018301518183018401529082019062000200565b83821115620002315760008385830101525b9695505050505050565b600080600080608085870312156200025257600080fd5b84516001600160a01b03811681146200026a57600080fd5b60208601519094506001600160401b03808211156200028857600080fd5b620002968883890162000184565b94506040870151915080821115620002ad57600080fd5b50620002bc8782880162000184565b925050606085015160ff81168114620002d457600080fd5b939692955090935050565b634e487b7160e01b600052602160045260246000fd5b600181811c908216806200030a57607f821691505b602082108114156200032c57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e0516113b26200039660003960006102430152600081816101d0015281816106f501526108360152600061015b0152600081816102ad015281816105900152818161063d015281816106c901526107a101526113b26000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c806342966c68116100cd578063946731d011610081578063a457c2d711610066578063a457c2d714610330578063a9059cbb14610343578063dd62ed3e1461035657600080fd5b8063946731d01461032057806395d89b411461032857600080fd5b806370a08231116100b257806370a08231146102cf57806377c7b8fc1461030557806379cc67901461030d57600080fd5b806342966c6814610295578063481c6a75146102a857600080fd5b806318160ddd11610124578063313ce56711610109578063313ce5671461023c578063395093511461026d57806340c10f191461028057600080fd5b806318160ddd1461021757806323b872dd1461022957600080fd5b806304baa00b1461015657806306fdde0314610193578063095ea7b3146101a857806316f0115b146101cb575b600080fd5b61017d7f000000000000000000000000000000000000000000000000000000000000000081565b60405161018a9190611100565b60405180910390f35b61019b61039c565b60405161018a9190611141565b6101bb6101b63660046111dd565b61042e565b604051901515815260200161018a565b6101f27f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018a565b6002545b60405190815260200161018a565b6101bb610237366004611207565b610444565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161018a565b6101bb61027b3660046111dd565b61052f565b61029361028e3660046111dd565b610578565b005b6102936102a3366004611243565b610625565b6101f27f000000000000000000000000000000000000000000000000000000000000000081565b61021b6102dd36600461125c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61021b6106f1565b61029361031b3660046111dd565b610789565b61021b610832565b61019b61089f565b6101bb61033e3660046111dd565b6108ae565b6101bb6103513660046111dd565b610986565b61021b61036436600461127e565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6060600380546103ab906112b1565b80601f01602080910402602001604051908101604052809291908181526020018280546103d7906112b1565b80156104245780601f106103f957610100808354040283529160200191610424565b820191906000526020600020905b81548152906001019060200180831161040757829003601f168201915b5050505050905090565b600061043b338484610993565b50600192915050565b6000610451848484610b47565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482811015610517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6105248533858403610993565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161043b918590610573908690611334565b610993565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610617576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f6d696e743a206f6e6c79206d616e616765722063616e206d696e740000000000604482015260640161050e565b6106218282610dfb565b5050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f6275726e3a206f6e6c79206d616e616765722063616e206275726e0000000000604482015260640161050e565b6106ee7f000000000000000000000000000000000000000000000000000000000000000082610f1b565b50565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b468d2446040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610760573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610784919061134c565b905090565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610828576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f6275726e3a206f6e6c79206d616e616765722063616e206275726e0000000000604482015260640161050e565b6106218282610f1b565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632675323d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610760573d6000803e3d6000fd5b6060600480546103ab906112b1565b33600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120548281101561096f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161050e565b61097c3385858403610993565b5060019392505050565b600061043b338484610b47565b73ffffffffffffffffffffffffffffffffffffffff8316610a35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff8216610ad8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316610bea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff8216610c8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610d87908490611334565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610ded91815260200190565b60405180910390a350505050565b73ffffffffffffffffffffffffffffffffffffffff8216610e78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161050e565b8060026000828254610e8a9190611334565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610ec4908490611334565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610fbe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611074576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906110b0908490611365565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b3a565b602081016002831061113b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b600060208083528351808285015260005b8181101561116e57858101830151858201604001528201611152565b81811115611180576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146111d857600080fd5b919050565b600080604083850312156111f057600080fd5b6111f9836111b4565b946020939093013593505050565b60008060006060848603121561121c57600080fd5b611225846111b4565b9250611233602085016111b4565b9150604084013590509250925092565b60006020828403121561125557600080fd5b5035919050565b60006020828403121561126e57600080fd5b611277826111b4565b9392505050565b6000806040838503121561129157600080fd5b61129a836111b4565b91506112a8602084016111b4565b90509250929050565b600181811c908216806112c557607f821691505b602082108114156112ff577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561134757611347611305565b500190565b60006020828403121561135e57600080fd5b5051919050565b60008282101561137757611377611305565b50039056fea26469706673582212205da7605b1eb77e176834b8c6d409ca5ff6c554096b393edcfb1d126c1f13b63364736f6c634300080a00336101006040523480156200001257600080fd5b50604051620017483803806200174883398101604081905262000035916200023b565b60018484848482828181816003908051906020019062000057929190620000c8565b5080516200006d906004906020840190620000c8565b505033608052508691505060018111156200008c576200008c620002df565b60a0816001811115620000a357620000a3620002df565b9052506001600160a01b0390931660c052505060ff1660e05250620003329350505050565b828054620000d690620002f5565b90600052602060002090601f016020900481019282620000fa576000855562000145565b82601f106200011557805160ff191683800117855562000145565b8280016001018555821562000145579182015b828111156200014557825182559160200191906001019062000128565b506200015392915062000157565b5090565b5b8082111562000153576000815560010162000158565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200019657600080fd5b81516001600160401b0380821115620001b357620001b36200016e565b604051601f8301601f19908116603f01168101908282118183101715620001de57620001de6200016e565b81604052838152602092508683858801011115620001fb57600080fd5b600091505b838210156200021f578582018301518183018401529082019062000200565b83821115620002315760008385830101525b9695505050505050565b600080600080608085870312156200025257600080fd5b84516001600160a01b03811681146200026a57600080fd5b60208601519094506001600160401b03808211156200028857600080fd5b620002968883890162000184565b94506040870151915080821115620002ad57600080fd5b50620002bc8782880162000184565b925050606085015160ff81168114620002d457600080fd5b939692955090935050565b634e487b7160e01b600052602160045260246000fd5b600181811c908216806200030a57607f821691505b602082108114156200032c57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e0516113b26200039660003960006102430152600081816101d0015281816106f501526108360152600061015b0152600081816102ad015281816105900152818161063d015281816106c901526107a101526113b26000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c806342966c68116100cd578063946731d011610081578063a457c2d711610066578063a457c2d714610330578063a9059cbb14610343578063dd62ed3e1461035657600080fd5b8063946731d01461032057806395d89b411461032857600080fd5b806370a08231116100b257806370a08231146102cf57806377c7b8fc1461030557806379cc67901461030d57600080fd5b806342966c6814610295578063481c6a75146102a857600080fd5b806318160ddd11610124578063313ce56711610109578063313ce5671461023c578063395093511461026d57806340c10f191461028057600080fd5b806318160ddd1461021757806323b872dd1461022957600080fd5b806304baa00b1461015657806306fdde0314610193578063095ea7b3146101a857806316f0115b146101cb575b600080fd5b61017d7f000000000000000000000000000000000000000000000000000000000000000081565b60405161018a9190611100565b60405180910390f35b61019b61039c565b60405161018a9190611141565b6101bb6101b63660046111dd565b61042e565b604051901515815260200161018a565b6101f27f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018a565b6002545b60405190815260200161018a565b6101bb610237366004611207565b610444565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161018a565b6101bb61027b3660046111dd565b61052f565b61029361028e3660046111dd565b610578565b005b6102936102a3366004611243565b610625565b6101f27f000000000000000000000000000000000000000000000000000000000000000081565b61021b6102dd36600461125c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61021b6106f1565b61029361031b3660046111dd565b610789565b61021b610832565b61019b61089f565b6101bb61033e3660046111dd565b6108ae565b6101bb6103513660046111dd565b610986565b61021b61036436600461127e565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6060600380546103ab906112b1565b80601f01602080910402602001604051908101604052809291908181526020018280546103d7906112b1565b80156104245780601f106103f957610100808354040283529160200191610424565b820191906000526020600020905b81548152906001019060200180831161040757829003601f168201915b5050505050905090565b600061043b338484610993565b50600192915050565b6000610451848484610b47565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482811015610517576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6105248533858403610993565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161043b918590610573908690611334565b610993565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610617576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f6d696e743a206f6e6c79206d616e616765722063616e206d696e740000000000604482015260640161050e565b6106218282610dfb565b5050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146106c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f6275726e3a206f6e6c79206d616e616765722063616e206275726e0000000000604482015260640161050e565b6106ee7f000000000000000000000000000000000000000000000000000000000000000082610f1b565b50565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634e18f3246040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610760573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610784919061134c565b905090565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610828576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f6275726e3a206f6e6c79206d616e616765722063616e206275726e0000000000604482015260640161050e565b6106218282610f1b565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634570452a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610760573d6000803e3d6000fd5b6060600480546103ab906112b1565b33600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120548281101561096f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161050e565b61097c3385858403610993565b5060019392505050565b600061043b338484610b47565b73ffffffffffffffffffffffffffffffffffffffff8316610a35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff8216610ad8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316610bea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff8216610c8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610d87908490611334565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610ded91815260200190565b60405180910390a350505050565b73ffffffffffffffffffffffffffffffffffffffff8216610e78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161050e565b8060026000828254610e8a9190611334565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610ec4908490611334565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610fbe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611074576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081208383039055600280548492906110b0908490611365565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610b3a565b602081016002831061113b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b600060208083528351808285015260005b8181101561116e57858101830151858201604001528201611152565b81811115611180576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146111d857600080fd5b919050565b600080604083850312156111f057600080fd5b6111f9836111b4565b946020939093013593505050565b60008060006060848603121561121c57600080fd5b611225846111b4565b9250611233602085016111b4565b9150604084013590509250925092565b60006020828403121561125557600080fd5b5035919050565b60006020828403121561126e57600080fd5b611277826111b4565b9392505050565b6000806040838503121561129157600080fd5b61129a836111b4565b91506112a8602084016111b4565b90509250929050565b600181811c908216806112c557607f821691505b602082108114156112ff577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561134757611347611305565b500190565b60006020828403121561135e57600080fd5b5051919050565b60008282101561137757611377611305565b50039056fea2646970667358221220e13cc8729dc0df3311f93dcc79e4a597aba4509dca14a89508cfb35c4024457364736f6c634300080a0033000000000000000000000000148c05caf1bb09b5670f00d511718f733c54bc4c0000000000000000000000008c47924b35c3667f59df579f3ec061f8d76032420000000000000000000000000000000000000000000000000000000062e39380000000000000000000000000000000000000000000000000000000000000846c000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001d54656d707573204361706974616c20546f6b656e2d46594555543030330000000000000000000000000000000000000000000000000000000000000000000011744361706974616c2d465945555430303300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001b54656d707573205969656c6420546f6b656e2d46594555543030330000000000000000000000000000000000000000000000000000000000000000000000000f745969656c642d46594555543030330000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102d15760003560e01c806378e9792511610179578063b468d244116100d6578063e567e8691161008a578063f2fde38b11610064578063f2fde38b14610978578063f77c479114610998578063ff4c7e31146108c557600080fd5b8063e567e8691461090e578063e8a8cf6514610942578063e9c5ce281461096257600080fd5b8063ca9d2d55116100bb578063ca9d2d55146108a5578063ce76756f146108c5578063e34c4b6a146108da57600080fd5b8063b468d2441461034a578063c56c7a851461087157600080fd5b80638da5cb5b1161012d5780639d27d5fc116101125780639d27d5fc146107e6578063a8d1dbfb14610806578063af6934171461083a57600080fd5b80638da5cb5b1461079b578063960c6917146107c657600080fd5b806379ba50971161015e57806379ba5097146107325780638088e121146107475780638a425ea91461077b57600080fd5b806378e97925146106de57806378ec24ee1461071257600080fd5b806347e621b7116102325780634e289bdf116101e657806363dc4ef5116101c057806363dc4ef5146106775780636c8d4fa114610697578063757881fd146106aa57600080fd5b80634e289bdf146105475780634e8bfdaa1461055d57806354fd4d501461059157600080fd5b80634b009e06116102175780634b009e06146104fd5780634bb278f3146105305780634e18f3241461048057600080fd5b806347e621b71461049557806349d088c3146104c957600080fd5b80632d81f8381161028957806343bcfab61161026e57806343bcfab614610420578063454c87b31461045b5780634570452a1461048057600080fd5b80632d81f8381461039357806335083643146103ec57600080fd5b80632208ebbd116102ba5780632208ebbd146103165780632675323d1461034a5780632b532a971461035f57600080fd5b806313114a9d146102d65780631f796f7f146102ff575b600080fd5b3480156102e257600080fd5b506102ec60085481565b6040519081526020015b60405180910390f35b34801561030b57600080fd5b506102ec62093a8081565b34801561032257600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000271081565b34801561035657600080fd5b506102ec6109cc565b34801561036b57600080fd5b506102ec7f00000000000000000000000000000000000000000000000000000000000f424081565b34801561039f57600080fd5b506103c77f000000000000000000000000148c05caf1bb09b5670f00d511718f733c54bc4c81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f6565b3480156103f857600080fd5b506103c77f00000000000000000000000073f5e4465946d03045cdc78d6028b53a0745babb81565b34801561042c57600080fd5b5061044061043b366004612dfd565b6109f1565b604080519384526020840192909252908201526060016102f6565b34801561046757600080fd5b50610470610b1e565b60405190151581526020016102f6565b34801561048c57600080fd5b506102ec610b56565b3480156104a157600080fd5b506103c77f000000000000000000000000049d68029688eabf473097a2fc38ef61633a3c7a81565b3480156104d557600080fd5b506102ec7f00000000000000000000000000000000000000000000000000000000000f424081565b61051061050b366004612e43565b610b75565b6040805194855260208501939093529183015260608201526080016102f6565b34801561053c57600080fd5b50610545610c83565b005b34801561055357600080fd5b506102ec60035481565b34801561056957600080fd5b506102ec7f0000000000000000000000000000000000000000000000000000000062e3938081565b34801561059d57600080fd5b5061064a604080516060810182526000808252602082018190529181019190915260405180606001604052807f000000000000000000000000000000000000000000000000000000000000000161ffff1681526020017f000000000000000000000000000000000000000000000000000000000000000061ffff1681526020017f000000000000000000000000000000000000000000000000000000000000000061ffff16815250905090565b60408051825161ffff908116825260208085015182169083015292820151909216908201526060016102f6565b34801561068357600080fd5b50610545610692366004612e6f565b610caa565b6105106106a5366004612dfd565b610e0e565b3480156106b657600080fd5b506102ec7f00000000000000000000000000000000000000000000000000000000000f424081565b3480156106ea57600080fd5b506102ec7f0000000000000000000000000000000000000000000000000000000062042d7a81565b34801561071e57600080fd5b5061054561072d366004612e8a565b610f01565b34801561073e57600080fd5b50610545611160565b34801561075357600080fd5b506102ec7f00000000000000000000000000000000000000000000000000000000000f719681565b34801561078757600080fd5b506102ec610796366004612ea2565b611253565b3480156107a757600080fd5b5060015473ffffffffffffffffffffffffffffffffffffffff166103c7565b3480156107d257600080fd5b506102ec6107e1366004612ea2565b611289565b3480156107f257600080fd5b506102ec610801366004612ed5565b6112b6565b34801561081257600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000271081565b34801561084657600080fd5b5061084f6112f0565b60408051825181526020808401519082015291810151908201526060016102f6565b34801561087d57600080fd5b506103c77f0000000000000000000000009f6f78f2e1819c612a4ab98d73b75f2afa9ce3ad81565b3480156108b157600080fd5b506102ec6108c0366004612f05565b611339565b3480156108d157600080fd5b506102ec611374565b3480156108e657600080fd5b506102ec7f000000000000000000000000000000000000000000000000000000000000271081565b34801561091a57600080fd5b506102ec7f596561726e00000000000000000000000000000000000000000000000000000081565b34801561094e57600080fd5b5061051061095d366004612e43565b611405565b34801561096e57600080fd5b506102ec60045481565b34801561098457600080fd5b50610545610993366004612e6f565b6114f9565b3480156109a457600080fd5b506103c77f0000000000000000000000008c47924b35c3667f59df579f3ec061f8d760324281565b6000806109d76116b0565b90506109eb816109e6836116c2565b6117ff565b91505090565b600080803373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000008c47924b35c3667f59df579f3ec061f8d76032421614610abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f6e6c792063616c6c61626c652062792054656d707573436f6e74726f6c6c6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610aca878787611869565b91945092509050610b1273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000148c05caf1bb09b5670f00d511718f733c54bc4c168585611cee565b92509450945094915050565b60007f0000000000000000000000000000000000000000000000000000000062e3938042101580610b5157506003544210155b905090565b600080610b616116b0565b90506109eb81610b70836116c2565b611e43565b60008080803373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000008c47924b35c3667f59df579f3ec061f8d76032421614610c3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f6e6c792063616c6c61626c652062792054656d707573436f6e74726f6c6c6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610ab6565b60008611610c4f57610c4f612f3e565b610c5886611ea4565b925060008311610c6a57610c6a612f3e565b610c74838661202c565b92999598509650909450505050565b610c8b610b1e565b8015610c975750600454155b15610ca857610ca4611374565b6004555b565b60026000541415610d17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ab6565b600260005533610d3c60015473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614610db9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ab6565b6008805460009091557f000000000000000000000000148c05caf1bb09b5670f00d511718f733c54bc4c610e0473ffffffffffffffffffffffffffffffffffffffff821684846122f0565b5050600160005550565b60008080803373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000008c47924b35c3667f59df579f3ec061f8d76032421614610ed8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f6e6c792063616c6c61626c652062792054656d707573436f6e74726f6c6c6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610ab6565b610ee3888888611869565b91955092509050610ef484866123c4565b9250945094509450949050565b33610f2160015473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614610f9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ab6565b7f000000000000000000000000000000000000000000000000000000000000271081351115611029576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4465706f736974206665652070657263656e74203e206d6178000000000000006044820152606401610ab6565b7f0000000000000000000000000000000000000000000000000000000000002710816020013511156110b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4561726c792072656465656d206665652070657263656e74203e206d617800006044820152606401610ab6565b7f000000000000000000000000000000000000000000000000000000000000271081604001351115611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d61747572652072656465656d206665652070657263656e74203e206d6178006044820152606401610ab6565b8035600555602081013560065560400135600755565b505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314611207576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4f776e61626c653a204f6e6c792070726f706f736564206f776e65722063616e60448201527f20616363657074206f776e6572736869700000000000000000000000000000006064820152608401610ab6565b6002546112299073ffffffffffffffffffffffffffffffffffffffff166124e6565b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600061128083837f00000000000000000000000000000000000000000000000000000000000f424061255d565b90505b92915050565b600061128083837f00000000000000000000000000000000000000000000000000000000000f4240612574565b6000806112c1611374565b90506000836112d9576112d48583611289565b6112db565b845b90506112e78183612581565b95945050505050565b61131460405180606001604052806000815260200160008152602001600081525090565b5060408051606081018252600554815260065460208201526007549181019190915290565b600080611344611374565b90506000806113548787856125b8565b505091509150846113655781611367565b805b93505050505b9392505050565b60007f000000000000000000000000148c05caf1bb09b5670f00d511718f733c54bc4c73ffffffffffffffffffffffffffffffffffffffff166399530b066040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b519190612f6d565b60008080803373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000008c47924b35c3667f59df579f3ec061f8d760324216146114cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f6e6c792063616c6c61626c652062792054656d707573436f6e74726f6c6c6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610ab6565b600086116114df576114df612f3e565b6114e9868661202c565b9299919850965090945092505050565b3361151960015473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614611596576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ab6565b73ffffffffffffffffffffffffffffffffffffffff8116611639576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610ab6565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600154604051919216907fb51454ce8c7f26becd312a46c4815553887f2ec876a0b8dc813b87f62edf6f8090600090a350565b6000610b516116bd611374565b612825565b60006116cc610b1e565b156116d5575090565b426000807f0000000000000000000000000000000000000000000000000000000062e39380831061170757600061172b565b827f0000000000000000000000000000000000000000000000000000000062e39380035b9150507f0000000000000000000000000000000000000000000000000000000062042d7a7f0000000000000000000000000000000000000000000000000000000062e3938003600061179e83837f00000000000000000000000000000000000000000000000000000000000f424061255d565b90506117eb817f000000000000000000000000000000000000000000000000000000000000846c7f00000000000000000000000000000000000000000000000000000000000f4240612574565b6117f59087612fb5565b9695505050505050565b60007f00000000000000000000000000000000000000000000000000000000000f4240821015611830575081611283565b600061185d84847f00000000000000000000000000000000000000000000000000000000000f424061255d565b9050805b949350505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526000918291829186917f00000000000000000000000073f5e4465946d03045cdc78d6028b53a0745babb16906370a0823190602401602060405180830381865afa1580156118fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119229190612f6d565b101561198a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e73756666696369656e74207072696e636970616c732e00000000000000006044820152606401610ab6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015285917f0000000000000000000000009f6f78f2e1819c612a4ab98d73b75f2afa9ce3ad909116906370a0823190602401602060405180830381865afa158015611a1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a3e9190612f6d565b1015611aa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e73756666696369656e74207969656c64732e0000000000000000000000006044820152606401610ab6565b6000611ab0611374565b90506000611abd82612875565b5090508015611ad357611ace610c83565b611b62565b858714611b62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f496e657175616c20726564656d7074696f6e206e6f7420616c6c6f776564206260448201527f65666f7265206d617475726974792e00000000000000000000000000000000006064820152608401610ab6565b6040517f79cc679000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8981166004830152602482018990527f00000000000000000000000073f5e4465946d03045cdc78d6028b53a0745babb16906379cc679090604401600060405180830381600087803b158015611bf257600080fd5b505af1158015611c06573d6000803e3d6000fd5b50506040517f79cc679000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152602482018a90527f0000000000000000000000009f6f78f2e1819c612a4ab98d73b75f2afa9ce3ad1692506379cc67909150604401600060405180830381600087803b158015611c9a57600080fd5b505af1158015611cae573d6000803e3d6000fd5b50505050611cbd8787846125b8565b6008805494995091975095508692909150600090611cdc908490612fb5565b92505081905550505093509350939050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015260009182918616906370a0823190602401602060405180830381865afa158015611d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d839190612f6d565b9050611da673ffffffffffffffffffffffffffffffffffffffff861685856122f0565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528291908716906370a0823190602401602060405180830381865afa158015611e15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e399190612f6d565b6112e79190612fcd565b60007f00000000000000000000000000000000000000000000000000000000000f424080831015611e78576000915050611283565b6000611e9c8483611e958882611e8e8186612fcd565b9190612574565b919061255d565b9050806112e7565b6000816000611eb1612944565b90503415611ec157611ec1612f3e565b6000611ecb6129d2565b9050611f2e73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000049d68029688eabf473097a2fc38ef61633a3c7a167f000000000000000000000000148c05caf1bb09b5670f00d511718f733c54bc4c87612a47565b6040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690527f000000000000000000000000148c05caf1bb09b5670f00d511718f733c54bc4c73ffffffffffffffffffffffffffffffffffffffff169063b6b55f25906024016020604051808303816000875af1158015611fbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fdf9190612f6d565b5080611fe96129d2565b611ff39190612fcd565b9350506000612000612944565b61200a9083612fcd565b6120149084612fcd565b9050801561202457612024612f3e565b505050919050565b60008060008061203a611374565b905060008061204883612875565b9150915081156120b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4d6174757269747920726561636865642e0000000000000000000000000000006044820152606401610ab6565b801561211c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4e65676174697665207969656c642100000000000000000000000000000000006044820152606401610ab6565b600554889080156121785761215282827f00000000000000000000000000000000000000000000000000000000000f4240612574565b955061215e8683612fcd565b915085600860008282546121729190612fb5565b90915550505b6121828286611289565b965061218e8786612581565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152602482018390529199507f00000000000000000000000073f5e4465946d03045cdc78d6028b53a0745babb909116906340c10f1990604401600060405180830381600087803b15801561222357600080fd5b505af1158015612237573d6000803e3d6000fd5b50506040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152602482018c90527f0000000000000000000000009f6f78f2e1819c612a4ab98d73b75f2afa9ce3ad1692506340c10f199150604401600060405180830381600087803b1580156122cb57600080fd5b505af11580156122df573d6000803e3d6000fd5b505050505050505092959194509250565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261115b9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612b4b565b600082600160006123d36129d2565b6040517ef714ce0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff87811660248301529192507f000000000000000000000000148c05caf1bb09b5670f00d511718f733c54bc4c9091169062f714ce906044016020604051808303816000875af115801561246b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248f9190612f6d565b9350600061249b6129d2565b6124a59083612fcd565b905060008482116124bf576124ba8286612fcd565b6124c9565b6124c98583612fcd565b9050838111156124db576124db612f3e565b505050505092915050565b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008261256a8386612fe4565b6118619190613021565b60008161256a8486612fe4565b6000816125ae7f00000000000000000000000000000000000000000000000000000000000f719685612fe4565b6112809190613021565b6000806000806125c785612c57565b90507f00000000000000000000000000000000000000000000000000000000000f719681101561262d577f00000000000000000000000000000000000000000000000000000000000f719661261c8289612fe4565b6126269190613021565b9250612798565b60006126597f00000000000000000000000000000000000000000000000000000000000f719683612fcd565b905060006126a8827f00000000000000000000000000000000000000000000000000000000000f71967f00000000000000000000000000000000000000000000000000000000000f424061255d565b905060006126d789837f00000000000000000000000000000000000000000000000000000000000f4240612574565b90506126e3818b612fb5565b95506126ed610b1e565b80156126f857508388115b15612794576000612709858a612fcd565b9050600061278361275b837f00000000000000000000000000000000000000000000000000000000000f71967f00000000000000000000000000000000000000000000000000000000000f4240612574565b8c907f00000000000000000000000000000000000000000000000000000000000f4240612574565b905061278f818b611253565b965050505b5050505b6127a28386611253565b935060006127ae610b1e565b6127ba576006546127be565b6007545b9050801561281b5760006127f386837f00000000000000000000000000000000000000000000000000000000000f4240612574565b90506127ff8187612fcd565b955061280b8185612fb5565b93506128178688611289565b9450505b5093509350935093565b60006112837f00000000000000000000000000000000000000000000000000000000000f71967f00000000000000000000000000000000000000000000000000000000000f4240611e9585612c57565b600080612880610b1e565b156128b257506001927f00000000000000000000000000000000000000000000000000000000000f7196909210919050565b7f00000000000000000000000000000000000000000000000000000000000f719683106128e85750506000600981905591829150565b6009546128fe5750504260095550600090600190565b4262093a806009546129109190612fb5565b116129385742600355612921610b1e565b61292d5761292d612f3e565b506001928392509050565b50600092600192509050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000049d68029688eabf473097a2fc38ef61633a3c7a73ffffffffffffffffffffffffffffffffffffffff16906370a08231906024015b602060405180830381865afa1580156113e1573d6000803e3d6000fd5b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000148c05caf1bb09b5670f00d511718f733c54bc4c73ffffffffffffffffffffffffffffffffffffffff16906370a08231906024016129b5565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015612abe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ae29190612f6d565b612aec9190612fb5565b60405173ffffffffffffffffffffffffffffffffffffffff8516602482015260448101829052909150612b459085907f095ea7b30000000000000000000000000000000000000000000000000000000090606401612342565b50505050565b6000612bad826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612c8d9092919063ffffffff16565b80519091501561115b5780806020019051810190612bcb919061305c565b61115b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610ab6565b6000612c61610b1e565b8015612c6e575060045415155b15612c84576004548210612c8457600454611283565b5090565b919050565b6060611861848460008585843b612d00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ab6565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612d2991906130a5565b60006040518083038185875af1925050503d8060008114612d66576040519150601f19603f3d011682016040523d82523d6000602084013e612d6b565b606091505b5091509150612d7b828286612d86565b979650505050505050565b60608315612d9557508161136d565b825115612da55782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab691906130c1565b803573ffffffffffffffffffffffffffffffffffffffff81168114612c8857600080fd5b60008060008060808587031215612e1357600080fd5b612e1c85612dd9565b93506020850135925060408501359150612e3860608601612dd9565b905092959194509250565b60008060408385031215612e5657600080fd5b82359150612e6660208401612dd9565b90509250929050565b600060208284031215612e8157600080fd5b61128082612dd9565b600060608284031215612e9c57600080fd5b50919050565b60008060408385031215612eb557600080fd5b50508035926020909101359150565b8015158114612ed257600080fd5b50565b60008060408385031215612ee857600080fd5b823591506020830135612efa81612ec4565b809150509250929050565b600080600060608486031215612f1a57600080fd5b83359250602084013591506040840135612f3381612ec4565b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600060208284031215612f7f57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612fc857612fc8612f86565b500190565b600082821015612fdf57612fdf612f86565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561301c5761301c612f86565b500290565b600082613057577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561306e57600080fd5b815161136d81612ec4565b60005b8381101561309457818101518382015260200161307c565b83811115612b455750506000910152565b600082516130b7818460208701613079565b9190910192915050565b60208152600082518060208401526130e0816040850160208701613079565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea26469706673582212207c606cc259dd4c350ef1c5e4250b86620e3a91dbad3e9bf85924fbd9e362409c64736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000148c05caf1bb09b5670f00d511718f733c54bc4c0000000000000000000000008c47924b35c3667f59df579f3ec061f8d76032420000000000000000000000000000000000000000000000000000000062e39380000000000000000000000000000000000000000000000000000000000000846c000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001d54656d707573204361706974616c20546f6b656e2d46594555543030330000000000000000000000000000000000000000000000000000000000000000000011744361706974616c2d465945555430303300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001b54656d707573205969656c6420546f6b656e2d46594555543030330000000000000000000000000000000000000000000000000000000000000000000000000f745969656c642d46594555543030330000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : vault (address): 0x148c05caf1Bb09B5670f00D511718f733C54bC4c
Arg [1] : controller (address): 0x8c47924b35C3667F59Df579F3ec061F8d7603242
Arg [2] : maturity (uint256): 1659081600
Arg [3] : estYield (uint256): 33900
Arg [4] : principalsData (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [5] : yieldsData (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [6] : maxFeeSetup (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
21 Constructor Arguments found :
Arg [0] : 000000000000000000000000148c05caf1bb09b5670f00d511718f733c54bc4c
Arg [1] : 0000000000000000000000008c47924b35c3667f59df579f3ec061f8d7603242
Arg [2] : 0000000000000000000000000000000000000000000000000000000062e39380
Arg [3] : 000000000000000000000000000000000000000000000000000000000000846c
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [5] : 00000000000000000000000000000000000000000000000000000000000001e0
Arg [6] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [7] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [8] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [11] : 000000000000000000000000000000000000000000000000000000000000001d
Arg [12] : 54656d707573204361706974616c20546f6b656e2d4659455554303033000000
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000011
Arg [14] : 744361706974616c2d4659455554303033000000000000000000000000000000
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [17] : 000000000000000000000000000000000000000000000000000000000000001b
Arg [18] : 54656d707573205969656c6420546f6b656e2d46594555543030330000000000
Arg [19] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [20] : 745969656c642d46594555543030330000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.