Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 5,542 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Remove Market Li... | 21697624 | 5 days ago | IN | 0 ETH | 0.00354033 | ||||
Remove Market Li... | 21465646 | 37 days ago | IN | 0 ETH | 0.00927351 | ||||
Remove Market Li... | 21465628 | 37 days ago | IN | 0 ETH | 0.00210207 | ||||
Redeem After Exp... | 21460723 | 38 days ago | IN | 0 ETH | 0.00092402 | ||||
Remove Market Li... | 21460700 | 38 days ago | IN | 0 ETH | 0.00388115 | ||||
Redeem After Exp... | 20570230 | 162 days ago | IN | 0 ETH | 0.00070483 | ||||
Swap Exact In | 20285227 | 202 days ago | IN | 0 ETH | 0.00030828 | ||||
Redeem After Exp... | 20284215 | 202 days ago | IN | 0 ETH | 0.00223391 | ||||
Remove Market Li... | 20251323 | 207 days ago | IN | 0 ETH | 0.000875 | ||||
Redeem After Exp... | 20251304 | 207 days ago | IN | 0 ETH | 0.00019456 | ||||
Remove Market Li... | 20216908 | 212 days ago | IN | 0 ETH | 0.00131071 | ||||
Remove Market Li... | 20133813 | 223 days ago | IN | 0 ETH | 0.00579019 | ||||
Redeem After Exp... | 20133801 | 223 days ago | IN | 0 ETH | 0.00161347 | ||||
Redeem After Exp... | 19927805 | 252 days ago | IN | 0 ETH | 0.00571829 | ||||
Remove Market Li... | 19801057 | 270 days ago | IN | 0 ETH | 0.002248 | ||||
Remove Market Li... | 19744908 | 278 days ago | IN | 0 ETH | 0.00265001 | ||||
Redeem After Exp... | 19600835 | 298 days ago | IN | 0 ETH | 0.00386542 | ||||
Redeem After Exp... | 19556046 | 304 days ago | IN | 0 ETH | 0.00365775 | ||||
Redeem After Exp... | 19488055 | 314 days ago | IN | 0 ETH | 0.00389618 | ||||
Redeem After Exp... | 19286118 | 342 days ago | IN | 0 ETH | 0.01011971 | ||||
Remove Market Li... | 19282188 | 342 days ago | IN | 0 ETH | 0.01658688 | ||||
Remove Market Li... | 19262587 | 345 days ago | IN | 0 ETH | 0.02554046 | ||||
Redeem After Exp... | 19262554 | 345 days ago | IN | 0 ETH | 0.01613169 | ||||
Remove Market Li... | 19247420 | 347 days ago | IN | 0 ETH | 0.0089188 | ||||
Remove Market Li... | 19210530 | 352 days ago | IN | 0 ETH | 0.01176888 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
PendleRouter
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; pragma abicoder v2; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "../libraries/MathLib.sol"; import "../interfaces/IPendleRouter.sol"; import "../interfaces/IPendleData.sol"; import "../interfaces/IPendleForge.sol"; import "../interfaces/IPendleMarketFactory.sol"; import "../interfaces/IPendleMarket.sol"; import "../periphery/PermissionsV2.sol"; import "../periphery/WithdrawableV2.sol"; import "../periphery/PendleRouterNonReentrant.sol"; /** @dev OVERALL NOTE: * The router will not hold any funds, instead it will just help sending funds to other contracts & users * addLiquidity/removeLiquidity/swap all supports auto wrap of ETH - There will be no markets of XYT-ETH, only markets of XYT-WETH - If users want to send in / receive ETH, just pass the ETH_ADDRESS to the corresponding field, the router will automatically wrap/unwrap WETH and interact with markets - principle of ETH wrap implementation: always use the token with the "original" prefix for transfer, and use the non-original token (_xyt, _token...) in all other cases * Markets will not transfer any XYT/baseToken, but instead make requests to Router through the transfer array and the Router will transfer them */ contract PendleRouter is IPendleRouter, WithdrawableV2, PendleRouterNonReentrant { using SafeERC20 for IERC20; using SafeMath for uint256; using Math for uint256; IWETH public immutable override weth; IPendleData public immutable override data; address private constant ETH_ADDRESS = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); // if someone's allowance for the router is below this amount, // we will approve the router again (to spend from their account) // if we already call .approveRouter for the a token, we shouldn't need to approve again uint256 private constant REASONABLE_ALLOWANCE_AMOUNT = type(uint256).max / 2; constructor( address _governanceManager, IWETH _weth, IPendleData _data ) PermissionsV2(_governanceManager) PendleRouterNonReentrant() { weth = _weth; data = _data; } /** * @dev Accepts ETH via fallback from the WETH contract. **/ receive() external payable { require(msg.sender == address(weth), "ETH_NOT_FROM_WETH"); } /** * @notice Create a new pair of OT + XYT tokens to represent the * principal and interest for an underlying asset, until an expiry Conditions: * _expiry must be divisible for expiryDivisor() so that there are not too many yieldContracts * Any _underlyingAsset can be passed in, since there is no way to validate them * Have Reentrancy protection **/ function newYieldContracts( bytes32 _forgeId, address _underlyingAsset, uint256 _expiry ) external override nonReentrant returns (address ot, address xyt) { require(_underlyingAsset != address(0), "ZERO_ADDRESS"); require(_expiry > block.timestamp, "INVALID_EXPIRY"); require(_expiry % data.expiryDivisor() == 0, "INVALID_EXPIRY"); IPendleForge forge = IPendleForge(data.getForgeAddress(_forgeId)); require(address(forge) != address(0), "FORGE_NOT_EXISTS"); ot = address(data.otTokens(_forgeId, _underlyingAsset, _expiry)); xyt = address(data.xytTokens(_forgeId, _underlyingAsset, _expiry)); require(ot == address(0) && xyt == address(0), "DUPLICATE_YIELD_CONTRACT"); (ot, xyt) = forge.newYieldContracts(_underlyingAsset, _expiry); } /** * @notice After an expiry, redeem OT tokens to get back the underlyingYieldToken * and also any interests * @notice This function acts as a proxy to the actual function * @dev The interest from "the last global action before expiry" until the expiry * is given to the OT holders. This is to simplify accounting. An assumption * is that the last global action before expiry will be close to the expiry * @dev all validity checks are in the internal function Conditions: * Have Reentrancy protection **/ function redeemAfterExpiry( bytes32 _forgeId, address _underlyingAsset, uint256 _expiry ) public override nonReentrant returns (uint256 redeemedAmount) { require(data.isValidXYT(_forgeId, _underlyingAsset, _expiry), "INVALID_YT"); require(_expiry < block.timestamp, "MUST_BE_AFTER_EXPIRY"); // guaranteed to be a valid forge by the isValidXYT check IPendleForge forge = IPendleForge(data.getForgeAddress(_forgeId)); redeemedAmount = forge.redeemAfterExpiry(msg.sender, _underlyingAsset, _expiry); } /** * @notice redeem the dueInterests from XYTs * @dev all validity checks are in the internal function Conditions: * Have Reentrancy protection **/ function redeemDueInterests( bytes32 _forgeId, address _underlyingAsset, uint256 _expiry, address _user ) external override nonReentrant returns (uint256 interests) { require(data.isValidXYT(_forgeId, _underlyingAsset, _expiry), "INVALID_YT"); require(_user != address(0), "ZERO_ADDRESS"); IPendleForge forge = IPendleForge(data.getForgeAddress(_forgeId)); interests = forge.redeemDueInterests(_user, _underlyingAsset, _expiry); } /** * @notice Before the expiry, a user can redeem the same amount of OT+XYT to get back * the underlying yield token Conditions: * Have Reentrancy protection **/ function redeemUnderlying( bytes32 _forgeId, address _underlyingAsset, uint256 _expiry, uint256 _amountToRedeem ) external override nonReentrant returns (uint256 redeemedAmount) { require(data.isValidXYT(_forgeId, _underlyingAsset, _expiry), "INVALID_YT"); require(block.timestamp < _expiry, "YIELD_CONTRACT_EXPIRED"); require(_amountToRedeem != 0, "ZERO_AMOUNT"); // guaranteed to be a valid forge by the isValidXYT check IPendleForge forge = IPendleForge(data.getForgeAddress(_forgeId)); redeemedAmount = forge.redeemUnderlying( msg.sender, _underlyingAsset, _expiry, _amountToRedeem ); } /** * @notice Use to renewYield. Basically a proxy to call redeemAfterExpiry & tokenizeYield * @param _renewalRate a Fixed Point number, shows how much of the total redeemedAmount is renewed. We allowed _renewalRate > RONE in case the user wants to increase his position Conditions: * No Reentrancy protection because it will just act as a proxy for 2 calls **/ function renewYield( bytes32 _forgeId, uint256 _oldExpiry, address _underlyingAsset, uint256 _newExpiry, uint256 _renewalRate ) external override returns ( uint256 redeemedAmount, uint256 amountRenewed, address ot, address xyt, uint256 amountTokenMinted ) { require(0 < _renewalRate, "INVALID_RENEWAL_RATE"); redeemedAmount = redeemAfterExpiry(_forgeId, _underlyingAsset, _oldExpiry); amountRenewed = redeemedAmount.rmul(_renewalRate); (ot, xyt, amountTokenMinted) = tokenizeYield( _forgeId, _underlyingAsset, _newExpiry, amountRenewed, msg.sender ); } /** * @notice tokenize yield tokens to get OT+XYT. We allows tokenizing for others too * @dev each forge is for a yield protocol (for example: Aave, Compound) Conditions: * Have Reentrancy protection * Can only tokenize to a not-yet-expired XYT **/ function tokenizeYield( bytes32 _forgeId, address _underlyingAsset, uint256 _expiry, uint256 _amountToTokenize, address _to ) public override nonReentrant returns ( address ot, address xyt, uint256 amountTokenMinted ) { require(data.isValidXYT(_forgeId, _underlyingAsset, _expiry), "INVALID_YT"); require(block.timestamp < _expiry, "YIELD_CONTRACT_EXPIRED"); require(_to != address(0), "ZERO_ADDRESS"); require(_amountToTokenize != 0, "ZERO_AMOUNT"); // guaranteed to be a valid forge by the isValidXYT check IPendleForge forge = IPendleForge(data.getForgeAddress(_forgeId)); // In this getYieldBearingToken call, the forge will check if there is // any yieldToken that matches the underlyingAsset. For more details please // check the getYieldBearingToken in forge IERC20 yieldToken = IERC20(forge.getYieldBearingToken(_underlyingAsset)); // pull tokens in yieldToken.safeTransferFrom( msg.sender, forge.yieldTokenHolders(_underlyingAsset, _expiry), _amountToTokenize ); // mint OT&XYT for users (ot, xyt, amountTokenMinted) = forge.mintOtAndXyt( _underlyingAsset, _expiry, _amountToTokenize, _to ); } /** * @notice add market liquidity by both xyt and baseToken Conditions: * Have Reentrancy protection */ function addMarketLiquidityDual( bytes32 _marketFactoryId, address _xyt, address _token, uint256 _desiredXytAmount, uint256 _desiredTokenAmount, uint256 _xytMinAmount, uint256 _tokenMinAmount ) public payable override nonReentrant returns ( uint256 amountXytUsed, uint256 amountTokenUsed, uint256 lpOut ) { require( _desiredXytAmount != 0 && _desiredXytAmount >= _xytMinAmount, "INVALID_YT_AMOUNTS" ); require( _desiredTokenAmount != 0 && _desiredTokenAmount >= _tokenMinAmount, "INVALID_TOKEN_AMOUNTS" ); address originalToken = _token; _token = _isETH(_token) ? address(weth) : _token; IPendleMarket market = IPendleMarket(data.getMarket(_marketFactoryId, _xyt, _token)); require(address(market) != address(0), "MARKET_NOT_FOUND"); // note that LP minting will be done in the market PendingTransfer[2] memory transfers; (transfers, lpOut) = market.addMarketLiquidityDual( msg.sender, _desiredXytAmount, _desiredTokenAmount, _xytMinAmount, _tokenMinAmount ); _settlePendingTransfers(transfers, _xyt, originalToken, address(market)); amountXytUsed = transfers[0].amount; amountTokenUsed = transfers[1].amount; emit Join(msg.sender, amountXytUsed, amountTokenUsed, address(market), lpOut); } /** * @notice add market liquidity by xyt or base token * @dev no checks on _minOutLp * @param _forXyt whether the user wants to addLiquidity by _xyt or _token Conditions: * Have Reentrancy protection */ function addMarketLiquiditySingle( bytes32 _marketFactoryId, address _xyt, address _token, bool _forXyt, uint256 _exactIn, uint256 _minOutLp ) external payable override nonReentrant returns (uint256 exactOutLp) { require(_exactIn != 0, "ZERO_AMOUNTS"); address originalToken = _token; _token = _isETH(_token) ? address(weth) : _token; IPendleMarket market = IPendleMarket(data.getMarket(_marketFactoryId, _xyt, _token)); require(address(market) != address(0), "MARKET_NOT_FOUND"); address assetToTransferIn = _forXyt ? _xyt : originalToken; address assetForMarket = _forXyt ? _xyt : _token; // note that LP minting will be done in the market PendingTransfer[2] memory transfers; (transfers, exactOutLp) = market.addMarketLiquiditySingle( msg.sender, assetForMarket, _exactIn, _minOutLp ); if (_forXyt) { emit Join(msg.sender, _exactIn, 0, address(market), exactOutLp); } else { emit Join(msg.sender, 0, _exactIn, address(market), exactOutLp); } // We only need settle the transfering in of the assetToTransferIn _settleTokenTransfer(assetToTransferIn, transfers[0], address(market)); } /** * @notice remove market liquidity by xyt and base tokens * @dev no checks on _minOutXyt, _minOutToken Conditions: * Have Reentrancy protection */ function removeMarketLiquidityDual( bytes32 _marketFactoryId, address _xyt, address _token, uint256 _exactInLp, uint256 _minOutXyt, uint256 _minOutToken ) external override nonReentrant returns (uint256 exactOutXyt, uint256 exactOutToken) { require(_exactInLp != 0, "ZERO_LP_IN"); address originalToken = _token; _token = _isETH(_token) ? address(weth) : _token; IPendleMarket market = IPendleMarket(data.getMarket(_marketFactoryId, _xyt, _token)); require(address(market) != address(0), "MARKET_NOT_FOUND"); // note that LP burning will be done in the market PendingTransfer[2] memory transfers = market.removeMarketLiquidityDual(msg.sender, _exactInLp, _minOutXyt, _minOutToken); _settlePendingTransfers(transfers, _xyt, originalToken, address(market)); exactOutXyt = transfers[0].amount; exactOutToken = transfers[1].amount; emit Exit(msg.sender, exactOutXyt, exactOutToken, address(market), _exactInLp); } /** * @notice remove market liquidity by xyt or base tokens * @dev no checks on _minOutAsset * @param _forXyt whether the user wants to addLiquidity by _xyt or _token Conditions: * Have Reentrancy protection */ function removeMarketLiquiditySingle( bytes32 _marketFactoryId, address _xyt, address _token, bool _forXyt, uint256 _exactInLp, uint256 _minOutAsset ) external override nonReentrant returns (uint256 exactOutXyt, uint256 exactOutToken) { require(_exactInLp != 0, "ZERO_LP_IN"); address originalToken = _token; _token = _isETH(_token) ? address(weth) : _token; IPendleMarket market = IPendleMarket(data.getMarket(_marketFactoryId, _xyt, _token)); require(address(market) != address(0), "MARKET_NOT_FOUND"); address assetForMarket = _forXyt ? _xyt : _token; // note that LP burning will be done in the market PendingTransfer[2] memory transfers = market.removeMarketLiquiditySingle( msg.sender, assetForMarket, _exactInLp, _minOutAsset ); address assetToTransferOut = _forXyt ? _xyt : originalToken; _settleTokenTransfer(assetToTransferOut, transfers[0], address(market)); if (_forXyt) { emit Exit(msg.sender, transfers[0].amount, 0, address(market), _exactInLp); return (transfers[0].amount, 0); } else { emit Exit(msg.sender, 0, transfers[0].amount, address(market), _exactInLp); return (0, transfers[0].amount); } } /** * @notice create a new market for a pair of xyt & token * @dev A market can be uniquely identified by the triplet(_marketFactoryId,_xyt,_token) Conditions: * Have Reentrancy protection */ function createMarket( bytes32 _marketFactoryId, address _xyt, address _token ) external override nonReentrant returns (address market) { require(_xyt != address(0), "ZERO_ADDRESS"); require(_token != address(0), "ZERO_ADDRESS"); require(data.isXyt(_xyt), "INVALID_YT"); require(!data.isXyt(_token), "YT_QUOTE_PAIR_FORBIDDEN"); require(data.getMarket(_marketFactoryId, _xyt, _token) == address(0), "EXISTED_MARKET"); IPendleMarketFactory factory = IPendleMarketFactory(data.getMarketFactoryAddress(_marketFactoryId)); require(address(factory) != address(0), "ZERO_ADDRESS"); bytes32 forgeId = IPendleForge(IPendleYieldToken(_xyt).forge()).forgeId(); require(data.validForgeFactoryPair(forgeId, _marketFactoryId), "INVALID_FORGE_FACTORY"); market = factory.createMarket(_xyt, _token); emit MarketCreated(_marketFactoryId, _xyt, _token, market); } /** * @notice bootstrap a market (aka the first one to add liquidity) Conditions: * Have Reentrancy protection */ function bootstrapMarket( bytes32 _marketFactoryId, address _xyt, address _token, uint256 _initialXytLiquidity, uint256 _initialTokenLiquidity ) external payable override nonReentrant { require(_initialXytLiquidity > 0, "INVALID_YT_AMOUNT"); require(_initialTokenLiquidity > 0, "INVALID_TOKEN_AMOUNT"); address originalToken = _token; _token = _isETH(_token) ? address(weth) : _token; IPendleMarket market = IPendleMarket(data.getMarket(_marketFactoryId, _xyt, _token)); require(address(market) != address(0), "MARKET_NOT_FOUND"); PendingTransfer[2] memory transfers; uint256 exactOutLp; (transfers, exactOutLp) = market.bootstrap( msg.sender, _initialXytLiquidity, _initialTokenLiquidity ); _settlePendingTransfers(transfers, _xyt, originalToken, address(market)); emit Join( msg.sender, _initialXytLiquidity, _initialTokenLiquidity, address(market), exactOutLp ); } /** * @notice trade by swap exact amount of token into market * @dev no checks on _minOutAmount Conditions: * Have Reentrancy protection */ function swapExactIn( address _tokenIn, address _tokenOut, uint256 _inAmount, uint256 _minOutAmount, bytes32 _marketFactoryId ) external payable override nonReentrant returns (uint256 outSwapAmount) { require(_inAmount != 0, "ZERO_IN_AMOUNT"); address originalTokenIn = _tokenIn; address originalTokenOut = _tokenOut; _tokenIn = _isETH(_tokenIn) ? address(weth) : _tokenIn; _tokenOut = _isETH(_tokenOut) ? address(weth) : _tokenOut; IPendleMarket market = IPendleMarket(data.getMarketFromKey(_tokenIn, _tokenOut, _marketFactoryId)); require(address(market) != address(0), "MARKET_NOT_FOUND"); PendingTransfer[2] memory transfers; (outSwapAmount, transfers) = market.swapExactIn( _tokenIn, _inAmount, _tokenOut, _minOutAmount ); _settlePendingTransfers(transfers, originalTokenIn, originalTokenOut, address(market)); emit SwapEvent(msg.sender, _tokenIn, _tokenOut, _inAmount, outSwapAmount, address(market)); } /** * @notice trade by swap exact amount of token out of market * @dev no checks on _maxInAmount Conditions: * Have Reentrancy protection */ function swapExactOut( address _tokenIn, address _tokenOut, uint256 _outAmount, uint256 _maxInAmount, bytes32 _marketFactoryId ) external payable override nonReentrant returns (uint256 inSwapAmount) { require(_outAmount != 0, "ZERO_OUT_AMOUNT"); address originalTokenIn = _tokenIn; address originalTokenOut = _tokenOut; _tokenIn = _isETH(_tokenIn) ? address(weth) : _tokenIn; _tokenOut = _isETH(_tokenOut) ? address(weth) : _tokenOut; IPendleMarket market = IPendleMarket(data.getMarketFromKey(_tokenIn, _tokenOut, _marketFactoryId)); require(address(market) != address(0), "MARKET_NOT_FOUND"); PendingTransfer[2] memory transfers; (inSwapAmount, transfers) = market.swapExactOut( _tokenIn, _maxInAmount, _tokenOut, _outAmount ); _settlePendingTransfers(transfers, originalTokenIn, originalTokenOut, address(market)); emit SwapEvent(msg.sender, _tokenIn, _tokenOut, inSwapAmount, _outAmount, address(market)); } /** * @notice For Lp holders to claim Lp interests Conditions: * Have Reentrancy protection */ function redeemLpInterests(address market, address user) external override nonReentrant returns (uint256 interests) { require(data.isMarket(market), "INVALID_MARKET"); require(user != address(0), "ZERO_ADDRESS"); interests = IPendleMarket(market).redeemLpInterests(user); } function _getData() internal view override returns (IPendleData) { return data; } function _isETH(address token) internal pure returns (bool) { return (token == ETH_ADDRESS); } /** * @notice This function takes in the standard array PendingTransfer[2] that represents * any pending transfers of tokens to be done between a market and msg.sender * @dev transfers[0] and transfers[1] always represent the tokens that are traded * The convention is that: * - if its a function with xyt and baseToken, transfers[0] is always xyt * - if its a function with tokenIn and tokenOut, transfers[0] is always tokenOut */ function _settlePendingTransfers( PendingTransfer[2] memory transfers, address firstToken, address secondToken, address market ) internal { _settleTokenTransfer(firstToken, transfers[0], market); _settleTokenTransfer(secondToken, transfers[1], market); } /** * @notice This function settles a PendingTransfer, where the token could be ETH_ADDRESS * a PendingTransfer is always between a market and msg.sender */ function _settleTokenTransfer( address token, PendingTransfer memory transfer, address market ) internal { if (transfer.amount == 0) { return; } if (transfer.isOut) { if (_isETH(token)) { weth.transferFrom(market, address(this), transfer.amount); weth.withdraw(transfer.amount); (bool success, ) = msg.sender.call{value: transfer.amount}(""); require(success, "TRANSFER_FAILED"); } else { IERC20(token).safeTransferFrom(market, msg.sender, transfer.amount); } } else { if (_isETH(token)) { require(msg.value >= transfer.amount, "INSUFFICENT_ETH_AMOUNT"); // we only need transfer.amount, so we return the excess uint256 excess = msg.value.sub(transfer.amount); if (excess != 0) { (bool success, ) = msg.sender.call{value: excess}(""); require(success, "TRANSFER_FAILED"); } weth.deposit{value: transfer.amount}(); weth.transfer(market, transfer.amount); } else { // its a transfer in of token. If its an XYT // we will auto approve the router to spend from the user account; if (data.isXyt(token)) { _checkApproveRouter(token); } IERC20(token).safeTransferFrom(msg.sender, market, transfer.amount); } } } // Check if an user has approved the router to spend the amount // if not, approve the router to spend the token from the user account function _checkApproveRouter(address token) internal { uint256 allowance = IPendleBaseToken(token).allowance(msg.sender, address(this)); if (allowance >= REASONABLE_ALLOWANCE_AMOUNT) return; IPendleYieldToken(token).approveRouter(msg.sender); } // There shouldn't be any fund in here // hence governance is allowed to withdraw anything from here. function _allowedToWithdraw(address) internal pure override returns (bool allowed) { allowed = true; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./IERC20.sol"; import "../../math/SafeMath.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 SafeMath for uint256; 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' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(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 // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.0; pragma abicoder v2; import "@openzeppelin/contracts/math/SafeMath.sol"; library Math { using SafeMath for uint256; uint256 internal constant BIG_NUMBER = (uint256(1) << uint256(200)); uint256 internal constant PRECISION_BITS = 40; uint256 internal constant RONE = uint256(1) << PRECISION_BITS; uint256 internal constant PI = (314 * RONE) / 10**2; uint256 internal constant PI_PLUSONE = (414 * RONE) / 10**2; uint256 internal constant PRECISION_POW = 1e2; function checkMultOverflow(uint256 _x, uint256 _y) internal pure returns (bool) { if (_y == 0) return false; return (((_x * _y) / _y) != _x); } /** @notice find the integer part of log2(p/q) => find largest x s.t p >= q * 2^x => find largest x s.t 2^x <= p / q */ function log2Int(uint256 _p, uint256 _q) internal pure returns (uint256) { uint256 res = 0; uint256 remain = _p / _q; while (remain > 0) { res++; remain /= 2; } return res - 1; } /** @notice log2 for a number that it in [1,2) @dev _x is FP, return a FP @dev function is from Kyber. Long modified the condition to be (_x >= one) && (_x < two) to avoid the case where x = 2 may lead to incorrect result */ function log2ForSmallNumber(uint256 _x) internal pure returns (uint256) { uint256 res = 0; uint256 one = (uint256(1) << PRECISION_BITS); uint256 two = 2 * one; uint256 addition = one; require((_x >= one) && (_x < two), "MATH_ERROR"); require(PRECISION_BITS < 125, "MATH_ERROR"); for (uint256 i = PRECISION_BITS; i > 0; i--) { _x = (_x * _x) / one; addition = addition / 2; if (_x >= two) { _x = _x / 2; res += addition; } } return res; } /** @notice log2 of (p/q). returns result in FP form @dev function is from Kyber. @dev _p & _q is FP, return a FP */ function logBase2(uint256 _p, uint256 _q) internal pure returns (uint256) { uint256 n = 0; if (_p > _q) { n = log2Int(_p, _q); } require(n * RONE <= BIG_NUMBER, "MATH_ERROR"); require(!checkMultOverflow(_p, RONE), "MATH_ERROR"); require(!checkMultOverflow(n, RONE), "MATH_ERROR"); require(!checkMultOverflow(uint256(1) << n, _q), "MATH_ERROR"); uint256 y = (_p * RONE) / (_q * (uint256(1) << n)); uint256 log2Small = log2ForSmallNumber(y); assert(log2Small <= BIG_NUMBER); return n * RONE + log2Small; } /** @notice calculate ln(p/q). returned result >= 0 @dev function is from Kyber. @dev _p & _q is FP, return a FP */ function ln(uint256 p, uint256 q) internal pure returns (uint256) { uint256 ln2Numerator = 6931471805599453094172; uint256 ln2Denomerator = 10000000000000000000000; uint256 log2x = logBase2(p, q); require(!checkMultOverflow(ln2Numerator, log2x), "MATH_ERROR"); return (ln2Numerator * log2x) / ln2Denomerator; } /** @notice extract the fractional part of a FP @dev value is a FP, return a FP */ function fpart(uint256 value) internal pure returns (uint256) { return value % RONE; } /** @notice convert a FP to an Int @dev value is a FP, return an Int */ function toInt(uint256 value) internal pure returns (uint256) { return value / RONE; } /** @notice convert an Int to a FP @dev value is an Int, return a FP */ function toFP(uint256 value) internal pure returns (uint256) { return value * RONE; } /** @notice return e^exp in FP form @dev estimation by formula at http://pages.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/exp.html the function is based on exp function of: https://github.com/NovakDistributed/macroverse/blob/master/contracts/RealMath.sol @dev the function is expected to converge quite fast, after about 20 iteration @dev exp is a FP, return a FP */ function rpowe(uint256 exp) internal pure returns (uint256) { uint256 res = 0; uint256 curTerm = RONE; for (uint256 n = 0; ; n++) { res += curTerm; curTerm = rmul(curTerm, rdiv(exp, toFP(n + 1))); if (curTerm == 0) { break; } if (n == 500) { /* testing shows that in the most extreme case, it will take 430 turns to converge. however, it's expected that the numbers will not exceed 2^120 in normal situation the most extreme case is rpow((1<<256)-1,(1<<40)-1) (equal to rpow((2^256-1)/2^40,0.99..9)) */ revert("RPOWE_SLOW_CONVERGE"); } } return res; } /** @notice calculate base^exp with base and exp being FP int @dev to improve accuracy, base^exp = base^(int(exp)+frac(exp)) = base^int(exp) * base^frac @dev base & exp are FP, return a FP */ function rpow(uint256 base, uint256 exp) internal pure returns (uint256) { if (exp == 0) { // Anything to the 0 is 1 return RONE; } if (base == 0) { // 0 to anything except 0 is 0 return 0; } uint256 frac = fpart(exp); // get the fractional part uint256 whole = exp - frac; uint256 wholePow = rpowi(base, toInt(whole)); // whole is a FP, convert to Int uint256 fracPow; // instead of calculating base ^ frac, we will calculate e ^ (frac*ln(base)) if (base < RONE) { /* since the base is smaller than 1.0, ln(base) < 0. Since 1 / (e^(frac*ln(1/base))) = e ^ (frac*ln(base)), we will calculate 1 / (e^(frac*ln(1/base))) instead. */ uint256 newExp = rmul(frac, ln(rdiv(RONE, base), RONE)); fracPow = rdiv(RONE, rpowe(newExp)); } else { /* base is greater than 1, calculate normally */ uint256 newExp = rmul(frac, ln(base, RONE)); fracPow = rpowe(newExp); } return rmul(wholePow, fracPow); } /** @notice return base^exp with base in FP form and exp in Int @dev this function use a technique called: exponentiating by squaring complexity O(log(q)) @dev function is from Kyber. @dev base is a FP, exp is an Int, return a FP */ function rpowi(uint256 base, uint256 exp) internal pure returns (uint256) { uint256 res = exp % 2 != 0 ? base : RONE; for (exp /= 2; exp != 0; exp /= 2) { base = rmul(base, base); if (exp % 2 != 0) { res = rmul(res, base); } } return res; } /** @dev y is an Int, returns an Int @dev babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) @dev from Uniswap */ function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } /** @notice divide 2 FP, return a FP @dev function is from Balancer. @dev x & y are FP, return a FP */ function rdiv(uint256 x, uint256 y) internal pure returns (uint256) { return (y / 2).add(x.mul(RONE)).div(y); } /** @notice multiply 2 FP, return a FP @dev function is from Balancer. @dev x & y are FP, return a FP */ function rmul(uint256 x, uint256 y) internal pure returns (uint256) { return (RONE / 2).add(x.mul(y)).div(RONE); } function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } function subMax0(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a - b : 0; } }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; pragma abicoder v2; import "../interfaces/IWETH.sol"; import "./IPendleData.sol"; import "../libraries/PendleStructs.sol"; import "./IPendleMarketFactory.sol"; interface IPendleRouter { /** * @notice Emitted when a market for a future yield token and an ERC20 token is created. * @param marketFactoryId Forge identifier. * @param xyt The address of the tokenized future yield token as the base asset. * @param token The address of an ERC20 token as the quote asset. * @param market The address of the newly created market. **/ event MarketCreated( bytes32 marketFactoryId, address indexed xyt, address indexed token, address indexed market ); /** * @notice Emitted when a swap happens on the market. * @param trader The address of msg.sender. * @param inToken The input token. * @param outToken The output token. * @param exactIn The exact amount being traded. * @param exactOut The exact amount received. * @param market The market address. **/ event SwapEvent( address indexed trader, address inToken, address outToken, uint256 exactIn, uint256 exactOut, address market ); /** * @dev Emitted when user adds liquidity * @param sender The user who added liquidity. * @param token0Amount the amount of token0 (xyt) provided by user * @param token1Amount the amount of token1 provided by user * @param market The market address. * @param exactOutLp The exact LP minted */ event Join( address indexed sender, uint256 token0Amount, uint256 token1Amount, address market, uint256 exactOutLp ); /** * @dev Emitted when user removes liquidity * @param sender The user who removed liquidity. * @param token0Amount the amount of token0 (xyt) given to user * @param token1Amount the amount of token1 given to user * @param market The market address. * @param exactInLp The exact Lp to remove */ event Exit( address indexed sender, uint256 token0Amount, uint256 token1Amount, address market, uint256 exactInLp ); /** * @notice Gets a reference to the PendleData contract. * @return Returns the data contract reference. **/ function data() external view returns (IPendleData); /** * @notice Gets a reference of the WETH9 token contract address. * @return WETH token reference. **/ function weth() external view returns (IWETH); /*********** * FORGE * ***********/ function newYieldContracts( bytes32 forgeId, address underlyingAsset, uint256 expiry ) external returns (address ot, address xyt); function redeemAfterExpiry( bytes32 forgeId, address underlyingAsset, uint256 expiry ) external returns (uint256 redeemedAmount); function redeemDueInterests( bytes32 forgeId, address underlyingAsset, uint256 expiry, address user ) external returns (uint256 interests); function redeemUnderlying( bytes32 forgeId, address underlyingAsset, uint256 expiry, uint256 amountToRedeem ) external returns (uint256 redeemedAmount); function renewYield( bytes32 forgeId, uint256 oldExpiry, address underlyingAsset, uint256 newExpiry, uint256 renewalRate ) external returns ( uint256 redeemedAmount, uint256 amountRenewed, address ot, address xyt, uint256 amountTokenMinted ); function tokenizeYield( bytes32 forgeId, address underlyingAsset, uint256 expiry, uint256 amountToTokenize, address to ) external returns ( address ot, address xyt, uint256 amountTokenMinted ); /*********** * MARKET * ***********/ function addMarketLiquidityDual( bytes32 _marketFactoryId, address _xyt, address _token, uint256 _desiredXytAmount, uint256 _desiredTokenAmount, uint256 _xytMinAmount, uint256 _tokenMinAmount ) external payable returns ( uint256 amountXytUsed, uint256 amountTokenUsed, uint256 lpOut ); function addMarketLiquiditySingle( bytes32 marketFactoryId, address xyt, address token, bool forXyt, uint256 exactInAsset, uint256 minOutLp ) external payable returns (uint256 exactOutLp); function removeMarketLiquidityDual( bytes32 marketFactoryId, address xyt, address token, uint256 exactInLp, uint256 minOutXyt, uint256 minOutToken ) external returns (uint256 exactOutXyt, uint256 exactOutToken); function removeMarketLiquiditySingle( bytes32 marketFactoryId, address xyt, address token, bool forXyt, uint256 exactInLp, uint256 minOutAsset ) external returns (uint256 exactOutXyt, uint256 exactOutToken); /** * @notice Creates a market given a protocol ID, future yield token, and an ERC20 token. * @param marketFactoryId Market Factory identifier. * @param xyt Token address of the future yield token as base asset. * @param token Token address of an ERC20 token as quote asset. * @return market Returns the address of the newly created market. **/ function createMarket( bytes32 marketFactoryId, address xyt, address token ) external returns (address market); function bootstrapMarket( bytes32 marketFactoryId, address xyt, address token, uint256 initialXytLiquidity, uint256 initialTokenLiquidity ) external payable; function swapExactIn( address tokenIn, address tokenOut, uint256 inTotalAmount, uint256 minOutTotalAmount, bytes32 marketFactoryId ) external payable returns (uint256 outTotalAmount); function swapExactOut( address tokenIn, address tokenOut, uint256 outTotalAmount, uint256 maxInTotalAmount, bytes32 marketFactoryId ) external payable returns (uint256 inTotalAmount); function redeemLpInterests(address market, address user) external returns (uint256 interests); }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; import "./IPendleRouter.sol"; import "./IPendleYieldToken.sol"; import "./IPendlePausingManager.sol"; import "./IPendleMarket.sol"; interface IPendleData { /** * @notice Emitted when validity of a forge-factory pair is updated * @param _forgeId the forge id * @param _marketFactoryId the market factory id * @param _valid valid or not **/ event ForgeFactoryValiditySet(bytes32 _forgeId, bytes32 _marketFactoryId, bool _valid); /** * @notice Emitted when Pendle and PendleFactory addresses have been updated. * @param treasury The address of the new treasury contract. **/ event TreasurySet(address treasury); /** * @notice Emitted when LockParams is changed **/ event LockParamsSet(uint256 lockNumerator, uint256 lockDenominator); /** * @notice Emitted when ExpiryDivisor is changed **/ event ExpiryDivisorSet(uint256 expiryDivisor); /** * @notice Emitted when forge fee is changed **/ event ForgeFeeSet(uint256 forgeFee); /** * @notice Emitted when interestUpdateRateDeltaForMarket is changed * @param interestUpdateRateDeltaForMarket new interestUpdateRateDeltaForMarket setting **/ event InterestUpdateRateDeltaForMarketSet(uint256 interestUpdateRateDeltaForMarket); /** * @notice Emitted when market fees are changed * @param _swapFee new swapFee setting * @param _protocolSwapFee new protocolSwapFee setting **/ event MarketFeesSet(uint256 _swapFee, uint256 _protocolSwapFee); /** * @notice Emitted when the curve shift block delta is changed * @param _blockDelta new block delta setting **/ event CurveShiftBlockDeltaSet(uint256 _blockDelta); /** * @dev Emitted when new forge is added * @param marketFactoryId Human Readable Market Factory ID in Bytes * @param marketFactoryAddress The Market Factory Address */ event NewMarketFactory(bytes32 indexed marketFactoryId, address indexed marketFactoryAddress); /** * @notice Set/update validity of a forge-factory pair * @param _forgeId the forge id * @param _marketFactoryId the market factory id * @param _valid valid or not **/ function setForgeFactoryValidity( bytes32 _forgeId, bytes32 _marketFactoryId, bool _valid ) external; /** * @notice Sets the PendleTreasury contract addresses. * @param newTreasury Address of new treasury contract. **/ function setTreasury(address newTreasury) external; /** * @notice Gets a reference to the PendleRouter contract. * @return Returns the router contract reference. **/ function router() external view returns (IPendleRouter); /** * @notice Gets a reference to the PendleRouter contract. * @return Returns the router contract reference. **/ function pausingManager() external view returns (IPendlePausingManager); /** * @notice Gets the treasury contract address where fees are being sent to. * @return Address of the treasury contract. **/ function treasury() external view returns (address); /*********** * FORGE * ***********/ /** * @notice Emitted when a forge for a protocol is added. * @param forgeId Forge and protocol identifier. * @param forgeAddress The address of the added forge. **/ event ForgeAdded(bytes32 indexed forgeId, address indexed forgeAddress); /** * @notice Adds a new forge for a protocol. * @param forgeId Forge and protocol identifier. * @param forgeAddress The address of the added forge. **/ function addForge(bytes32 forgeId, address forgeAddress) external; /** * @notice Store new OT and XYT details. * @param forgeId Forge and protocol identifier. * @param ot The address of the new XYT. * @param xyt The address of the new XYT. * @param underlyingAsset Token address of the underlying asset. * @param expiry Yield contract expiry in epoch time. **/ function storeTokens( bytes32 forgeId, address ot, address xyt, address underlyingAsset, uint256 expiry ) external; /** * @notice Set a new forge fee * @param _forgeFee new forge fee **/ function setForgeFee(uint256 _forgeFee) external; /** * @notice Gets the OT and XYT tokens. * @param forgeId Forge and protocol identifier. * @param underlyingYieldToken Token address of the underlying yield token. * @param expiry Yield contract expiry in epoch time. * @return ot The OT token references. * @return xyt The XYT token references. **/ function getPendleYieldTokens( bytes32 forgeId, address underlyingYieldToken, uint256 expiry ) external view returns (IPendleYieldToken ot, IPendleYieldToken xyt); /** * @notice Gets a forge given the identifier. * @param forgeId Forge and protocol identifier. * @return forgeAddress Returns the forge address. **/ function getForgeAddress(bytes32 forgeId) external view returns (address forgeAddress); /** * @notice Checks if an XYT token is valid. * @param forgeId The forgeId of the forge. * @param underlyingAsset Token address of the underlying asset. * @param expiry Yield contract expiry in epoch time. * @return True if valid, false otherwise. **/ function isValidXYT( bytes32 forgeId, address underlyingAsset, uint256 expiry ) external view returns (bool); /** * @notice Checks if an OT token is valid. * @param forgeId The forgeId of the forge. * @param underlyingAsset Token address of the underlying asset. * @param expiry Yield contract expiry in epoch time. * @return True if valid, false otherwise. **/ function isValidOT( bytes32 forgeId, address underlyingAsset, uint256 expiry ) external view returns (bool); function validForgeFactoryPair(bytes32 _forgeId, bytes32 _marketFactoryId) external view returns (bool); /** * @notice Gets a reference to a specific OT. * @param forgeId Forge and protocol identifier. * @param underlyingYieldToken Token address of the underlying yield token. * @param expiry Yield contract expiry in epoch time. * @return ot Returns the reference to an OT. **/ function otTokens( bytes32 forgeId, address underlyingYieldToken, uint256 expiry ) external view returns (IPendleYieldToken ot); /** * @notice Gets a reference to a specific XYT. * @param forgeId Forge and protocol identifier. * @param underlyingAsset Token address of the underlying asset * @param expiry Yield contract expiry in epoch time. * @return xyt Returns the reference to an XYT. **/ function xytTokens( bytes32 forgeId, address underlyingAsset, uint256 expiry ) external view returns (IPendleYieldToken xyt); /*********** * MARKET * ***********/ event MarketPairAdded(address indexed market, address indexed xyt, address indexed token); function addMarketFactory(bytes32 marketFactoryId, address marketFactoryAddress) external; function isMarket(address _addr) external view returns (bool result); function isXyt(address _addr) external view returns (bool result); function addMarket( bytes32 marketFactoryId, address xyt, address token, address market ) external; function setMarketFees(uint256 _swapFee, uint256 _protocolSwapFee) external; function setInterestUpdateRateDeltaForMarket(uint256 _interestUpdateRateDeltaForMarket) external; function setLockParams(uint256 _lockNumerator, uint256 _lockDenominator) external; function setExpiryDivisor(uint256 _expiryDivisor) external; function setCurveShiftBlockDelta(uint256 _blockDelta) external; /** * @notice Displays the number of markets currently existing. * @return Returns markets length, **/ function allMarketsLength() external view returns (uint256); function forgeFee() external view returns (uint256); function interestUpdateRateDeltaForMarket() external view returns (uint256); function expiryDivisor() external view returns (uint256); function lockNumerator() external view returns (uint256); function lockDenominator() external view returns (uint256); function swapFee() external view returns (uint256); function protocolSwapFee() external view returns (uint256); function curveShiftBlockDelta() external view returns (uint256); function getMarketByIndex(uint256 index) external view returns (address market); /** * @notice Gets a market given a future yield token and an ERC20 token. * @param xyt Token address of the future yield token as base asset. * @param token Token address of an ERC20 token as quote asset. * @return market Returns the market address. **/ function getMarket( bytes32 marketFactoryId, address xyt, address token ) external view returns (address market); /** * @notice Gets a market factory given the identifier. * @param marketFactoryId MarketFactory identifier. * @return marketFactoryAddress Returns the factory address. **/ function getMarketFactoryAddress(bytes32 marketFactoryId) external view returns (address marketFactoryAddress); function getMarketFromKey( address xyt, address token, bytes32 marketFactoryId ) external view returns (address market); }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./IPendleRouter.sol"; import "./IPendleData.sol"; import "./IPendleRewardManager.sol"; import "./IPendleYieldContractDeployer.sol"; interface IPendleForge { /** * @dev Emitted when the Forge has minted the OT and XYT tokens. * @param forgeId The forgeId * @param underlyingAsset The address of the underlying yield token. * @param expiry The expiry of the XYT token * @param amountToTokenize The amount of yield bearing assets to tokenize * @param amountTokenMinted The amount of OT/XYT minted **/ event MintYieldTokens( bytes32 forgeId, address indexed underlyingAsset, uint256 indexed expiry, uint256 amountToTokenize, uint256 amountTokenMinted, address indexed user ); /** * @dev Emitted when the Forge has created new yield token contracts. * @param forgeId The forgeId * @param underlyingAsset The address of the underlying asset. * @param expiry The date in epoch time when the contract will expire. * @param ot The address of the ownership token. * @param xyt The address of the new future yield token. **/ event NewYieldContracts( bytes32 forgeId, address indexed underlyingAsset, uint256 indexed expiry, address ot, address xyt, address yieldBearingAsset ); /** * @dev Emitted when the Forge has redeemed the OT and XYT tokens. * @param forgeId The forgeId * @param underlyingAsset the address of the underlying asset * @param expiry The expiry of the XYT token * @param amountToRedeem The amount of OT to be redeemed. * @param redeemedAmount The amount of yield token received **/ event RedeemYieldToken( bytes32 forgeId, address indexed underlyingAsset, uint256 indexed expiry, uint256 amountToRedeem, uint256 redeemedAmount, address indexed user ); /** * @dev Emitted when interest claim is settled * @param forgeId The forgeId * @param underlyingAsset the address of the underlying asset * @param expiry The expiry of the XYT token * @param user Interest receiver Address * @param amount The amount of interest claimed **/ event DueInterestsSettled( bytes32 forgeId, address indexed underlyingAsset, uint256 indexed expiry, uint256 amount, uint256 forgeFeeAmount, address indexed user ); /** * @dev Emitted when forge fee is withdrawn * @param forgeId The forgeId * @param underlyingAsset the address of the underlying asset * @param expiry The expiry of the XYT token * @param amount The amount of interest claimed **/ event ForgeFeeWithdrawn( bytes32 forgeId, address indexed underlyingAsset, uint256 indexed expiry, uint256 amount ); function setUpEmergencyMode( address _underlyingAsset, uint256 _expiry, address spender ) external; function newYieldContracts(address underlyingAsset, uint256 expiry) external returns (address ot, address xyt); function redeemAfterExpiry( address user, address underlyingAsset, uint256 expiry ) external returns (uint256 redeemedAmount); function redeemDueInterests( address user, address underlyingAsset, uint256 expiry ) external returns (uint256 interests); function updateDueInterests( address underlyingAsset, uint256 expiry, address user ) external; function updatePendingRewards( address _underlyingAsset, uint256 _expiry, address _user ) external; function redeemUnderlying( address user, address underlyingAsset, uint256 expiry, uint256 amountToRedeem ) external returns (uint256 redeemedAmount); function mintOtAndXyt( address underlyingAsset, uint256 expiry, uint256 amountToTokenize, address to ) external returns ( address ot, address xyt, uint256 amountTokenMinted ); function withdrawForgeFee(address underlyingAsset, uint256 expiry) external; function getYieldBearingToken(address underlyingAsset) external returns (address); /** * @notice Gets a reference to the PendleRouter contract. * @return Returns the router contract reference. **/ function router() external view returns (IPendleRouter); function data() external view returns (IPendleData); function rewardManager() external view returns (IPendleRewardManager); function yieldContractDeployer() external view returns (IPendleYieldContractDeployer); function rewardToken() external view returns (IERC20); /** * @notice Gets the bytes32 ID of the forge. * @return Returns the forge and protocol identifier. **/ function forgeId() external view returns (bytes32); function dueInterests( address _underlyingAsset, uint256 expiry, address _user ) external view returns (uint256); function yieldTokenHolders(address _underlyingAsset, uint256 _expiry) external view returns (address yieldTokenHolder); }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; import "./IPendleRouter.sol"; interface IPendleMarketFactory { /** * @notice Creates a market given a protocol ID, future yield token, and an ERC20 token. * @param xyt Token address of the futuonlyCorere yield token as base asset. * @param token Token address of an ERC20 token as quote asset. * @return market Returns the address of the newly created market. **/ function createMarket(address xyt, address token) external returns (address market); /** * @notice Gets a reference to the PendleRouter contract. * @return Returns the router contract reference. **/ function router() external view returns (IPendleRouter); function marketFactoryId() external view returns (bytes32); }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; pragma abicoder v2; import "./IPendleRouter.sol"; import "./IPendleBaseToken.sol"; import "../libraries/PendleStructs.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IPendleMarket is IERC20 { /** * @notice Emitted when reserves pool has been updated * @param reserve0 The XYT reserves. * @param weight0 The XYT weight * @param reserve1 The generic token reserves. * For the generic Token weight it can be inferred by (2^40) - weight0 **/ event Sync(uint256 reserve0, uint256 weight0, uint256 reserve1); function setUpEmergencyMode(address spender) external; function bootstrap( address user, uint256 initialXytLiquidity, uint256 initialTokenLiquidity ) external returns (PendingTransfer[2] memory transfers, uint256 exactOutLp); function addMarketLiquiditySingle( address user, address inToken, uint256 inAmount, uint256 minOutLp ) external returns (PendingTransfer[2] memory transfers, uint256 exactOutLp); function addMarketLiquidityDual( address user, uint256 _desiredXytAmount, uint256 _desiredTokenAmount, uint256 _xytMinAmount, uint256 _tokenMinAmount ) external returns (PendingTransfer[2] memory transfers, uint256 lpOut); function removeMarketLiquidityDual( address user, uint256 inLp, uint256 minOutXyt, uint256 minOutToken ) external returns (PendingTransfer[2] memory transfers); function removeMarketLiquiditySingle( address user, address outToken, uint256 exactInLp, uint256 minOutToken ) external returns (PendingTransfer[2] memory transfers); function swapExactIn( address inToken, uint256 inAmount, address outToken, uint256 minOutAmount ) external returns (uint256 outAmount, PendingTransfer[2] memory transfers); function swapExactOut( address inToken, uint256 maxInAmount, address outToken, uint256 outAmount ) external returns (uint256 inAmount, PendingTransfer[2] memory transfers); function redeemLpInterests(address user) external returns (uint256 interests); function getReserves() external view returns ( uint256 xytBalance, uint256 xytWeight, uint256 tokenBalance, uint256 tokenWeight, uint256 currentBlock ); function factoryId() external view returns (bytes32); function token() external view returns (address); function xyt() external view returns (address); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../core/PendleGovernanceManager.sol"; import "../interfaces/IPermissionsV2.sol"; abstract contract PermissionsV2 is IPermissionsV2 { PendleGovernanceManager public immutable override governanceManager; address internal initializer; constructor(address _governanceManager) { require(_governanceManager != address(0), "ZERO_ADDRESS"); initializer = msg.sender; governanceManager = PendleGovernanceManager(_governanceManager); } modifier initialized() { require(initializer == address(0), "NOT_INITIALIZED"); _; } modifier onlyGovernance() { require(msg.sender == _governance(), "ONLY_GOVERNANCE"); _; } function _governance() internal view returns (address) { return governanceManager.governance(); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "./PermissionsV2.sol"; abstract contract WithdrawableV2 is PermissionsV2 { using SafeERC20 for IERC20; event EtherWithdraw(uint256 amount, address sendTo); event TokenWithdraw(IERC20 token, uint256 amount, address sendTo); /** * @dev Allows governance to withdraw Ether in a Pendle contract * in case of accidental ETH transfer into the contract. * @param amount The amount of Ether to withdraw. * @param sendTo The recipient address. */ function withdrawEther(uint256 amount, address payable sendTo) external onlyGovernance { (bool success, ) = sendTo.call{value: amount}(""); require(success, "WITHDRAW_FAILED"); emit EtherWithdraw(amount, sendTo); } /** * @dev Allows governance to withdraw all IERC20 compatible tokens in a Pendle * contract in case of accidental token transfer into the contract. * @param token IERC20 The address of the token contract. * @param amount The amount of IERC20 tokens to withdraw. * @param sendTo The recipient address. */ function withdrawToken( IERC20 token, uint256 amount, address sendTo ) external onlyGovernance { require(_allowedToWithdraw(address(token)), "TOKEN_NOT_ALLOWED"); token.safeTransfer(sendTo, amount); emit TokenWithdraw(token, amount, sendTo); } // must be overridden by the sub contracts, so we must consider explicitly // in each and every contract which tokens are allowed to be withdrawn function _allowedToWithdraw(address) internal view virtual returns (bool allowed); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; pragma abicoder v2; import "../interfaces/IPendleData.sol"; abstract contract PendleRouterNonReentrant { uint8 internal _guardCounter; modifier nonReentrant() { _checkNonReentrancy(); // use functions to reduce bytecode size _; _guardCounter--; } constructor() { _guardCounter = 1; } /** * We allow markets to make at most ONE Reentrant call in the case of redeemLpInterests * The flow of redeemLpInterests will be: Router.redeemLpInterests -> market.redeemLpInterests -> Router.redeemDueInterests (so there is at most ONE Reentrant call) */ function _checkNonReentrancy() internal { if (_getData().isMarket(msg.sender)) { require(_guardCounter <= 2, "REENTRANT_CALL"); } else { require(_guardCounter == 1, "REENTRANT_CALL"); } _guardCounter++; } function _getData() internal view virtual returns (IPendleData); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <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; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @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"); // solhint-disable-next-line avoid-low-level-calls (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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IWETH is IERC20 { function deposit() external payable; function withdraw(uint256 wad) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.7.6; struct TokenReserve { uint256 weight; uint256 balance; } struct PendingTransfer { uint256 amount; bool isOut; }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./IPendleBaseToken.sol"; import "./IPendleForge.sol"; interface IPendleYieldToken is IERC20, IPendleBaseToken { /** * @notice Emitted when burning OT or XYT tokens. * @param user The address performing the burn. * @param amount The amount to be burned. **/ event Burn(address indexed user, uint256 amount); /** * @notice Emitted when minting OT or XYT tokens. * @param user The address performing the mint. * @param amount The amount to be minted. **/ event Mint(address indexed user, uint256 amount); /** * @notice Burns OT or XYT tokens from user, reducing the total supply. * @param user The address performing the burn. * @param amount The amount to be burned. **/ function burn(address user, uint256 amount) external; /** * @notice Mints new OT or XYT tokens for user, increasing the total supply. * @param user The address to send the minted tokens. * @param amount The amount to be minted. **/ function mint(address user, uint256 amount) external; /** * @notice Gets the forge address of the PendleForge contract for this yield token. * @return Retuns the forge address. **/ function forge() external view returns (IPendleForge); /** * @notice Returns the address of the underlying asset. * @return Returns the underlying asset address. **/ function underlyingAsset() external view returns (address); /** * @notice Returns the address of the underlying yield token. * @return Returns the underlying yield token address. **/ function underlyingYieldToken() external view returns (address); /** * @notice let the router approve itself to spend OT/XYT/LP from any wallet * @param user user to approve **/ function approveRouter(address user) external; }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; interface IPendlePausingManager { event AddPausingAdmin(address admin); event RemovePausingAdmin(address admin); event PendingForgeEmergencyHandler(address _pendingForgeHandler); event PendingMarketEmergencyHandler(address _pendingMarketHandler); event PendingLiqMiningEmergencyHandler(address _pendingLiqMiningHandler); event ForgeEmergencyHandlerSet(address forgeEmergencyHandler); event MarketEmergencyHandlerSet(address marketEmergencyHandler); event LiqMiningEmergencyHandlerSet(address liqMiningEmergencyHandler); event PausingManagerLocked(); event ForgeHandlerLocked(); event MarketHandlerLocked(); event LiqMiningHandlerLocked(); event SetForgePaused(bytes32 forgeId, bool settingToPaused); event SetForgeAssetPaused(bytes32 forgeId, address underlyingAsset, bool settingToPaused); event SetForgeAssetExpiryPaused( bytes32 forgeId, address underlyingAsset, uint256 expiry, bool settingToPaused ); event SetForgeLocked(bytes32 forgeId); event SetForgeAssetLocked(bytes32 forgeId, address underlyingAsset); event SetForgeAssetExpiryLocked(bytes32 forgeId, address underlyingAsset, uint256 expiry); event SetMarketFactoryPaused(bytes32 marketFactoryId, bool settingToPaused); event SetMarketPaused(bytes32 marketFactoryId, address market, bool settingToPaused); event SetMarketFactoryLocked(bytes32 marketFactoryId); event SetMarketLocked(bytes32 marketFactoryId, address market); event SetLiqMiningPaused(address liqMiningContract, bool settingToPaused); event SetLiqMiningLocked(address liqMiningContract); function forgeEmergencyHandler() external view returns ( address handler, address pendingHandler, uint256 timelockDeadline ); function marketEmergencyHandler() external view returns ( address handler, address pendingHandler, uint256 timelockDeadline ); function liqMiningEmergencyHandler() external view returns ( address handler, address pendingHandler, uint256 timelockDeadline ); function permLocked() external view returns (bool); function permForgeHandlerLocked() external view returns (bool); function permMarketHandlerLocked() external view returns (bool); function permLiqMiningHandlerLocked() external view returns (bool); function isPausingAdmin(address) external view returns (bool); function setPausingAdmin(address admin, bool isAdmin) external; function requestForgeHandlerChange(address _pendingForgeHandler) external; function requestMarketHandlerChange(address _pendingMarketHandler) external; function requestLiqMiningHandlerChange(address _pendingLiqMiningHandler) external; function applyForgeHandlerChange() external; function applyMarketHandlerChange() external; function applyLiqMiningHandlerChange() external; function lockPausingManagerPermanently() external; function lockForgeHandlerPermanently() external; function lockMarketHandlerPermanently() external; function lockLiqMiningHandlerPermanently() external; function setForgePaused(bytes32 forgeId, bool paused) external; function setForgeAssetPaused( bytes32 forgeId, address underlyingAsset, bool paused ) external; function setForgeAssetExpiryPaused( bytes32 forgeId, address underlyingAsset, uint256 expiry, bool paused ) external; function setForgeLocked(bytes32 forgeId) external; function setForgeAssetLocked(bytes32 forgeId, address underlyingAsset) external; function setForgeAssetExpiryLocked( bytes32 forgeId, address underlyingAsset, uint256 expiry ) external; function checkYieldContractStatus( bytes32 forgeId, address underlyingAsset, uint256 expiry ) external returns (bool _paused, bool _locked); function setMarketFactoryPaused(bytes32 marketFactoryId, bool paused) external; function setMarketPaused( bytes32 marketFactoryId, address market, bool paused ) external; function setMarketFactoryLocked(bytes32 marketFactoryId) external; function setMarketLocked(bytes32 marketFactoryId, address market) external; function checkMarketStatus(bytes32 marketFactoryId, address market) external returns (bool _paused, bool _locked); function setLiqMiningPaused(address liqMiningContract, bool settingToPaused) external; function setLiqMiningLocked(address liqMiningContract) external; function checkLiqMiningStatus(address liqMiningContract) external returns (bool _paused, bool _locked); }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IPendleBaseToken is IERC20 { /** * @notice Decreases the allowance granted to spender by the caller. * @param spender The address to reduce the allowance from. * @param subtractedValue The amount allowance to subtract. * @return Returns true if allowance has decreased, otherwise false. **/ function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); /** * @notice The yield contract start in epoch time. * @return Returns the yield start date. **/ function start() external view returns (uint256); /** * @notice The yield contract expiry in epoch time. * @return Returns the yield expiry date. **/ function expiry() external view returns (uint256); /** * @notice Increases the allowance granted to spender by the caller. * @param spender The address to increase the allowance from. * @param addedValue The amount allowance to add. * @return Returns true if allowance has increased, otherwise false **/ function increaseAllowance(address spender, uint256 addedValue) external returns (bool); /** * @notice Returns the number of decimals the token uses. * @return Returns the token's decimals. **/ function decimals() external view returns (uint8); /** * @notice Returns the name of the token. * @return Returns the token's name. **/ function name() external view returns (string memory); /** * @notice Returns the symbol of the token. * @return Returns the token's symbol. **/ function symbol() external view returns (string memory); /** * @notice approve using the owner's signature **/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; interface IPendleRewardManager { event UpdateFrequencySet(address[], uint256[]); event SkippingRewardsSet(bool); event DueRewardsSettled( bytes32 forgeId, address underlyingAsset, uint256 expiry, uint256 amountOut, address user ); function redeemRewards( address _underlyingAsset, uint256 _expiry, address _user ) external returns (uint256 dueRewards); function updatePendingRewards( address _underlyingAsset, uint256 _expiry, address _user ) external; function updateParamLManual(address _underlyingAsset, uint256 _expiry) external; function setUpdateFrequency( address[] calldata underlyingAssets, uint256[] calldata frequencies ) external; function setSkippingRewards(bool skippingRewards) external; function forgeId() external returns (bytes32); }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; interface IPendleYieldContractDeployer { function forgeId() external returns (bytes32); function forgeOwnershipToken( address _underlyingAsset, string memory _name, string memory _symbol, uint8 _decimals, uint256 _expiry ) external returns (address ot); function forgeFutureYieldToken( address _underlyingAsset, string memory _name, string memory _symbol, uint8 _decimals, uint256 _expiry ) external returns (address xyt); function deployYieldTokenHolder(address yieldToken, uint256 expiry) external returns (address yieldTokenHolder); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; contract PendleGovernanceManager { address public governance; address public pendingGovernance; event GovernanceClaimed(address newGovernance, address previousGovernance); event TransferGovernancePending(address pendingGovernance); constructor(address _governance) { require(_governance != address(0), "ZERO_ADDRESS"); governance = _governance; } modifier onlyGovernance() { require(msg.sender == governance, "ONLY_GOVERNANCE"); _; } /** * @dev Allows the pendingGovernance address to finalize the change governance process. */ function claimGovernance() external { require(pendingGovernance == msg.sender, "WRONG_GOVERNANCE"); emit GovernanceClaimed(pendingGovernance, governance); governance = pendingGovernance; pendingGovernance = address(0); } /** * @dev Allows the current governance to set the pendingGovernance address. * @param _governance The address to transfer ownership to. */ function transferGovernance(address _governance) external onlyGovernance { require(_governance != address(0), "ZERO_ADDRESS"); pendingGovernance = _governance; emit TransferGovernancePending(pendingGovernance); } }
// SPDX-License-Identifier: MIT /* * MIT License * =========== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity 0.7.6; pragma abicoder v2; import "../core/PendleGovernanceManager.sol"; interface IPermissionsV2 { function governanceManager() external returns (PendleGovernanceManager); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_governanceManager","type":"address"},{"internalType":"contract IWETH","name":"_weth","type":"address"},{"internalType":"contract IPendleData","name":"_data","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"sendTo","type":"address"}],"name":"EtherWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"token0Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"token1Amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"market","type":"address"},{"indexed":false,"internalType":"uint256","name":"exactInLp","type":"uint256"}],"name":"Exit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"token0Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"token1Amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"market","type":"address"},{"indexed":false,"internalType":"uint256","name":"exactOutLp","type":"uint256"}],"name":"Join","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"marketFactoryId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"xyt","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"market","type":"address"}],"name":"MarketCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"address","name":"inToken","type":"address"},{"indexed":false,"internalType":"address","name":"outToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"exactIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"exactOut","type":"uint256"},{"indexed":false,"internalType":"address","name":"market","type":"address"}],"name":"SwapEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"sendTo","type":"address"}],"name":"TokenWithdraw","type":"event"},{"inputs":[{"internalType":"bytes32","name":"_marketFactoryId","type":"bytes32"},{"internalType":"address","name":"_xyt","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_desiredXytAmount","type":"uint256"},{"internalType":"uint256","name":"_desiredTokenAmount","type":"uint256"},{"internalType":"uint256","name":"_xytMinAmount","type":"uint256"},{"internalType":"uint256","name":"_tokenMinAmount","type":"uint256"}],"name":"addMarketLiquidityDual","outputs":[{"internalType":"uint256","name":"amountXytUsed","type":"uint256"},{"internalType":"uint256","name":"amountTokenUsed","type":"uint256"},{"internalType":"uint256","name":"lpOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_marketFactoryId","type":"bytes32"},{"internalType":"address","name":"_xyt","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"bool","name":"_forXyt","type":"bool"},{"internalType":"uint256","name":"_exactIn","type":"uint256"},{"internalType":"uint256","name":"_minOutLp","type":"uint256"}],"name":"addMarketLiquiditySingle","outputs":[{"internalType":"uint256","name":"exactOutLp","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_marketFactoryId","type":"bytes32"},{"internalType":"address","name":"_xyt","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_initialXytLiquidity","type":"uint256"},{"internalType":"uint256","name":"_initialTokenLiquidity","type":"uint256"}],"name":"bootstrapMarket","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_marketFactoryId","type":"bytes32"},{"internalType":"address","name":"_xyt","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"createMarket","outputs":[{"internalType":"address","name":"market","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"data","outputs":[{"internalType":"contract IPendleData","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceManager","outputs":[{"internalType":"contract PendleGovernanceManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_forgeId","type":"bytes32"},{"internalType":"address","name":"_underlyingAsset","type":"address"},{"internalType":"uint256","name":"_expiry","type":"uint256"}],"name":"newYieldContracts","outputs":[{"internalType":"address","name":"ot","type":"address"},{"internalType":"address","name":"xyt","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_forgeId","type":"bytes32"},{"internalType":"address","name":"_underlyingAsset","type":"address"},{"internalType":"uint256","name":"_expiry","type":"uint256"}],"name":"redeemAfterExpiry","outputs":[{"internalType":"uint256","name":"redeemedAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_forgeId","type":"bytes32"},{"internalType":"address","name":"_underlyingAsset","type":"address"},{"internalType":"uint256","name":"_expiry","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"redeemDueInterests","outputs":[{"internalType":"uint256","name":"interests","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"market","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"redeemLpInterests","outputs":[{"internalType":"uint256","name":"interests","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_forgeId","type":"bytes32"},{"internalType":"address","name":"_underlyingAsset","type":"address"},{"internalType":"uint256","name":"_expiry","type":"uint256"},{"internalType":"uint256","name":"_amountToRedeem","type":"uint256"}],"name":"redeemUnderlying","outputs":[{"internalType":"uint256","name":"redeemedAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_marketFactoryId","type":"bytes32"},{"internalType":"address","name":"_xyt","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_exactInLp","type":"uint256"},{"internalType":"uint256","name":"_minOutXyt","type":"uint256"},{"internalType":"uint256","name":"_minOutToken","type":"uint256"}],"name":"removeMarketLiquidityDual","outputs":[{"internalType":"uint256","name":"exactOutXyt","type":"uint256"},{"internalType":"uint256","name":"exactOutToken","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_marketFactoryId","type":"bytes32"},{"internalType":"address","name":"_xyt","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"bool","name":"_forXyt","type":"bool"},{"internalType":"uint256","name":"_exactInLp","type":"uint256"},{"internalType":"uint256","name":"_minOutAsset","type":"uint256"}],"name":"removeMarketLiquiditySingle","outputs":[{"internalType":"uint256","name":"exactOutXyt","type":"uint256"},{"internalType":"uint256","name":"exactOutToken","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_forgeId","type":"bytes32"},{"internalType":"uint256","name":"_oldExpiry","type":"uint256"},{"internalType":"address","name":"_underlyingAsset","type":"address"},{"internalType":"uint256","name":"_newExpiry","type":"uint256"},{"internalType":"uint256","name":"_renewalRate","type":"uint256"}],"name":"renewYield","outputs":[{"internalType":"uint256","name":"redeemedAmount","type":"uint256"},{"internalType":"uint256","name":"amountRenewed","type":"uint256"},{"internalType":"address","name":"ot","type":"address"},{"internalType":"address","name":"xyt","type":"address"},{"internalType":"uint256","name":"amountTokenMinted","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint256","name":"_inAmount","type":"uint256"},{"internalType":"uint256","name":"_minOutAmount","type":"uint256"},{"internalType":"bytes32","name":"_marketFactoryId","type":"bytes32"}],"name":"swapExactIn","outputs":[{"internalType":"uint256","name":"outSwapAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint256","name":"_outAmount","type":"uint256"},{"internalType":"uint256","name":"_maxInAmount","type":"uint256"},{"internalType":"bytes32","name":"_marketFactoryId","type":"bytes32"}],"name":"swapExactOut","outputs":[{"internalType":"uint256","name":"inSwapAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_forgeId","type":"bytes32"},{"internalType":"address","name":"_underlyingAsset","type":"address"},{"internalType":"uint256","name":"_expiry","type":"uint256"},{"internalType":"uint256","name":"_amountToTokenize","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"tokenizeYield","outputs":[{"internalType":"address","name":"ot","type":"address"},{"internalType":"address","name":"xyt","type":"address"},{"internalType":"uint256","name":"amountTokenMinted","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"sendTo","type":"address"}],"name":"withdrawEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"sendTo","type":"address"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60e06040523480156200001157600080fd5b5060405162004a4938038062004a498339810160408190526200003491620000cc565b826001600160a01b03811662000080576040805162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b604482015290519081900360640190fd5b600080546001600160601b0319606093841b811660805260ff60a01b196001600160a01b0319909216331791909116600160a01b1790915592811b831660a0521b1660c0525062000138565b600080600060608486031215620000e1578283fd5b8351620000ee816200011f565b602085015190935062000101816200011f565b604085015190925062000114816200011f565b809150509250925092565b6001600160a01b03811681146200013557600080fd5b50565b60805160601c60a05160601c60c05160601c61480962000240600039806104a752806106a7528061078c52806109495280610b765280610da65280610e755280610f395280610fdc528061130a528061151652806116bc528061177d52806119765280611a715280611b8f5280611e555280611f0d5280611fc15280612092528061223c5280612408528061252952806128e252806129c05280612b7f52806134015280613506525080610133528061044a528061048152806109235280610b50528061126452806114b952806114f052806117575280611b695280612b595280613060528061310452806132cc5280613358525080612afa5280612f0b52506148096000f3fe6080604052600436106101235760003560e01c806373d4a13a116100a0578063bd73897011610064578063bd73897014610375578063ce56c454146103a4578063d230566c146103c4578063d2e6d1c3146103e4578063e612b996146103f95761017b565b806373d4a13a146102de57806374f62c0d146102f35780637e6dbccf14610315578063825fedd214610335578063b7edadef146103555761017b565b80633ccdbb28116100e75780633ccdbb28146102385780633fc8cef3146102585780635697fae91461027a57806356c132cf146102ab578063640a06a8146102cb5761017b565b806309077c1f146101805780631251ae7c146101a9578063205b5fb7146101c957806339f46c31146101dc5780633a884f901461020a5761017b565b3661017b57336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101795760405162461bcd60e51b8152600401610170906145f0565b60405180910390fd5b005b600080fd5b61019361018e366004613c09565b61040c565b6040516101a091906141e1565b60405180910390f35b3480156101b557600080fd5b506101936101c4366004613ec0565b610686565b6101796101d7366004613d79565b6108c5565b3480156101e857600080fd5b506101fc6101f7366004613dca565b610b12565b6040516101a0929190614228565b34801561021657600080fd5b5061022a610225366004613e89565b610d54565b6040516101a0929190614067565b34801561024457600080fd5b50610179610253366004613fca565b611152565b34801561026457600080fd5b5061026d611262565b6040516101a09190614053565b34801561028657600080fd5b5061029a610295366004613f9a565b611286565b6040516101a09594939291906146b9565b3480156102b757600080fd5b506101936102c6366004613b61565b6112e9565b6101936102d9366004613c09565b61147b565b3480156102ea57600080fd5b5061026d6116ba565b610306610301366004613e25565b6116de565b6040516101a0939291906146e5565b34801561032157600080fd5b50610193610330366004613f09565b611955565b34801561034157600080fd5b506101fc610350366004613d15565b611b2b565b34801561036157600080fd5b5061026d610370366004613cd4565b611de8565b34801561038157600080fd5b50610395610390366004613f45565b6123e4565b6040516101a093929190614081565b3480156103b057600080fd5b506101796103bf366004614000565b612782565b3480156103d057600080fd5b506101936103df366004613e89565b6128c1565b3480156103f057600080fd5b5061026d612af8565b610193610407366004613d15565b612b1c565b6000610416612db0565b836104335760405162461bcd60e51b81526004016101709061425a565b858561043e82612ebd565b610448578761046a565b7f00000000000000000000000000000000000000000000000000000000000000005b975061047587612ebd565b61047f57866104a1565b7f00000000000000000000000000000000000000000000000000000000000000005b965060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b4238f498a8a886040518463ffffffff1660e01b81526004016104f593929190614081565b60206040518083038186803b15801561050d57600080fd5b505afa158015610521573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105459190613b45565b90506001600160a01b03811661056d5760405162461bcd60e51b815260040161017090614667565b610575613a68565b60405163055a7da960e21b81526001600160a01b03831690631569f6a4906105a7908d908b908e908e9060040161418c565b60a060405180830381600087803b1580156105c157600080fd5b505af11580156105d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f99190614024565b909550905061060a81858585612ee2565b336001600160a01b03167ff5fd10e802251a919c2bfd2cfc15e2526d3864c819e2b4dc346ca1ade0f516588b8b888c8760405161064b959493929190614143565b60405180910390a250506000805460001960ff600160a01b808404821692909201160260ff60a01b1990911617905550909695505050505050565b6000610690612db0565b6040516304a6060f60e51b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906394c0c1e0906106e090889088908890600401614209565b60206040518083038186803b1580156106f857600080fd5b505afa15801561070c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107309190613ca0565b61074c5760405162461bcd60e51b8152600401610170906143df565b6001600160a01b0382166107725760405162461bcd60e51b815260040161017090614493565b60405163288b600960e21b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a22d8024906107c19089906004016141e1565b60206040518083038186803b1580156107d957600080fd5b505afa1580156107ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108119190613b45565b60405163097660b960e01b81529091506001600160a01b0382169063097660b99061084490869089908990600401614081565b602060405180830381600087803b15801561085e57600080fd5b505af1158015610872573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108969190613cbc565b6000805460001960ff600160a01b808404821692909201160260ff60a01b199091161790559695505050505050565b6108cd612db0565b600082116108ed5760405162461bcd60e51b815260040161017090614468565b6000811161090d5760405162461bcd60e51b815260040161017090614403565b8261091781612ebd565b6109215783610943565b7f00000000000000000000000000000000000000000000000000000000000000005b935060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638e7cf7668888886040518463ffffffff1660e01b8152600401610997939291906141ea565b60206040518083038186803b1580156109af57600080fd5b505afa1580156109c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e79190613b45565b90506001600160a01b038116610a0f5760405162461bcd60e51b815260040161017090614667565b610a17613a68565b60405163a6f319bb60e01b81526000906001600160a01b0384169063a6f319bb90610a4a9033908a908a906004016140ce565b60a060405180830381600087803b158015610a6457600080fd5b505af1158015610a78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9c9190613c74565b9092509050610aad82898686612ee2565b336001600160a01b031660008051602061478a83398151915287878685604051610ada9493929190614236565b60405180910390a250506000805460001960ff600160a01b808404821692909201160260ff60a01b1990911617905550505050505050565b600080610b1d612db0565b84610b3a5760405162461bcd60e51b81526004016101709061461b565b85610b4481612ebd565b610b4e5786610b70565b7f00000000000000000000000000000000000000000000000000000000000000005b965060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638e7cf7668b8b8b6040518463ffffffff1660e01b8152600401610bc4939291906141ea565b60206040518083038186803b158015610bdc57600080fd5b505afa158015610bf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c149190613b45565b90506001600160a01b038116610c3c5760405162461bcd60e51b815260040161017090614667565b60405163834c295560e01b81526000906001600160a01b0383169063834c295590610c719033908c908c908c906004016140ef565b608060405180830381600087803b158015610c8b57600080fd5b505af1158015610c9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc39190613c59565b9050610cd1818b8585612ee2565b805151602082015151604051919650945033907f3af46289ed754c6821a8849534b8412a33bcd8387cb986f39e7e9937fb251cde90610d17908890889087908e90614236565b60405180910390a250506000805460001960ff600160a01b808404821692909201160260ff60a01b19909116179055509097909650945050505050565b600080610d5f612db0565b6001600160a01b038416610d855760405162461bcd60e51b815260040161017090614493565b428311610da45760405162461bcd60e51b81526004016101709061463f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e9e5f3cf6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dfd57600080fd5b505afa158015610e11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e359190613cbc565b8381610e3d57fe5b0615610e5b5760405162461bcd60e51b81526004016101709061463f565b60405163288b600960e21b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a22d802490610eaa9089906004016141e1565b60206040518083038186803b158015610ec257600080fd5b505afa158015610ed6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efa9190613b45565b90506001600160a01b038116610f225760405162461bcd60e51b8152600401610170906142b3565b604051631f019ead60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631f019ead90610f7290899089908990600401614209565b60206040518083038186803b158015610f8a57600080fd5b505afa158015610f9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc29190613b45565b604051631771964d60e21b81529093506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690635dc659349061101590899089908990600401614209565b60206040518083038186803b15801561102d57600080fd5b505afa158015611041573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110659190613b45565b91506001600160a01b03831615801561108557506001600160a01b038216155b6110a15760405162461bcd60e51b815260040161017090614431565b6040516304c2fceb60e51b81526001600160a01b0382169063985f9d60906110cf9088908890600401614173565b6040805180830381600087803b1580156110e857600080fd5b505af11580156110fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111209190613b99565b6000805460001960ff600160a01b808404821692909201160260ff60a01b199091161790559097909650945050505050565b61115a612f07565b6001600160a01b0316336001600160a01b0316146111b1576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6111ba83612f93565b6111ff576040805162461bcd60e51b81526020600482015260116024820152701513d2d15397d393d517d0531313d5d151607a1b604482015290519081900360640190fd5b6112136001600160a01b0384168284612f99565b604080516001600160a01b0380861682526020820185905283168183015290517f72cb8a894ddb372ceec3d2a7648d86f17d5a15caae0e986c53109b8a9a9385e69181900360600190a1505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000806000856000106112ae5760405162461bcd60e51b8152600401610170906144b9565b6112b98a898b6128c1565b94506112c58587612ff0565b93506112d48a898987336123e4565b969c959b509099509750939550919350505050565b60006112f3612db0565b6040516337649a6d60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636ec934da9061133f908690600401614053565b60206040518083038186803b15801561135757600080fd5b505afa15801561136b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138f9190613ca0565b6113ab5760405162461bcd60e51b815260040161017090614305565b6001600160a01b0382166113d15760405162461bcd60e51b815260040161017090614493565b604051633c12f35f60e21b81526001600160a01b0384169063f04bcd7c906113fd908590600401614053565b602060405180830381600087803b15801561141757600080fd5b505af115801561142b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144f9190613cbc565b6000805460001960ff600160a01b808404821692909201160260ff60a01b199091161790559392505050565b6000611485612db0565b836114a25760405162461bcd60e51b815260040161017090614691565b85856114ad82612ebd565b6114b757876114d9565b7f00000000000000000000000000000000000000000000000000000000000000005b97506114e487612ebd565b6114ee5786611510565b7f00000000000000000000000000000000000000000000000000000000000000005b965060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b4238f498a8a886040518463ffffffff1660e01b815260040161156493929190614081565b60206040518083038186803b15801561157c57600080fd5b505afa158015611590573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b49190613b45565b90506001600160a01b0381166115dc5760405162461bcd60e51b815260040161017090614667565b6115e4613a68565b604051637c2e4e7160e11b81526001600160a01b0383169063f85c9ce290611616908d908c908e908d9060040161418c565b60a060405180830381600087803b15801561163057600080fd5b505af1158015611644573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116689190614024565b909550905061167981858585612ee2565b336001600160a01b03167ff5fd10e802251a919c2bfd2cfc15e2526d3864c819e2b4dc346ca1ade0f516588b8b8b898760405161064b959493929190614143565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008060006116eb612db0565b86158015906116fa5750848710155b6117165760405162461bcd60e51b815260040161017090614568565b85158015906117255750838610155b6117415760405162461bcd60e51b81526004016101709061432d565b8761174b81612ebd565b6117555788611777565b7f00000000000000000000000000000000000000000000000000000000000000005b985060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638e7cf7668d8d8d6040518463ffffffff1660e01b81526004016117cb939291906141ea565b60206040518083038186803b1580156117e357600080fd5b505afa1580156117f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181b9190613b45565b90506001600160a01b0381166118435760405162461bcd60e51b815260040161017090614667565b61184b613a68565b60405163055392f960e11b81526001600160a01b03831690630aa725f29061187f9033908e908e908e908e90600401614115565b60a060405180830381600087803b15801561189957600080fd5b505af11580156118ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d19190613c74565b945090506118e1818d8585612ee2565b8051516020820151516040519197509550339060008051602061478a83398151915290611915908990899087908a90614236565b60405180910390a250506000805460001960ff600160a01b808404821692909201160260ff60a01b19909116179055509199909850909650945050505050565b600061195f612db0565b6040516304a6060f60e51b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906394c0c1e0906119af90889088908890600401614209565b60206040518083038186803b1580156119c757600080fd5b505afa1580156119db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ff9190613ca0565b611a1b5760405162461bcd60e51b8152600401610170906143df565b824210611a3a5760405162461bcd60e51b815260040161017090614283565b81611a575760405162461bcd60e51b815260040161017090614594565b60405163288b600960e21b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a22d802490611aa69089906004016141e1565b60206040518083038186803b158015611abe57600080fd5b505afa158015611ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af69190613b45565b604051631312bc7b60e31b81529091506001600160a01b03821690639895e3d8906108449033908990899089906004016140a5565b600080611b36612db0565b83611b535760405162461bcd60e51b81526004016101709061461b565b85611b5d81612ebd565b611b675786611b89565b7f00000000000000000000000000000000000000000000000000000000000000005b965060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638e7cf7668b8b8b6040518463ffffffff1660e01b8152600401611bdd939291906141ea565b60206040518083038186803b158015611bf557600080fd5b505afa158015611c09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2d9190613b45565b90506001600160a01b038116611c555760405162461bcd60e51b815260040161017090614667565b600087611c625788611c64565b895b90506000826001600160a01b0316630dd2cbb933848b8b6040518563ffffffff1660e01b8152600401611c9a94939291906140a5565b608060405180830381600087803b158015611cb457600080fd5b505af1158015611cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cec9190613c59565b9050600089611cfb5784611cfd565b8b5b9050611d12818360005b602002015186613024565b8915611d6d5781515160405133917f3af46289ed754c6821a8849534b8412a33bcd8387cb986f39e7e9937fb251cde91611d53919060009089908f90614236565b60405180910390a250515194506000935061112092505050565b81515160405133917f3af46289ed754c6821a8849534b8412a33bcd8387cb986f39e7e9937fb251cde91611da79160009189908f90614236565b60405180910390a25051516000805460ff60a01b198116600160a01b9182900460ff90811660001901169091021781559c909b509950505050505050505050565b6000611df2612db0565b6001600160a01b038316611e185760405162461bcd60e51b815260040161017090614493565b6001600160a01b038216611e3e5760405162461bcd60e51b815260040161017090614493565b604051631a209e5560e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631a209e5590611e8a908690600401614053565b60206040518083038186803b158015611ea257600080fd5b505afa158015611eb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eda9190613ca0565b611ef65760405162461bcd60e51b8152600401610170906143df565b604051631a209e5560e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631a209e5590611f42908590600401614053565b60206040518083038186803b158015611f5a57600080fd5b505afa158015611f6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f929190613ca0565b15611faf5760405162461bcd60e51b8152600401610170906145b9565b60405163473e7bb360e11b81526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690638e7cf76690612002908890889088906004016141ea565b60206040518083038186803b15801561201a57600080fd5b505afa15801561202e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120529190613b45565b6001600160a01b0316146120785760405162461bcd60e51b8152600401610170906144e7565b60405163c6069e4560e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c6069e45906120c79088906004016141e1565b60206040518083038186803b1580156120df57600080fd5b505afa1580156120f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121179190613b45565b90506001600160a01b03811661213f5760405162461bcd60e51b815260040161017090614493565b6000846001600160a01b0316636c6f42396040518163ffffffff1660e01b815260040160206040518083038186803b15801561217a57600080fd5b505afa15801561218e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b29190613b45565b6001600160a01b031663beb9a9736040518163ffffffff1660e01b815260040160206040518083038186803b1580156121ea57600080fd5b505afa1580156121fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122229190613cbc565b604051631ad19d3160e01b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631ad19d31906122739084908a90600401614228565b60206040518083038186803b15801561228b57600080fd5b505afa15801561229f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c39190613ca0565b6122df5760405162461bcd60e51b8152600401610170906143b0565b60405163103fe89360e11b81526001600160a01b0383169063207fd1269061230d9088908890600401614067565b602060405180830381600087803b15801561232757600080fd5b505af115801561233b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235f9190613b45565b9250826001600160a01b0316846001600160a01b0316866001600160a01b03167fb18af3690cc6a832c9b2e802aab7a21111f4cfca5c2e4fcf614f6ea55b405f4a896040516123ae91906141e1565b60405180910390a450506000805460001960ff600160a01b808404821692909201160260ff60a01b199091161790559392505050565b60008060006123f1612db0565b6040516304a6060f60e51b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906394c0c1e090612441908b908b908b90600401614209565b60206040518083038186803b15801561245957600080fd5b505afa15801561246d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124919190613ca0565b6124ad5760405162461bcd60e51b8152600401610170906143df565b8542106124cc5760405162461bcd60e51b815260040161017090614283565b6001600160a01b0384166124f25760405162461bcd60e51b815260040161017090614493565b8461250f5760405162461bcd60e51b815260040161017090614594565b60405163288b600960e21b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a22d80249061255e908c906004016141e1565b60206040518083038186803b15801561257657600080fd5b505afa15801561258a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ae9190613b45565b90506000816001600160a01b03166319d515ec8a6040518263ffffffff1660e01b81526004016125de9190614053565b602060405180830381600087803b1580156125f857600080fd5b505af115801561260c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126309190613b45565b90506126c633836001600160a01b03166339f4e3368c8c6040518363ffffffff1660e01b8152600401612664929190614173565b60206040518083038186803b15801561267c57600080fd5b505afa158015612690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b49190613b45565b6001600160a01b03841691908a6134aa565b6040516311e1c13360e31b81526001600160a01b03831690638f0e0998906126f8908c908c908c908c906004016141b6565b606060405180830381600087803b15801561271257600080fd5b505af1158015612726573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061274a9190613bc7565b6000805460001960ff600160a01b808404821692909201160260ff60a01b19909116179055919c909b50909950975050505050505050565b61278a612f07565b6001600160a01b0316336001600160a01b0316146127e1576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6040516000906001600160a01b0383169084908381818185875af1925050503d806000811461282c576040519150601f19603f3d011682016040523d82523d6000602084013e612831565b606091505b5050905080612879576040805162461bcd60e51b815260206004820152600f60248201526e15d2551211149055d7d19052531151608a1b604482015290519081900360640190fd5b604080518481526001600160a01b038416602082015281517fec47e7ed86c86774d1a72c19f35c639911393fe7c1a34031fdbd260890da90de929181900390910190a1505050565b60006128cb612db0565b6040516304a6060f60e51b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906394c0c1e09061291b90879087908790600401614209565b60206040518083038186803b15801561293357600080fd5b505afa158015612947573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296b9190613ca0565b6129875760405162461bcd60e51b8152600401610170906143df565b4282106129a65760405162461bcd60e51b815260040161017090614382565b60405163288b600960e21b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a22d8024906129f59088906004016141e1565b60206040518083038186803b158015612a0d57600080fd5b505afa158015612a21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a459190613b45565b60405163bdc6c01560e01b81529091506001600160a01b0382169063bdc6c01590612a7890339088908890600401614081565b602060405180830381600087803b158015612a9257600080fd5b505af1158015612aa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aca9190613cbc565b6000805460001960ff600160a01b808404821692909201160260ff60a01b1990911617905595945050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000612b26612db0565b82612b435760405162461bcd60e51b81526004016101709061435c565b84612b4d81612ebd565b612b575785612b79565b7f00000000000000000000000000000000000000000000000000000000000000005b955060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638e7cf7668a8a8a6040518463ffffffff1660e01b8152600401612bcd939291906141ea565b60206040518083038186803b158015612be557600080fd5b505afa158015612bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c1d9190613b45565b90506001600160a01b038116612c455760405162461bcd60e51b815260040161017090614667565b600086612c525782612c54565b885b9050600087612c635788612c65565b895b9050612c6f613a68565b60405163247d376f60e11b81526001600160a01b038516906348fa6ede90612ca190339086908d908d906004016140a5565b60a060405180830381600087803b158015612cbb57600080fd5b505af1158015612ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cf39190613c74565b965090508815612d3857336001600160a01b031660008051602061478a833981519152896000878a604051612d2b9493929190614236565b60405180910390a2612d6f565b336001600160a01b031660008051602061478a83398151915260008a878a604051612d669493929190614236565b60405180910390a25b612d7b83826000611d07565b50506000805460001960ff600160a01b808404821692909201160260ff60a01b19909116179055509198975050505050505050565b612db8613504565b6001600160a01b0316636ec934da336040518263ffffffff1660e01b8152600401612de39190614053565b60206040518083038186803b158015612dfb57600080fd5b505afa158015612e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e339190613ca0565b15612e6b576000546002600160a01b90910460ff161115612e665760405162461bcd60e51b8152600401610170906142dd565b612e97565b600054600160a01b900460ff16600114612e975760405162461bcd60e51b8152600401610170906142dd565b60008054600160ff600160a01b808404821692909201160260ff60a01b19909116179055565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14919050565b612ef5838560005b602002015183613024565b612f0182856001612eea565b50505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b158015612f6257600080fd5b505afa158015612f76573d6000803e3d6000fd5b505050506040513d6020811015612f8c57600080fd5b5051905090565b50600190565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612feb908490613528565b505050565b600061301b6501000000000061301561300986866135d9565b64800000000090613632565b9061368c565b90505b92915050565b815161302f57612feb565b8160200151156132055761304283612ebd565b156131e65781516040516323b872dd60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916323b872dd91613098918591309190600401614081565b602060405180830381600087803b1580156130b257600080fd5b505af11580156130c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ea9190613ca0565b508151604051632e1a7d4d60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691632e1a7d4d9161313891906004016141e1565b600060405180830381600087803b15801561315257600080fd5b505af1158015613166573d6000803e3d6000fd5b505083516040516000935033925061317d90614050565b60006040518083038185875af1925050503d80600081146131ba576040519150601f19603f3d011682016040523d82523d6000602084013e6131bf565b606091505b50509050806131e05760405162461bcd60e51b81526004016101709061453f565b50613200565b8151613200906001600160a01b03851690839033906134aa565b612feb565b61320e83612ebd565b156133ea5781513410156132345760405162461bcd60e51b81526004016101709061450f565b81516000906132449034906136f3565b905080156132ca576000336001600160a01b03168260405161326590614050565b60006040518083038185875af1925050503d80600081146132a2576040519150601f19603f3d011682016040523d82523d6000602084013e6132a7565b606091505b50509050806132c85760405162461bcd60e51b81526004016101709061453f565b505b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db084600001516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561332957600080fd5b505af115801561333d573d6000803e3d6000fd5b5050855160405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016945063a9059cbb93506133919250869190600401614173565b602060405180830381600087803b1580156133ab57600080fd5b505af11580156133bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133e39190613ca0565b5050612feb565b604051631a209e5560e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631a209e5590613436908690600401614053565b60206040518083038186803b15801561344e57600080fd5b505afa158015613462573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134869190613ca0565b156134945761349483613750565b8151612feb906001600160a01b03851690339084905b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612f01908590613528565b7f000000000000000000000000000000000000000000000000000000000000000090565b600061357d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661384a9092919063ffffffff16565b805190915015612feb5780806020019051602081101561359c57600080fd5b5051612feb5760405162461bcd60e51b815260040180806020018281038252602a8152602001806147aa602a913960400191505060405180910390fd5b6000826135e85750600061301e565b828202828482816135f557fe5b041461301b5760405162461bcd60e51b81526004018080602001828103825260218152602001806147696021913960400191505060405180910390fd5b60008282018381101561301b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008082116136e2576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b8183816136eb57fe5b049392505050565b60008282111561374a576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b604051636eb1769f60e11b81526000906001600160a01b0383169063dd62ed3e906137819033903090600401614067565b60206040518083038186803b15801561379957600080fd5b505afa1580156137ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137d19190613cbc565b90506001600160ff1b0381106137e75750613847565b60405163f259cd2760e01b81526001600160a01b0383169063f259cd2790613813903390600401614053565b600060405180830381600087803b15801561382d57600080fd5b505af1158015613841573d6000803e3d6000fd5b50505050505b50565b60606138598484600085613863565b90505b9392505050565b6060824710156138a45760405162461bcd60e51b81526004018080602001828103825260268152602001806147436026913960400191505060405180910390fd5b6138ad856139be565b6138fe576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b6020831061393c5780518252601f19909201916020918201910161391d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461399e576040519150601f19603f3d011682016040523d82523d6000602084013e6139a3565b606091505b50915091506139b38282866139c4565b979650505050505050565b3b151590565b606083156139d357508161385c565b8251156139e35782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613a2d578181015183820152602001613a15565b50505050905090810190601f168015613a5a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60405180604001604052806002905b613a7f613a95565b815260200190600190039081613a775790505090565b604080518082019091526000808252602082015290565b600082601f830112613abc578081fd5b6040613ac7816146fb565b808486608087011115613ad8578485fd5b845b6002811015613b3957848289031215613af1578586fd5b845185810181811067ffffffffffffffff82111715613b0c57fe5b865282518152602080840151613b2181614734565b82820152908552939093019290840190600101613ada565b50909695505050505050565b600060208284031215613b56578081fd5b815161301b8161471f565b60008060408385031215613b73578081fd5b8235613b7e8161471f565b91506020830135613b8e8161471f565b809150509250929050565b60008060408385031215613bab578182fd5b8251613bb68161471f565b6020840151909250613b8e8161471f565b600080600060608486031215613bdb578081fd5b8351613be68161471f565b6020850151909350613bf78161471f565b80925050604084015190509250925092565b600080600080600060a08688031215613c20578081fd5b8535613c2b8161471f565b94506020860135613c3b8161471f565b94979496505050506040830135926060810135926080909101359150565b600060808284031215613c6a578081fd5b61301b8383613aac565b60008060a08385031215613c86578182fd5b613c908484613aac565b9150608083015190509250929050565b600060208284031215613cb1578081fd5b815161301b81614734565b600060208284031215613ccd578081fd5b5051919050565b600080600060608486031215613ce8578283fd5b833592506020840135613cfa8161471f565b91506040840135613d0a8161471f565b809150509250925092565b60008060008060008060c08789031215613d2d578384fd5b863595506020870135613d3f8161471f565b94506040870135613d4f8161471f565b93506060870135613d5f81614734565b9598949750929560808101359460a0909101359350915050565b600080600080600060a08688031215613d90578283fd5b853594506020860135613da28161471f565b93506040860135613db28161471f565b94979396509394606081013594506080013592915050565b60008060008060008060c08789031215613de2578384fd5b863595506020870135613df48161471f565b94506040870135613e048161471f565b959894975094956060810135955060808101359460a0909101359350915050565b600080600080600080600060e0888a031215613e3f578485fd5b873596506020880135613e518161471f565b95506040880135613e618161471f565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b600080600060608486031215613e9d578081fd5b833592506020840135613eaf8161471f565b929592945050506040919091013590565b60008060008060808587031215613ed5578182fd5b843593506020850135613ee78161471f565b9250604085013591506060850135613efe8161471f565b939692955090935050565b60008060008060808587031215613f1e578182fd5b843593506020850135613f308161471f565b93969395505050506040820135916060013590565b600080600080600060a08688031215613f5c578283fd5b853594506020860135613f6e8161471f565b935060408601359250606086013591506080860135613f8c8161471f565b809150509295509295909350565b600080600080600060a08688031215613fb1578283fd5b85359450602086013593506040860135613db28161471f565b600080600060608486031215613fde578081fd5b8335613fe98161471f565b9250602084013591506040840135613d0a8161471f565b60008060408385031215614012578182fd5b823591506020830135613b8e8161471f565b60008060a08385031215614036578182fd5b825191506140478460208501613aac565b90509250929050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b6001600160a01b03959095168552602085019390935260408401919091526060830152608082015260a00190565b6001600160a01b039586168152938516602085015260408401929092526060830152909116608082015260a00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039485168152602081019390935292166040820152606081019190915260800190565b6001600160a01b03948516815260208101939093526040830191909152909116606082015260800190565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b9283526001600160a01b03919091166020830152604082015260600190565b918252602082015260400190565b93845260208401929092526001600160a01b03166040830152606082015260800190565b6020808252600f908201526e16915493d7d3d55517d05353d55395608a1b604082015260600190565b602080825260169082015275165251531117d0d3d395149050d517d156141254915160521b604082015260600190565b60208082526010908201526f464f5247455f4e4f545f45584953545360801b604082015260600190565b6020808252600e908201526d14915153951490539517d0d0531360921b604082015260600190565b6020808252600e908201526d1253959053125117d3505492d15560921b604082015260600190565b602080825260159082015274494e56414c49445f544f4b454e5f414d4f554e545360581b604082015260600190565b6020808252600c908201526b5a45524f5f414d4f554e545360a01b604082015260600190565b6020808252601490820152734d5553545f42455f41465445525f45585049525960601b604082015260600190565b602080825260159082015274494e56414c49445f464f5247455f464143544f525960581b604082015260600190565b6020808252600a90820152691253959053125117d65560b21b604082015260600190565b6020808252601490820152731253959053125117d513d2d15397d05353d5539560621b604082015260600190565b60208082526018908201527f4455504c49434154455f5949454c445f434f4e54524143540000000000000000604082015260600190565b6020808252601190820152701253959053125117d65517d05353d55395607a1b604082015260600190565b6020808252600c908201526b5a45524f5f4144445245535360a01b604082015260600190565b602080825260149082015273494e56414c49445f52454e4557414c5f5241544560601b604082015260600190565b6020808252600e908201526d11561254d5115117d3505492d15560921b604082015260600190565b602080825260169082015275125394d551919250d1539517d1551217d05353d5539560521b604082015260600190565b6020808252600f908201526e1514905394d1915497d19052531151608a1b604082015260600190565b602080825260129082015271494e56414c49445f59545f414d4f554e545360701b604082015260600190565b6020808252600b908201526a16915493d7d05353d5539560aa1b604082015260600190565b60208082526017908201527f59545f51554f54455f504149525f464f5242494444454e000000000000000000604082015260600190565b60208082526011908201527008aa890be9c9ea8be8ca49e9abeae8aa89607b1b604082015260600190565b6020808252600a90820152692d22a927afa6282fa4a760b11b604082015260600190565b6020808252600e908201526d494e56414c49445f45585049525960901b604082015260600190565b60208082526010908201526f13505492d15517d393d517d193d5539160821b604082015260600190565b6020808252600e908201526d16915493d7d25397d05353d5539560921b604082015260600190565b94855260208501939093526001600160a01b039182166040850152166060830152608082015260a00190565b9283526020830191909152604082015260600190565b60405181810167ffffffffffffffff8111828210171561471757fe5b604052919050565b6001600160a01b038116811461384757600080fd5b801515811461384757600080fdfe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77e37fea01e65dea7d589abafc4bd0d5282a09ddce3e9ea971ed3399d776a1a2965361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212209626ffd93186e1b8f8d1dca57ff67323512eb5b53bb896d8c2322bc538e936f664736f6c634300070600330000000000000000000000009b528bf0639fc31ae6d698c48d830873227741f1000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d6
Deployed Bytecode
0x6080604052600436106101235760003560e01c806373d4a13a116100a0578063bd73897011610064578063bd73897014610375578063ce56c454146103a4578063d230566c146103c4578063d2e6d1c3146103e4578063e612b996146103f95761017b565b806373d4a13a146102de57806374f62c0d146102f35780637e6dbccf14610315578063825fedd214610335578063b7edadef146103555761017b565b80633ccdbb28116100e75780633ccdbb28146102385780633fc8cef3146102585780635697fae91461027a57806356c132cf146102ab578063640a06a8146102cb5761017b565b806309077c1f146101805780631251ae7c146101a9578063205b5fb7146101c957806339f46c31146101dc5780633a884f901461020a5761017b565b3661017b57336001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216146101795760405162461bcd60e51b8152600401610170906145f0565b60405180910390fd5b005b600080fd5b61019361018e366004613c09565b61040c565b6040516101a091906141e1565b60405180910390f35b3480156101b557600080fd5b506101936101c4366004613ec0565b610686565b6101796101d7366004613d79565b6108c5565b3480156101e857600080fd5b506101fc6101f7366004613dca565b610b12565b6040516101a0929190614228565b34801561021657600080fd5b5061022a610225366004613e89565b610d54565b6040516101a0929190614067565b34801561024457600080fd5b50610179610253366004613fca565b611152565b34801561026457600080fd5b5061026d611262565b6040516101a09190614053565b34801561028657600080fd5b5061029a610295366004613f9a565b611286565b6040516101a09594939291906146b9565b3480156102b757600080fd5b506101936102c6366004613b61565b6112e9565b6101936102d9366004613c09565b61147b565b3480156102ea57600080fd5b5061026d6116ba565b610306610301366004613e25565b6116de565b6040516101a0939291906146e5565b34801561032157600080fd5b50610193610330366004613f09565b611955565b34801561034157600080fd5b506101fc610350366004613d15565b611b2b565b34801561036157600080fd5b5061026d610370366004613cd4565b611de8565b34801561038157600080fd5b50610395610390366004613f45565b6123e4565b6040516101a093929190614081565b3480156103b057600080fd5b506101796103bf366004614000565b612782565b3480156103d057600080fd5b506101936103df366004613e89565b6128c1565b3480156103f057600080fd5b5061026d612af8565b610193610407366004613d15565b612b1c565b6000610416612db0565b836104335760405162461bcd60e51b81526004016101709061425a565b858561043e82612ebd565b610448578761046a565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b975061047587612ebd565b61047f57866104a1565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b965060007f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d66001600160a01b031663b4238f498a8a886040518463ffffffff1660e01b81526004016104f593929190614081565b60206040518083038186803b15801561050d57600080fd5b505afa158015610521573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105459190613b45565b90506001600160a01b03811661056d5760405162461bcd60e51b815260040161017090614667565b610575613a68565b60405163055a7da960e21b81526001600160a01b03831690631569f6a4906105a7908d908b908e908e9060040161418c565b60a060405180830381600087803b1580156105c157600080fd5b505af11580156105d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f99190614024565b909550905061060a81858585612ee2565b336001600160a01b03167ff5fd10e802251a919c2bfd2cfc15e2526d3864c819e2b4dc346ca1ade0f516588b8b888c8760405161064b959493929190614143565b60405180910390a250506000805460001960ff600160a01b808404821692909201160260ff60a01b1990911617905550909695505050505050565b6000610690612db0565b6040516304a6060f60e51b81526001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d616906394c0c1e0906106e090889088908890600401614209565b60206040518083038186803b1580156106f857600080fd5b505afa15801561070c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107309190613ca0565b61074c5760405162461bcd60e51b8152600401610170906143df565b6001600160a01b0382166107725760405162461bcd60e51b815260040161017090614493565b60405163288b600960e21b81526000906001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d6169063a22d8024906107c19089906004016141e1565b60206040518083038186803b1580156107d957600080fd5b505afa1580156107ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108119190613b45565b60405163097660b960e01b81529091506001600160a01b0382169063097660b99061084490869089908990600401614081565b602060405180830381600087803b15801561085e57600080fd5b505af1158015610872573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108969190613cbc565b6000805460001960ff600160a01b808404821692909201160260ff60a01b199091161790559695505050505050565b6108cd612db0565b600082116108ed5760405162461bcd60e51b815260040161017090614468565b6000811161090d5760405162461bcd60e51b815260040161017090614403565b8261091781612ebd565b6109215783610943565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b935060007f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d66001600160a01b0316638e7cf7668888886040518463ffffffff1660e01b8152600401610997939291906141ea565b60206040518083038186803b1580156109af57600080fd5b505afa1580156109c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e79190613b45565b90506001600160a01b038116610a0f5760405162461bcd60e51b815260040161017090614667565b610a17613a68565b60405163a6f319bb60e01b81526000906001600160a01b0384169063a6f319bb90610a4a9033908a908a906004016140ce565b60a060405180830381600087803b158015610a6457600080fd5b505af1158015610a78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9c9190613c74565b9092509050610aad82898686612ee2565b336001600160a01b031660008051602061478a83398151915287878685604051610ada9493929190614236565b60405180910390a250506000805460001960ff600160a01b808404821692909201160260ff60a01b1990911617905550505050505050565b600080610b1d612db0565b84610b3a5760405162461bcd60e51b81526004016101709061461b565b85610b4481612ebd565b610b4e5786610b70565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b965060007f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d66001600160a01b0316638e7cf7668b8b8b6040518463ffffffff1660e01b8152600401610bc4939291906141ea565b60206040518083038186803b158015610bdc57600080fd5b505afa158015610bf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c149190613b45565b90506001600160a01b038116610c3c5760405162461bcd60e51b815260040161017090614667565b60405163834c295560e01b81526000906001600160a01b0383169063834c295590610c719033908c908c908c906004016140ef565b608060405180830381600087803b158015610c8b57600080fd5b505af1158015610c9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc39190613c59565b9050610cd1818b8585612ee2565b805151602082015151604051919650945033907f3af46289ed754c6821a8849534b8412a33bcd8387cb986f39e7e9937fb251cde90610d17908890889087908e90614236565b60405180910390a250506000805460001960ff600160a01b808404821692909201160260ff60a01b19909116179055509097909650945050505050565b600080610d5f612db0565b6001600160a01b038416610d855760405162461bcd60e51b815260040161017090614493565b428311610da45760405162461bcd60e51b81526004016101709061463f565b7f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d66001600160a01b031663e9e5f3cf6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dfd57600080fd5b505afa158015610e11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e359190613cbc565b8381610e3d57fe5b0615610e5b5760405162461bcd60e51b81526004016101709061463f565b60405163288b600960e21b81526000906001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d6169063a22d802490610eaa9089906004016141e1565b60206040518083038186803b158015610ec257600080fd5b505afa158015610ed6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efa9190613b45565b90506001600160a01b038116610f225760405162461bcd60e51b8152600401610170906142b3565b604051631f019ead60e01b81526001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d61690631f019ead90610f7290899089908990600401614209565b60206040518083038186803b158015610f8a57600080fd5b505afa158015610f9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc29190613b45565b604051631771964d60e21b81529093506001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d61690635dc659349061101590899089908990600401614209565b60206040518083038186803b15801561102d57600080fd5b505afa158015611041573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110659190613b45565b91506001600160a01b03831615801561108557506001600160a01b038216155b6110a15760405162461bcd60e51b815260040161017090614431565b6040516304c2fceb60e51b81526001600160a01b0382169063985f9d60906110cf9088908890600401614173565b6040805180830381600087803b1580156110e857600080fd5b505af11580156110fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111209190613b99565b6000805460001960ff600160a01b808404821692909201160260ff60a01b199091161790559097909650945050505050565b61115a612f07565b6001600160a01b0316336001600160a01b0316146111b1576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6111ba83612f93565b6111ff576040805162461bcd60e51b81526020600482015260116024820152701513d2d15397d393d517d0531313d5d151607a1b604482015290519081900360640190fd5b6112136001600160a01b0384168284612f99565b604080516001600160a01b0380861682526020820185905283168183015290517f72cb8a894ddb372ceec3d2a7648d86f17d5a15caae0e986c53109b8a9a9385e69181900360600190a1505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6000806000806000856000106112ae5760405162461bcd60e51b8152600401610170906144b9565b6112b98a898b6128c1565b94506112c58587612ff0565b93506112d48a898987336123e4565b969c959b509099509750939550919350505050565b60006112f3612db0565b6040516337649a6d60e11b81526001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d61690636ec934da9061133f908690600401614053565b60206040518083038186803b15801561135757600080fd5b505afa15801561136b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138f9190613ca0565b6113ab5760405162461bcd60e51b815260040161017090614305565b6001600160a01b0382166113d15760405162461bcd60e51b815260040161017090614493565b604051633c12f35f60e21b81526001600160a01b0384169063f04bcd7c906113fd908590600401614053565b602060405180830381600087803b15801561141757600080fd5b505af115801561142b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144f9190613cbc565b6000805460001960ff600160a01b808404821692909201160260ff60a01b199091161790559392505050565b6000611485612db0565b836114a25760405162461bcd60e51b815260040161017090614691565b85856114ad82612ebd565b6114b757876114d9565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b97506114e487612ebd565b6114ee5786611510565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b965060007f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d66001600160a01b031663b4238f498a8a886040518463ffffffff1660e01b815260040161156493929190614081565b60206040518083038186803b15801561157c57600080fd5b505afa158015611590573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b49190613b45565b90506001600160a01b0381166115dc5760405162461bcd60e51b815260040161017090614667565b6115e4613a68565b604051637c2e4e7160e11b81526001600160a01b0383169063f85c9ce290611616908d908c908e908d9060040161418c565b60a060405180830381600087803b15801561163057600080fd5b505af1158015611644573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116689190614024565b909550905061167981858585612ee2565b336001600160a01b03167ff5fd10e802251a919c2bfd2cfc15e2526d3864c819e2b4dc346ca1ade0f516588b8b8b898760405161064b959493929190614143565b7f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d681565b60008060006116eb612db0565b86158015906116fa5750848710155b6117165760405162461bcd60e51b815260040161017090614568565b85158015906117255750838610155b6117415760405162461bcd60e51b81526004016101709061432d565b8761174b81612ebd565b6117555788611777565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b985060007f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d66001600160a01b0316638e7cf7668d8d8d6040518463ffffffff1660e01b81526004016117cb939291906141ea565b60206040518083038186803b1580156117e357600080fd5b505afa1580156117f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181b9190613b45565b90506001600160a01b0381166118435760405162461bcd60e51b815260040161017090614667565b61184b613a68565b60405163055392f960e11b81526001600160a01b03831690630aa725f29061187f9033908e908e908e908e90600401614115565b60a060405180830381600087803b15801561189957600080fd5b505af11580156118ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d19190613c74565b945090506118e1818d8585612ee2565b8051516020820151516040519197509550339060008051602061478a83398151915290611915908990899087908a90614236565b60405180910390a250506000805460001960ff600160a01b808404821692909201160260ff60a01b19909116179055509199909850909650945050505050565b600061195f612db0565b6040516304a6060f60e51b81526001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d616906394c0c1e0906119af90889088908890600401614209565b60206040518083038186803b1580156119c757600080fd5b505afa1580156119db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ff9190613ca0565b611a1b5760405162461bcd60e51b8152600401610170906143df565b824210611a3a5760405162461bcd60e51b815260040161017090614283565b81611a575760405162461bcd60e51b815260040161017090614594565b60405163288b600960e21b81526000906001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d6169063a22d802490611aa69089906004016141e1565b60206040518083038186803b158015611abe57600080fd5b505afa158015611ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af69190613b45565b604051631312bc7b60e31b81529091506001600160a01b03821690639895e3d8906108449033908990899089906004016140a5565b600080611b36612db0565b83611b535760405162461bcd60e51b81526004016101709061461b565b85611b5d81612ebd565b611b675786611b89565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b965060007f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d66001600160a01b0316638e7cf7668b8b8b6040518463ffffffff1660e01b8152600401611bdd939291906141ea565b60206040518083038186803b158015611bf557600080fd5b505afa158015611c09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2d9190613b45565b90506001600160a01b038116611c555760405162461bcd60e51b815260040161017090614667565b600087611c625788611c64565b895b90506000826001600160a01b0316630dd2cbb933848b8b6040518563ffffffff1660e01b8152600401611c9a94939291906140a5565b608060405180830381600087803b158015611cb457600080fd5b505af1158015611cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cec9190613c59565b9050600089611cfb5784611cfd565b8b5b9050611d12818360005b602002015186613024565b8915611d6d5781515160405133917f3af46289ed754c6821a8849534b8412a33bcd8387cb986f39e7e9937fb251cde91611d53919060009089908f90614236565b60405180910390a250515194506000935061112092505050565b81515160405133917f3af46289ed754c6821a8849534b8412a33bcd8387cb986f39e7e9937fb251cde91611da79160009189908f90614236565b60405180910390a25051516000805460ff60a01b198116600160a01b9182900460ff90811660001901169091021781559c909b509950505050505050505050565b6000611df2612db0565b6001600160a01b038316611e185760405162461bcd60e51b815260040161017090614493565b6001600160a01b038216611e3e5760405162461bcd60e51b815260040161017090614493565b604051631a209e5560e01b81526001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d61690631a209e5590611e8a908690600401614053565b60206040518083038186803b158015611ea257600080fd5b505afa158015611eb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eda9190613ca0565b611ef65760405162461bcd60e51b8152600401610170906143df565b604051631a209e5560e01b81526001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d61690631a209e5590611f42908590600401614053565b60206040518083038186803b158015611f5a57600080fd5b505afa158015611f6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f929190613ca0565b15611faf5760405162461bcd60e51b8152600401610170906145b9565b60405163473e7bb360e11b81526000907f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d66001600160a01b031690638e7cf76690612002908890889088906004016141ea565b60206040518083038186803b15801561201a57600080fd5b505afa15801561202e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120529190613b45565b6001600160a01b0316146120785760405162461bcd60e51b8152600401610170906144e7565b60405163c6069e4560e01b81526000906001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d6169063c6069e45906120c79088906004016141e1565b60206040518083038186803b1580156120df57600080fd5b505afa1580156120f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121179190613b45565b90506001600160a01b03811661213f5760405162461bcd60e51b815260040161017090614493565b6000846001600160a01b0316636c6f42396040518163ffffffff1660e01b815260040160206040518083038186803b15801561217a57600080fd5b505afa15801561218e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b29190613b45565b6001600160a01b031663beb9a9736040518163ffffffff1660e01b815260040160206040518083038186803b1580156121ea57600080fd5b505afa1580156121fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122229190613cbc565b604051631ad19d3160e01b81529091506001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d61690631ad19d31906122739084908a90600401614228565b60206040518083038186803b15801561228b57600080fd5b505afa15801561229f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c39190613ca0565b6122df5760405162461bcd60e51b8152600401610170906143b0565b60405163103fe89360e11b81526001600160a01b0383169063207fd1269061230d9088908890600401614067565b602060405180830381600087803b15801561232757600080fd5b505af115801561233b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235f9190613b45565b9250826001600160a01b0316846001600160a01b0316866001600160a01b03167fb18af3690cc6a832c9b2e802aab7a21111f4cfca5c2e4fcf614f6ea55b405f4a896040516123ae91906141e1565b60405180910390a450506000805460001960ff600160a01b808404821692909201160260ff60a01b199091161790559392505050565b60008060006123f1612db0565b6040516304a6060f60e51b81526001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d616906394c0c1e090612441908b908b908b90600401614209565b60206040518083038186803b15801561245957600080fd5b505afa15801561246d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124919190613ca0565b6124ad5760405162461bcd60e51b8152600401610170906143df565b8542106124cc5760405162461bcd60e51b815260040161017090614283565b6001600160a01b0384166124f25760405162461bcd60e51b815260040161017090614493565b8461250f5760405162461bcd60e51b815260040161017090614594565b60405163288b600960e21b81526000906001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d6169063a22d80249061255e908c906004016141e1565b60206040518083038186803b15801561257657600080fd5b505afa15801561258a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ae9190613b45565b90506000816001600160a01b03166319d515ec8a6040518263ffffffff1660e01b81526004016125de9190614053565b602060405180830381600087803b1580156125f857600080fd5b505af115801561260c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126309190613b45565b90506126c633836001600160a01b03166339f4e3368c8c6040518363ffffffff1660e01b8152600401612664929190614173565b60206040518083038186803b15801561267c57600080fd5b505afa158015612690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b49190613b45565b6001600160a01b03841691908a6134aa565b6040516311e1c13360e31b81526001600160a01b03831690638f0e0998906126f8908c908c908c908c906004016141b6565b606060405180830381600087803b15801561271257600080fd5b505af1158015612726573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061274a9190613bc7565b6000805460001960ff600160a01b808404821692909201160260ff60a01b19909116179055919c909b50909950975050505050505050565b61278a612f07565b6001600160a01b0316336001600160a01b0316146127e1576040805162461bcd60e51b815260206004820152600f60248201526e4f4e4c595f474f5645524e414e434560881b604482015290519081900360640190fd5b6040516000906001600160a01b0383169084908381818185875af1925050503d806000811461282c576040519150601f19603f3d011682016040523d82523d6000602084013e612831565b606091505b5050905080612879576040805162461bcd60e51b815260206004820152600f60248201526e15d2551211149055d7d19052531151608a1b604482015290519081900360640190fd5b604080518481526001600160a01b038416602082015281517fec47e7ed86c86774d1a72c19f35c639911393fe7c1a34031fdbd260890da90de929181900390910190a1505050565b60006128cb612db0565b6040516304a6060f60e51b81526001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d616906394c0c1e09061291b90879087908790600401614209565b60206040518083038186803b15801561293357600080fd5b505afa158015612947573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061296b9190613ca0565b6129875760405162461bcd60e51b8152600401610170906143df565b4282106129a65760405162461bcd60e51b815260040161017090614382565b60405163288b600960e21b81526000906001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d6169063a22d8024906129f59088906004016141e1565b60206040518083038186803b158015612a0d57600080fd5b505afa158015612a21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a459190613b45565b60405163bdc6c01560e01b81529091506001600160a01b0382169063bdc6c01590612a7890339088908890600401614081565b602060405180830381600087803b158015612a9257600080fd5b505af1158015612aa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aca9190613cbc565b6000805460001960ff600160a01b808404821692909201160260ff60a01b1990911617905595945050505050565b7f0000000000000000000000009b528bf0639fc31ae6d698c48d830873227741f181565b6000612b26612db0565b82612b435760405162461bcd60e51b81526004016101709061435c565b84612b4d81612ebd565b612b575785612b79565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b955060007f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d66001600160a01b0316638e7cf7668a8a8a6040518463ffffffff1660e01b8152600401612bcd939291906141ea565b60206040518083038186803b158015612be557600080fd5b505afa158015612bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c1d9190613b45565b90506001600160a01b038116612c455760405162461bcd60e51b815260040161017090614667565b600086612c525782612c54565b885b9050600087612c635788612c65565b895b9050612c6f613a68565b60405163247d376f60e11b81526001600160a01b038516906348fa6ede90612ca190339086908d908d906004016140a5565b60a060405180830381600087803b158015612cbb57600080fd5b505af1158015612ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cf39190613c74565b965090508815612d3857336001600160a01b031660008051602061478a833981519152896000878a604051612d2b9493929190614236565b60405180910390a2612d6f565b336001600160a01b031660008051602061478a83398151915260008a878a604051612d669493929190614236565b60405180910390a25b612d7b83826000611d07565b50506000805460001960ff600160a01b808404821692909201160260ff60a01b19909116179055509198975050505050505050565b612db8613504565b6001600160a01b0316636ec934da336040518263ffffffff1660e01b8152600401612de39190614053565b60206040518083038186803b158015612dfb57600080fd5b505afa158015612e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e339190613ca0565b15612e6b576000546002600160a01b90910460ff161115612e665760405162461bcd60e51b8152600401610170906142dd565b612e97565b600054600160a01b900460ff16600114612e975760405162461bcd60e51b8152600401610170906142dd565b60008054600160ff600160a01b808404821692909201160260ff60a01b19909116179055565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14919050565b612ef5838560005b602002015183613024565b612f0182856001612eea565b50505050565b60007f0000000000000000000000009b528bf0639fc31ae6d698c48d830873227741f16001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b158015612f6257600080fd5b505afa158015612f76573d6000803e3d6000fd5b505050506040513d6020811015612f8c57600080fd5b5051905090565b50600190565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612feb908490613528565b505050565b600061301b6501000000000061301561300986866135d9565b64800000000090613632565b9061368c565b90505b92915050565b815161302f57612feb565b8160200151156132055761304283612ebd565b156131e65781516040516323b872dd60e01b81526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216916323b872dd91613098918591309190600401614081565b602060405180830381600087803b1580156130b257600080fd5b505af11580156130c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ea9190613ca0565b508151604051632e1a7d4d60e01b81526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21691632e1a7d4d9161313891906004016141e1565b600060405180830381600087803b15801561315257600080fd5b505af1158015613166573d6000803e3d6000fd5b505083516040516000935033925061317d90614050565b60006040518083038185875af1925050503d80600081146131ba576040519150601f19603f3d011682016040523d82523d6000602084013e6131bf565b606091505b50509050806131e05760405162461bcd60e51b81526004016101709061453f565b50613200565b8151613200906001600160a01b03851690839033906134aa565b612feb565b61320e83612ebd565b156133ea5781513410156132345760405162461bcd60e51b81526004016101709061450f565b81516000906132449034906136f3565b905080156132ca576000336001600160a01b03168260405161326590614050565b60006040518083038185875af1925050503d80600081146132a2576040519150601f19603f3d011682016040523d82523d6000602084013e6132a7565b606091505b50509050806132c85760405162461bcd60e51b81526004016101709061453f565b505b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db084600001516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561332957600080fd5b505af115801561333d573d6000803e3d6000fd5b5050855160405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216945063a9059cbb93506133919250869190600401614173565b602060405180830381600087803b1580156133ab57600080fd5b505af11580156133bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133e39190613ca0565b5050612feb565b604051631a209e5560e01b81526001600160a01b037f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d61690631a209e5590613436908690600401614053565b60206040518083038186803b15801561344e57600080fd5b505afa158015613462573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134869190613ca0565b156134945761349483613750565b8151612feb906001600160a01b03851690339084905b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612f01908590613528565b7f000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d690565b600061357d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661384a9092919063ffffffff16565b805190915015612feb5780806020019051602081101561359c57600080fd5b5051612feb5760405162461bcd60e51b815260040180806020018281038252602a8152602001806147aa602a913960400191505060405180910390fd5b6000826135e85750600061301e565b828202828482816135f557fe5b041461301b5760405162461bcd60e51b81526004018080602001828103825260218152602001806147696021913960400191505060405180910390fd5b60008282018381101561301b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008082116136e2576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b8183816136eb57fe5b049392505050565b60008282111561374a576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b604051636eb1769f60e11b81526000906001600160a01b0383169063dd62ed3e906137819033903090600401614067565b60206040518083038186803b15801561379957600080fd5b505afa1580156137ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137d19190613cbc565b90506001600160ff1b0381106137e75750613847565b60405163f259cd2760e01b81526001600160a01b0383169063f259cd2790613813903390600401614053565b600060405180830381600087803b15801561382d57600080fd5b505af1158015613841573d6000803e3d6000fd5b50505050505b50565b60606138598484600085613863565b90505b9392505050565b6060824710156138a45760405162461bcd60e51b81526004018080602001828103825260268152602001806147436026913960400191505060405180910390fd5b6138ad856139be565b6138fe576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b6020831061393c5780518252601f19909201916020918201910161391d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461399e576040519150601f19603f3d011682016040523d82523d6000602084013e6139a3565b606091505b50915091506139b38282866139c4565b979650505050505050565b3b151590565b606083156139d357508161385c565b8251156139e35782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613a2d578181015183820152602001613a15565b50505050905090810190601f168015613a5a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60405180604001604052806002905b613a7f613a95565b815260200190600190039081613a775790505090565b604080518082019091526000808252602082015290565b600082601f830112613abc578081fd5b6040613ac7816146fb565b808486608087011115613ad8578485fd5b845b6002811015613b3957848289031215613af1578586fd5b845185810181811067ffffffffffffffff82111715613b0c57fe5b865282518152602080840151613b2181614734565b82820152908552939093019290840190600101613ada565b50909695505050505050565b600060208284031215613b56578081fd5b815161301b8161471f565b60008060408385031215613b73578081fd5b8235613b7e8161471f565b91506020830135613b8e8161471f565b809150509250929050565b60008060408385031215613bab578182fd5b8251613bb68161471f565b6020840151909250613b8e8161471f565b600080600060608486031215613bdb578081fd5b8351613be68161471f565b6020850151909350613bf78161471f565b80925050604084015190509250925092565b600080600080600060a08688031215613c20578081fd5b8535613c2b8161471f565b94506020860135613c3b8161471f565b94979496505050506040830135926060810135926080909101359150565b600060808284031215613c6a578081fd5b61301b8383613aac565b60008060a08385031215613c86578182fd5b613c908484613aac565b9150608083015190509250929050565b600060208284031215613cb1578081fd5b815161301b81614734565b600060208284031215613ccd578081fd5b5051919050565b600080600060608486031215613ce8578283fd5b833592506020840135613cfa8161471f565b91506040840135613d0a8161471f565b809150509250925092565b60008060008060008060c08789031215613d2d578384fd5b863595506020870135613d3f8161471f565b94506040870135613d4f8161471f565b93506060870135613d5f81614734565b9598949750929560808101359460a0909101359350915050565b600080600080600060a08688031215613d90578283fd5b853594506020860135613da28161471f565b93506040860135613db28161471f565b94979396509394606081013594506080013592915050565b60008060008060008060c08789031215613de2578384fd5b863595506020870135613df48161471f565b94506040870135613e048161471f565b959894975094956060810135955060808101359460a0909101359350915050565b600080600080600080600060e0888a031215613e3f578485fd5b873596506020880135613e518161471f565b95506040880135613e618161471f565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b600080600060608486031215613e9d578081fd5b833592506020840135613eaf8161471f565b929592945050506040919091013590565b60008060008060808587031215613ed5578182fd5b843593506020850135613ee78161471f565b9250604085013591506060850135613efe8161471f565b939692955090935050565b60008060008060808587031215613f1e578182fd5b843593506020850135613f308161471f565b93969395505050506040820135916060013590565b600080600080600060a08688031215613f5c578283fd5b853594506020860135613f6e8161471f565b935060408601359250606086013591506080860135613f8c8161471f565b809150509295509295909350565b600080600080600060a08688031215613fb1578283fd5b85359450602086013593506040860135613db28161471f565b600080600060608486031215613fde578081fd5b8335613fe98161471f565b9250602084013591506040840135613d0a8161471f565b60008060408385031215614012578182fd5b823591506020830135613b8e8161471f565b60008060a08385031215614036578182fd5b825191506140478460208501613aac565b90509250929050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b6001600160a01b03959095168552602085019390935260408401919091526060830152608082015260a00190565b6001600160a01b039586168152938516602085015260408401929092526060830152909116608082015260a00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039485168152602081019390935292166040820152606081019190915260800190565b6001600160a01b03948516815260208101939093526040830191909152909116606082015260800190565b90815260200190565b9283526001600160a01b03918216602084015216604082015260600190565b9283526001600160a01b03919091166020830152604082015260600190565b918252602082015260400190565b93845260208401929092526001600160a01b03166040830152606082015260800190565b6020808252600f908201526e16915493d7d3d55517d05353d55395608a1b604082015260600190565b602080825260169082015275165251531117d0d3d395149050d517d156141254915160521b604082015260600190565b60208082526010908201526f464f5247455f4e4f545f45584953545360801b604082015260600190565b6020808252600e908201526d14915153951490539517d0d0531360921b604082015260600190565b6020808252600e908201526d1253959053125117d3505492d15560921b604082015260600190565b602080825260159082015274494e56414c49445f544f4b454e5f414d4f554e545360581b604082015260600190565b6020808252600c908201526b5a45524f5f414d4f554e545360a01b604082015260600190565b6020808252601490820152734d5553545f42455f41465445525f45585049525960601b604082015260600190565b602080825260159082015274494e56414c49445f464f5247455f464143544f525960581b604082015260600190565b6020808252600a90820152691253959053125117d65560b21b604082015260600190565b6020808252601490820152731253959053125117d513d2d15397d05353d5539560621b604082015260600190565b60208082526018908201527f4455504c49434154455f5949454c445f434f4e54524143540000000000000000604082015260600190565b6020808252601190820152701253959053125117d65517d05353d55395607a1b604082015260600190565b6020808252600c908201526b5a45524f5f4144445245535360a01b604082015260600190565b602080825260149082015273494e56414c49445f52454e4557414c5f5241544560601b604082015260600190565b6020808252600e908201526d11561254d5115117d3505492d15560921b604082015260600190565b602080825260169082015275125394d551919250d1539517d1551217d05353d5539560521b604082015260600190565b6020808252600f908201526e1514905394d1915497d19052531151608a1b604082015260600190565b602080825260129082015271494e56414c49445f59545f414d4f554e545360701b604082015260600190565b6020808252600b908201526a16915493d7d05353d5539560aa1b604082015260600190565b60208082526017908201527f59545f51554f54455f504149525f464f5242494444454e000000000000000000604082015260600190565b60208082526011908201527008aa890be9c9ea8be8ca49e9abeae8aa89607b1b604082015260600190565b6020808252600a90820152692d22a927afa6282fa4a760b11b604082015260600190565b6020808252600e908201526d494e56414c49445f45585049525960901b604082015260600190565b60208082526010908201526f13505492d15517d393d517d193d5539160821b604082015260600190565b6020808252600e908201526d16915493d7d25397d05353d5539560921b604082015260600190565b94855260208501939093526001600160a01b039182166040850152166060830152608082015260a00190565b9283526020830191909152604082015260600190565b60405181810167ffffffffffffffff8111828210171561471757fe5b604052919050565b6001600160a01b038116811461384757600080fd5b801515811461384757600080fdfe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77e37fea01e65dea7d589abafc4bd0d5282a09ddce3e9ea971ed3399d776a1a2965361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212209626ffd93186e1b8f8d1dca57ff67323512eb5b53bb896d8c2322bc538e936f664736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009b528bf0639fc31ae6d698c48d830873227741f1000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d6
-----Decoded View---------------
Arg [0] : _governanceManager (address): 0x9b528BF0639fC31Ae6D698c48D830873227741F1
Arg [1] : _weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [2] : _data (address): 0xE8A6916576832AA5504092C1cCCC46E3bB9491d6
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000009b528bf0639fc31ae6d698c48d830873227741f1
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [2] : 000000000000000000000000e8a6916576832aa5504092c1cccc46e3bb9491d6
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.