Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 16 from a total of 16 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw Liquidi... | 17778568 | 537 days ago | IN | 0 ETH | 0.00455313 | ||||
Approve | 17778546 | 537 days ago | IN | 0 ETH | 0.00190465 | ||||
Open Swap | 13346373 | 1199 days ago | IN | 0 ETH | 0.01068712 | ||||
Approve | 13280199 | 1209 days ago | IN | 0 ETH | 0.00316172 | ||||
Withdraw Liquidi... | 13273506 | 1210 days ago | IN | 0 ETH | 0.0096577 | ||||
Approve | 13273496 | 1210 days ago | IN | 0 ETH | 0.00262705 | ||||
Open Swap | 13188997 | 1223 days ago | IN | 0 ETH | 0.0517119 | ||||
Liquidate | 13071548 | 1241 days ago | IN | 0 ETH | 0.00470191 | ||||
Deposit Liquidit... | 13068973 | 1242 days ago | IN | 0 ETH | 0.00484577 | ||||
Deposit Liquidit... | 13056278 | 1243 days ago | IN | 0 ETH | 0.00671866 | ||||
Deposit Liquidit... | 13056014 | 1244 days ago | IN | 0 ETH | 0.00478855 | ||||
Deposit Liquidit... | 13054505 | 1244 days ago | IN | 0 ETH | 0.00528 | ||||
Deposit Liquidit... | 13054500 | 1244 days ago | IN | 0 ETH | 0.00466942 | ||||
Open Swap | 13051698 | 1244 days ago | IN | 0 ETH | 0.01279131 | ||||
Open Swap | 13037695 | 1246 days ago | IN | 0 ETH | 0.02102018 | ||||
Deposit Liquidit... | 13037659 | 1246 days ago | IN | 0 ETH | 0.00608319 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
13031682 | 1247 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
Pool
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Unlicensed pragma solidity 0.7.6; // ============ Contract information ============ /** * @title InterestRateSwapPool * @notice A pool for Interest Rate Swaps * @author Greenwood Labs */ // ============ Imports ============ import '@openzeppelin/contracts/math/SafeMath.sol'; import '@openzeppelin/contracts/math/Math.sol'; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import '../interfaces/IPool.sol'; import '../interfaces/IAdapter.sol'; import './GreenwoodERC20.sol'; contract Pool is IPool, GreenwoodERC20 { // ============ Import usage ============ using SafeMath for uint256; using SafeERC20 for IERC20; // ============ Immutable storage ============ address private constant GOVERNANCE = 0xe3D5260Cd7F8a4207f41C3B2aC87882489f97213; uint256 private constant TEN_EXP_18 = 1000000000000000000; uint256 private constant STANDARD_DECIMALS = 18; uint256 private constant BLOCKS_PER_DAY = 6570; // 13.15 seconds per block uint256 private constant FEE_NUMERATOR = 3; uint256 private constant FEE_DENOMINATOR = 1000; uint256 private constant MAX_TO_PAY_BUFFER_NUMERATOR = 10; uint256 private constant MAX_TO_PAY_BUFFER_DENOMINATOR = 100; uint256 private constant DAYS_PER_YEAR = 360; // ============ Mutable storage ============ address private factory; address private adapter; address public underlier; uint256 public totalSwapCollateral; uint256 public totalSupplementaryCollateral; uint256 public totalActiveLiquidity; uint256 public totalAvailableLiquidity; uint256 public totalFees; uint256 public fixedRate; uint256 public utilization; uint256 public protocol; uint256 public direction; uint256 public durationInDays; uint256 public underlierDecimals; uint256 public decimalDifference; uint256 public rateLimit; uint256 public rateSensitivity; uint256 public utilizationInflection; uint256 public rateMultiplier; uint256 public maxDepositLimit; mapping(bytes32 => Swap) public swaps; mapping(address => uint256) public swapNumbers; mapping(address => uint256) public liquidityProviderLastDeposit; // ============ Structs ============ struct Swap { address user; bool isClosed; uint256 notional; uint256 swapCollateral; uint256 activeLiquidity; uint256 openBlock; uint256 underlierBorrowIndex; uint256 fixedRate; } // ============ Events ============ event OpenSwap(address indexed user, uint256 notional, uint256 activeLiquidity, uint256 fixedRate); event CloseSwap(address indexed user, uint256 notional, uint256 userToPay, uint256 ammToPay, uint256 fixedRate); event DepositLiquidity(address indexed user, uint256 liquidityAmount); event WithdrawLiquidity(address indexed user, uint256 liquidityAmount, uint256 feesAccrued); event Liquidate(address indexed liquidator, address indexed user, uint256 swapNumber, uint256 liquidatorReward); event Mint(address indexed user, uint256 underlyingTokenAmount, uint256 liquidityTokenAmount); event Burn(address indexed user, uint256 underlyingTokenAmount, uint256 liquidityTokenAmount); // ============ Constructor ============ constructor( address _underlier, uint256 _underlierDecimals, address _adapter, uint256 _protocol, uint256 _direction, uint256 _durationInDays, uint256 _initialDeposit, uint256 _rateLimit, uint256 _rateSensitivity, uint256 _utilizationInflection, uint256 _rateMultiplier, address _poolDeployer ) { // assert that the pool can be initialized with a non-zero amount require(_initialDeposit > 0, '14'); // initialize the pool factory = msg.sender; underlier = _underlier; underlierDecimals = _underlierDecimals; protocol = _protocol; direction = _direction; durationInDays = _durationInDays; // calculate difference in decimals between underlier and STANDARD_DECIMALS decimalDifference = _calculatedDecimalDifference(underlierDecimals, STANDARD_DECIMALS); // adjust the y token decimals to the standard number uint256 adjustedInitialDeposit = _convertToStandardDecimal(_initialDeposit); totalAvailableLiquidity = adjustedInitialDeposit; adapter = _adapter; rateLimit = _rateLimit; rateSensitivity = _rateSensitivity; utilizationInflection = _utilizationInflection; rateMultiplier = _rateMultiplier; maxDepositLimit = 1000000000000000000000000; // calculates the initial fixed rate to be offered fixedRate = _calculateFixedRate(); // update the pool deployer's deposit block number liquidityProviderLastDeposit[_poolDeployer] = block.number; // mint LP tokens to the pool deployer _mintLPTokens(_poolDeployer, adjustedInitialDeposit); } // ============ Opens a new interest rate swap ============ function openSwap(uint256 _notional) external override returns (bool) { // assert that a swap is opened with an non-zero notional require(_notional > 0, '9'); // adjust notional to standard decimal places uint256 adjustedNotional = _convertToStandardDecimal(_notional); // calculate the swap collateral and trade active liquidity based off the notional (uint256 swapCollateral, uint256 activeLiquidity) = _calculateSwapCollateralAndActiveLiquidity(adjustedNotional); // assert that there is sufficient liquidity to open this swap require(activeLiquidity <= totalAvailableLiquidity, '10'); // assign the supplementary collateral uint256 supplementaryCollateral = activeLiquidity; // the offered fixed rate for this swap uint256 offeredFixedRate = fixedRate; // calculate the fee based on swap collateral uint256 swapFee = swapCollateral.mul(FEE_NUMERATOR).div(FEE_DENOMINATOR); // calculate the current borrow index for the underlier uint256 underlierBorrowIndex = IAdapter(adapter).getBorrowIndex(underlier); // create the swap struct Swap memory swap = Swap( msg.sender, false, adjustedNotional, swapCollateral, activeLiquidity, block.number, underlierBorrowIndex, offeredFixedRate ); // create a swap key by hashing together the user and their current swap number bytes32 swapKey = keccak256(abi.encode(msg.sender, swapNumbers[msg.sender])); swaps[swapKey] = swap; // update the user's swap number swapNumbers[msg.sender] = swapNumbers[msg.sender].add(1); // update the total active liquidity totalActiveLiquidity = totalActiveLiquidity.add(activeLiquidity); // update the total swap collateral totalSwapCollateral = totalSwapCollateral.add(swapCollateral); // update the total supplementary collateral totalSupplementaryCollateral = totalSupplementaryCollateral.add(supplementaryCollateral); // update the total available liquidity totalAvailableLiquidity = totalAvailableLiquidity.sub(activeLiquidity); // update the total fees accrued totalFees = totalFees.add(swapFee); // the total amount to debit the user (swap collateral + fee + the supplementary collateral) uint256 amountToDebit = swapCollateral.add(swapFee).add(supplementaryCollateral); // calculate the new pool utilization utilization = _calculateUtilization(); // calculate the new fixed interest rate fixedRate = _calculateFixedRate(); // transfer underlier from the user IERC20(underlier).safeTransferFrom( msg.sender, address(this), _convertToUnderlierDecimal(amountToDebit) ); // emit an open swap event emit OpenSwap(msg.sender, adjustedNotional, activeLiquidity, offeredFixedRate); // return true on successful open swap return true; } // ============ Closes an interest rate swap ============ function closeSwap(uint256 _swapNumber) external override returns (bool) { // the key of the swap bytes32 swapKey = keccak256(abi.encode(msg.sender, _swapNumber)); // assert that a swap exists for this user require(swaps[swapKey].user == msg.sender, '11'); // assert that this swap has not already been closed require(!swaps[swapKey].isClosed, '12'); // get the swap to be closed Swap memory swap = swaps[swapKey]; // the amounts that the user and the AMM will pay on this swap, depending on the direction of the swap (uint256 userToPay, uint256 ammToPay) = _calculateInterestAccrued(swap); // assert that the swap cannot be closed in the same block that it was opened require(block.number > swap.openBlock, '13'); // the total payout for this swap uint256 payout = userToPay > ammToPay ? userToPay.sub(ammToPay) : ammToPay.sub(userToPay); // the supplementary collateral of this swap uint256 supplementaryCollateral = swap.activeLiquidity; // the active liquidity recovered upon closure of this swap uint256 activeLiquidityRecovered; // the amount to reward the user upon closing of the swap uint256 redeemableFunds; // the user won the swap if (ammToPay > userToPay) { // ensure the payout does not exceed the active liquidity for this swap payout = Math.min(payout, swap.activeLiquidity); // active liquidity recovered is the the total active liquidity reduced by the user's payout activeLiquidityRecovered = swap.activeLiquidity.sub(payout); // User can redeem all of swap collateral, all of supplementary collateral, and the payout redeemableFunds = swap.swapCollateral.add(supplementaryCollateral).add(payout); } // the AMM won the swap else if (ammToPay < userToPay) { // ensure the payout does not exceed the swap collateral for this swap payout = Math.min(payout, swap.swapCollateral); // active liquidity recovered is the the total active liquidity increased by the amm's payout activeLiquidityRecovered = swap.activeLiquidity.add(payout); // user can redeem all of swap collateral, all of supplementary collateral, with the payout subtracted redeemableFunds = swap.swapCollateral.add(supplementaryCollateral).sub(payout); } // neither party won the swap else { // active liquidity recovered is the the initial active liquidity for the trade activeLiquidityRecovered = swap.activeLiquidity; // user can redeem all of swap collateral and all of supplementary collateral redeemableFunds = swap.swapCollateral.add(supplementaryCollateral); } // update the total active liquidity totalActiveLiquidity = totalActiveLiquidity.sub(swap.activeLiquidity); // update the total swap collateral totalSwapCollateral = totalSwapCollateral.sub(swap.swapCollateral); // update the total supplementary collateral totalSupplementaryCollateral = totalSupplementaryCollateral.sub(supplementaryCollateral); // update the total available liquidity totalAvailableLiquidity = totalAvailableLiquidity.add(activeLiquidityRecovered); // close the swap swaps[swapKey].isClosed = true; // calculate the new pool utilization utilization = _calculateUtilization(); // calculate the new fixed interest rate fixedRate = _calculateFixedRate(); // transfer redeemable funds to the user IERC20(underlier).safeTransfer( msg.sender, _convertToUnderlierDecimal(redeemableFunds) ); // emit a close swap event emit CloseSwap(msg.sender, swap.notional, userToPay, ammToPay, swap.fixedRate); return true; } // ============ Deposit liquidity into the pool ============ function depositLiquidity(uint256 _liquidityAmount) external override returns (bool) { // adjust liquidity amount to standard decimals uint256 adjustedLiquidityAmount = _convertToStandardDecimal(_liquidityAmount); // asert that liquidity amount must be greater than 0 and amount to less than the max deposit limit require(adjustedLiquidityAmount > 0 && adjustedLiquidityAmount.add(totalActiveLiquidity).add(totalAvailableLiquidity) <= maxDepositLimit, '14'); // transfer the specified amount of underlier into the pool IERC20(underlier).safeTransferFrom(msg.sender, address(this), _liquidityAmount); // add to the total available liquidity in the pool totalAvailableLiquidity = totalAvailableLiquidity.add(adjustedLiquidityAmount); // update the most recent deposit block of the liquidity provider liquidityProviderLastDeposit[msg.sender] = block.number; // calculate the new pool utilization utilization = _calculateUtilization(); // calculate the new fixed interest rate fixedRate = _calculateFixedRate(); // mint LP tokens to the liiquidity provider _mintLPTokens(msg.sender, adjustedLiquidityAmount); // emit deposit liquidity event emit DepositLiquidity(msg.sender, adjustedLiquidityAmount); return true; } // ============ Withdraw liquidity into the pool ============ function withdrawLiquidity(uint256 _liquidityTokenAmount) external override returns (bool) { // assert that withdrawal does not occur in the same block as a deposit require(liquidityProviderLastDeposit[msg.sender] < block.number, '19'); // asert that liquidity amount must be greater than 0 require(_liquidityTokenAmount > 0, '14'); // transfer the liquidity tokens from sender to the pool IERC20(address(this)).safeTransferFrom(msg.sender, address(this), _liquidityTokenAmount); // determine the amount of underlying tokens that the liquidity tokens can be redeemed for uint256 redeemableUnderlyingTokens = calculateLiquidityTokenValue(_liquidityTokenAmount); // assert that there is enough available liquidity to safely withdraw this amount require(totalAvailableLiquidity >= redeemableUnderlyingTokens, '10'); // the fees that this withdraw will yield (total fees accrued * withdraw amount / total liquidity provided) uint256 feeShare = totalFees.mul(redeemableUnderlyingTokens).div(totalActiveLiquidity.add(totalAvailableLiquidity)); // update the total fees remaining in the pool totalFees = totalFees.sub(feeShare); // remove the withdrawn amount from the total available liquidity in the pool totalAvailableLiquidity = totalAvailableLiquidity.sub(redeemableUnderlyingTokens); // calculate the new pool utilization utilization = _calculateUtilization(); // calculate the new fixed interest rate fixedRate = _calculateFixedRate(); // burn LP tokens and redeem underlying tokens to the liiquidity provider _burnLPTokens(msg.sender, _liquidityTokenAmount); // emit withdraw liquidity event emit WithdrawLiquidity(msg.sender, _liquidityTokenAmount, feeShare); return true; } // ============ Liquidate a swap that has expired ============ function liquidate(address _user, uint256 _swapNumber) external override returns (bool) { // the key of the swap bytes32 swapKey = keccak256(abi.encode(_user, _swapNumber)); // assert that a swap exists for this user require(swaps[swapKey].user == _user, '11'); // get the swap to be liquidated Swap memory swap = swaps[swapKey]; // assert that the swap has not already been closed require(!swap.isClosed, '12'); // the expiration block of the swap uint256 expirationBlock = swap.openBlock.add(durationInDays.mul(BLOCKS_PER_DAY)); // assert that the swap has eclipsed the expiration block require(block.number >= expirationBlock, '17'); // transfer trade active liquidity from the liquidator IERC20(underlier).safeTransferFrom( msg.sender, address(this), _convertToUnderlierDecimal(swap.activeLiquidity) ); // the amounts that the user and the AMM will pay on this swap, depending on the direction of the swap (uint256 userToPay, uint256 ammToPay) =_calculateInterestAccrued(swap); // the total payout for this swap uint256 payout = userToPay > ammToPay ? userToPay.sub(ammToPay) : ammToPay.sub(userToPay); // the supplementary collateral of this swap uint256 supplementaryCollateral = swap.activeLiquidity; // the active liquidity recovered upon liquidation of this swap uint256 activeLiquidityRecovered; // the amount to reward the liquidator upon liquidation of the swap uint256 liquidatorReward; // the user won the swap if (ammToPay > userToPay) { // ensure the payout does not exceed the active liquidity for this swap payout = Math.min(payout, swap.activeLiquidity); // active liquidity recovered is the the total active liquidity increased by the user's unclaimed payout activeLiquidityRecovered = swap.activeLiquidity.add(payout); // liquidator is rewarded the supplementary collateral and the difference between the swap collateral and the payout liquidatorReward = supplementaryCollateral.add(swap.swapCollateral).sub(payout); } // the AMM won the swap else if (ammToPay < userToPay) { // ensure the payout does not exceed the swap collateral for this swap payout = Math.min(payout, swap.swapCollateral); // active liquidity recovered is the the total active liquidity increased by the entire swap collateral activeLiquidityRecovered = swap.activeLiquidity.add(swap.swapCollateral); // liquidator is rewarded all of the supplementary collateral liquidatorReward = supplementaryCollateral; } // neither party won the swap else { // active liquidity recovered is the the total active liquidity for this swap activeLiquidityRecovered = swap.activeLiquidity; // liquidator is rewarded all of the supplementary collateral and the swap collateral liquidatorReward = supplementaryCollateral.add(swap.swapCollateral); } // update the total active liquidity totalActiveLiquidity = totalActiveLiquidity.sub(swap.activeLiquidity); // update the total swap collateral totalSwapCollateral = totalSwapCollateral.sub(swap.swapCollateral); // update the total supplementary collateral totalSupplementaryCollateral = totalSupplementaryCollateral.sub(supplementaryCollateral); // update the total available liquidity totalAvailableLiquidity = totalAvailableLiquidity.add(activeLiquidityRecovered); // close the swap swaps[swapKey].isClosed = true; // calculate the new pool utilization utilization = _calculateUtilization(); // calculate the new fixed interest rate fixedRate = _calculateFixedRate(); // transfer liquidation reward to the liquidator IERC20(underlier).safeTransfer( msg.sender, _convertToUnderlierDecimal(liquidatorReward) ); // emit liquidate event emit Liquidate(msg.sender, _user, _swapNumber, liquidatorReward); return true; } // ============ External view for the interest accrued on a variable rate ============ function calculateVariableInterestAccrued(uint256 _notional, uint256 _borrowIndex) external view override returns (uint256) { return _calculateVariableInterestAccrued(_notional, _borrowIndex); } // ============ External view for the interest accrued on a fixed rate ============ function calculateFixedInterestAccrued(uint256 _notional, uint256 _fixedRate, uint256 _openBlock) external view override returns (uint256) { return _calculateFixedInterestAccrued(_notional, _fixedRate, _openBlock); } // ============ Calculates the fixed rate offered ============ function calculateFixedRate() external view returns (uint256) { return _calculateFixedRate(); } // ============ Calculates the max variable rate to pay ============ function calculateMaxVariableRate() external view returns (uint256) { return _calculateMaxVariableRate(); } // ============ Calculates the current variable rate for the underlier ============ function calculateVariableRate() external view returns (uint256) { // get the borrow rate from the adapter return IAdapter(adapter).getBorrowRate(underlier); } // ============ Allows governance to change the max deposit limit ============ function changeMaxDepositLimit(uint256 _limit) external { // assert that only governance can adjust the deposit limit require(msg.sender == GOVERNANCE, '18'); // change the deposit limit maxDepositLimit = _limit; } // ============ Calculates the current approximate value of liquidity tokens denoted in the underlying token ============ function calculateLiquidityTokenValue(uint256 liquidityTokenAmount) public view returns (uint256 redeemableUnderlyingTokens) { // get the total underlying token balance in this pool with supplementary and swap collateral amounts excluded uint256 adjustedUnderlyingTokenBalance = _convertToStandardDecimal(IERC20(underlier).balanceOf(address(this))) .sub(totalSwapCollateral) .sub(totalSupplementaryCollateral); // the total supply of LP tokens in circulation uint256 _totalSupply = totalSupply(); // determine the amount of underlying tokens that the liquidity tokens can be redeemed for redeemableUnderlyingTokens = liquidityTokenAmount.mul(adjustedUnderlyingTokenBalance).div(_totalSupply); } // ============ Internal methods ============ // ============ Mints LP tokens to users that deposit liquidity to the protocol ============ function _mintLPTokens(address to, uint256 underlyingTokenAmount) internal { // the total supply of LP tokens in circulation uint256 _totalSupply = totalSupply(); // determine the amount of LP tokens to mint uint256 mintableLiquidity; if (_totalSupply == 0) { // initialize the supply of LP tokens mintableLiquidity = underlyingTokenAmount; } else { // get the total underlying token balance in this pool uint256 underlyingTokenBalance = _convertToStandardDecimal(IERC20(underlier).balanceOf(address(this))); // adjust the underlying token balance to standardize the decimals // the supplementary collateral, swap collateral, and newly added liquidity amounts are excluded uint256 adjustedUnderlyingTokenBalance = underlyingTokenBalance .sub(totalSwapCollateral) .sub(totalSupplementaryCollateral) .sub(underlyingTokenAmount); // mint a proportional amount of LP tokens mintableLiquidity = underlyingTokenAmount.mul(_totalSupply).div(adjustedUnderlyingTokenBalance); } // assert that enough liquidity tokens are available to be minted require(mintableLiquidity > 0, 'INSUFFICIENT_LIQUIDITY_MINTED'); // mint the tokens directly to the LP _mint(to, mintableLiquidity); // emit minting of LP token event emit Mint(to, underlyingTokenAmount, mintableLiquidity); } // ============ Burns LP tokens and sends users the equivalent underlying tokens in return ============ function _burnLPTokens(address to, uint256 liquidityTokenAmount) internal { // determine the amount of underlying tokens that the liquidity tokens can be redeemed for uint256 redeemableUnderlyingTokens = calculateLiquidityTokenValue(liquidityTokenAmount); // assert that enough underlying tokens are available to send to the redeemer require(redeemableUnderlyingTokens > 0, 'INSUFFICIENT_LIQUIDITY_BURNED'); // burn the liquidity tokens _burn(address(this), liquidityTokenAmount); // transfer the underlying tokens IERC20(underlier).safeTransfer(to, _convertToUnderlierDecimal(redeemableUnderlyingTokens)); // emit burning of LP token event emit Mint(to, redeemableUnderlyingTokens, liquidityTokenAmount); } // ============ Calculates the fixed rate offered ============ function _calculateFixedRate() internal view returns (uint256) { // the new fixed rate based on updated pool utilization uint256 newFixedRate; // the rate offered before the utilization inflection is hit int256 preInflectionLeg; // the pool is long if (direction == 0) { // (utilization * rate sensitivity) + rate limit preInflectionLeg = int256(utilization.mul(rateSensitivity).div(TEN_EXP_18).add(rateLimit)); } // the pool is short else { // rate limit - (utilization * rate sensitivity) preInflectionLeg = int256(rateLimit) - int256(utilization.mul(rateSensitivity).div(TEN_EXP_18)); } // pool utilization is below the inflection if (utilization < utilizationInflection) { // assert that the leg is positive before converting to uint256 require(preInflectionLeg > 0); newFixedRate = uint256(preInflectionLeg); } // pool utilization is at or above the inflection else { // The additional change in the rate after the utilization inflection is hit // rate multiplier * (utilization - utilization inflection) int256 postInflectionLeg = int256(rateMultiplier.mul(utilization.sub(utilizationInflection)).div(TEN_EXP_18)); // assert that the addition of the legs is positive before converting to uint256 require(preInflectionLeg + postInflectionLeg > 0); newFixedRate = uint256(preInflectionLeg + postInflectionLeg); } // adjust the fixed rate as a percentage return newFixedRate.div(100); } // ============ Calculates the pool utilization ============ function _calculateUtilization() internal view returns (uint256) { // get the total liquidity of this pool uint256 totalPoolLiquidity = totalActiveLiquidity.add(totalAvailableLiquidity); // pool utilization is the total active liquidity / total pool liquidity uint256 newUtilization = totalActiveLiquidity.mul(TEN_EXP_18).div(totalPoolLiquidity); // adjust utilization to be an integer between 0 and 100 uint256 adjustedUtilization = newUtilization * 100; return adjustedUtilization; } // ============ Calculates the swap collateral and active liquidity needed for a given notional ============ function _calculateSwapCollateralAndActiveLiquidity(uint256 _notional) internal view returns (uint256, uint256) { // The maximum rate the user will pay on a swap uint256 userMaxRateToPay = direction == 0 ? fixedRate : _calculateMaxVariableRate(); // the maximum rate the AMM will pay on a swap uint256 ammMaxRateToPay = direction == 1 ? fixedRate : _calculateMaxVariableRate(); // notional * maximum rate to pay * (swap duration in days / days per year) uint256 swapCollateral = _calculateMaxAmountToPay(_notional, userMaxRateToPay); uint256 activeLiquidity = _calculateMaxAmountToPay(_notional, ammMaxRateToPay); return (swapCollateral, activeLiquidity); } // ============ Calculates the maximum amount to pay over a specific time window with a given notional and rate ============ function _calculateMaxAmountToPay(uint256 _notional, uint256 _rate) internal view returns (uint256) { // the period by which to adjust the rate uint256 period = DAYS_PER_YEAR.div(durationInDays); // notional * maximum rate to pay / (days per year / swap duration in days) return _notional.mul(_rate).div(TEN_EXP_18).div(period); } // ============ Calculates the maximum variable rate ============ function _calculateMaxVariableRate() internal view returns (uint256) { // use the current variable rate for the underlying token uint256 variableRate = IAdapter(adapter).getBorrowRate(underlier); // calculate a variable rate buffer uint256 maxBuffer = MAX_TO_PAY_BUFFER_NUMERATOR.mul(TEN_EXP_18).div(MAX_TO_PAY_BUFFER_DENOMINATOR); // add the buffer to the current variable rate return variableRate.add(maxBuffer); } // ============ Calculates the interest accrued for both parties on a swap ============ function _calculateInterestAccrued(Swap memory _swap) internal view returns (uint256, uint256) { // the amounts that the user and the AMM will pay on this swap, depending on the direction of the swap uint256 userToPay; uint256 ammToPay; // the fixed interest accrued on this swap uint256 fixedInterestAccrued = _calculateFixedInterestAccrued(_swap.notional, _swap.fixedRate, _swap.openBlock); // the variable interest accrued on this swap uint256 variableInterestAccrued = _calculateVariableInterestAccrued(_swap.notional, _swap.underlierBorrowIndex); // user went long on the variable rate if (direction == 0) { userToPay = fixedInterestAccrued; ammToPay = variableInterestAccrued; } // user went short on the variable rate else { userToPay = variableInterestAccrued; ammToPay = fixedInterestAccrued; } return (userToPay, ammToPay); } // ============ Calculates the interest accrued on a fixed rate ============ function _calculateFixedInterestAccrued(uint256 _notional, uint256 _fixedRate, uint256 _openBlock) internal view returns (uint256) { // the period of the fixed interest accrued uint256 period = durationInDays.mul(TEN_EXP_18).div(DAYS_PER_YEAR); // notional * fixed rate * (swap duration / days in year) uint256 maxFixedInterest = _notional.mul(_fixedRate).div(TEN_EXP_18).mul(period).div(TEN_EXP_18); // the blocks that have elapsed since the swap was opened uint256 blocksElapsed = block.number.sub(_openBlock); // the total blocks in a swap uint256 totalBlocksInSwapDuration = durationInDays.mul(BLOCKS_PER_DAY); // the percentage that the swap has matured // safeguard against blocks elapsed potentially being bigger than the total blocks in the swap uint256 swapMaturity = blocksElapsed < totalBlocksInSwapDuration ? blocksElapsed.mul(TEN_EXP_18).div(totalBlocksInSwapDuration) : TEN_EXP_18; // the max fixed amount one can pay in a full swap * the maturity percentage of the swap return maxFixedInterest.mul(swapMaturity).div(TEN_EXP_18); } // ============ Calculates the interest accrued on a variable rate ============ function _calculateVariableInterestAccrued(uint256 _notional, uint256 _openSwapBorrowIndex) internal view returns (uint256) { // get the current borrow index of the underlying asset uint256 currentBorrowIndex = IAdapter(adapter).getBorrowIndex(underlier); // The ratio between the current borrow index and the borrow index at time of open swap uint256 indexRatio = currentBorrowIndex.mul(TEN_EXP_18).div(_openSwapBorrowIndex); // notional * (current borrow index / borrow index when swap was opened) - notional return _notional.mul(indexRatio).div(TEN_EXP_18).sub(_notional); } // ============ Converts an amount to have the contract standard number of decimals ============ function _convertToStandardDecimal(uint256 _amount) internal view returns (uint256) { // set adjustment direction to false to convert to standard pool decimals return _convertToDecimal(_amount, true); } // ============ Converts an amount to have the underlying token's number of decimals ============ function _convertToUnderlierDecimal(uint256 _amount) internal view returns (uint256) { // set adjustment direction to true to convert to underlier decimals return _convertToDecimal(_amount, false); } // ============ Converts an amount to have a particular number of decimals ============ function _convertToDecimal(uint256 _amount, bool _adjustmentDirection) internal view returns (uint256) { // the amount after it has been converted to have the underlier number of decimals uint256 convertedAmount; // the underlying token has less decimal places if (underlierDecimals < STANDARD_DECIMALS) { convertedAmount = _adjustmentDirection ? _amount.mul(10 ** decimalDifference) : _amount.div(10 ** decimalDifference); } // there is no difference in the decimal places else { convertedAmount = _amount; } return convertedAmount; } // ============ Calculates the difference between the underlying decimals and the standard decimals ============ function _calculatedDecimalDifference(uint256 _x_decimal, uint256 _y_decimal) internal pure returns (uint256) { // the difference in decimals uint256 difference; // the second decimal is greater if (_x_decimal < _y_decimal) { difference = _y_decimal.sub(_x_decimal); } return difference; } }
// 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: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } }
// 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.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: Unlicensed pragma solidity 0.7.6; interface IPool { function openSwap(uint256 _notional) external returns (bool); function closeSwap(uint256 _swapNumber) external returns (bool); function depositLiquidity(uint256 _liquidityAmount) external returns (bool); function withdrawLiquidity(uint256 _liquidityAmount) external returns (bool); function liquidate(address _user, uint256 _swapNumber) external returns (bool); function calculateVariableInterestAccrued(uint256 _notional, uint256 _borrowIndex) external view returns (uint256); function calculateFixedInterestAccrued(uint256 _notional, uint256 _fixedRate, uint256 _openBlock) external view returns (uint256); }
// SPDX-License-Identifier: Unlicensed pragma solidity >=0.6.12; interface IAdapter { function getBorrowIndex(address underlier) external view returns (uint256); function getBorrowRate(address underlier) external view returns (uint256); }
// SPDX-License-Identifier: Unlicensed pragma solidity 0.7.6; // ============ Contract information ============ /** * @title Greenwood LP token * @notice An LP token for Greenwood Basis Swaps * @author Greenwood Labs */ // ============ Imports ============ import '../interfaces/IGreenwoodERC20.sol'; import '@openzeppelin/contracts/math/SafeMath.sol'; contract GreenwoodERC20 is IGreenwoodERC20 { // ============ Import usage ============ using SafeMath for uint256; // ============ Immutable storage ============ string public constant override name = 'Greenwood'; string public constant override symbol = 'GRN'; uint256 public constant override decimals = 18; // ============ Mutable storage ============ uint256 private _totalSupply; mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; // ============ Events ============ event Approval(address indexed owner, address indexed spender, uint256 value); event Transfer(address indexed from, address indexed to, uint256 value); // ============ Constructor ============ constructor() {} // ============ External methods ============ // ============ Returns the amount of tokens in existence ============ function totalSupply() public view override returns (uint256) { return _totalSupply; } // ============ Returns the amount of tokens owned by `account` ============ function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } // ============ Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` ============ function allowance(address owner, address spender) public view override returns (uint256) { return _allowances[owner][spender]; } // ============ Sets `amount` as the allowance of `spender` over the caller's tokens ============ function approve(address spender, uint256 amount) external override returns (bool) { _approve(msg.sender, spender, amount); return true; } // ============ Moves `amount` tokens from the caller's account to `recipient` ============ function transfer(address recipient, uint256 amount) external override returns (bool) { _transfer(msg.sender, recipient, amount); return true; } // ============ Moves `amount` tokens from `sender` to `recipient` using the allowance mechanism ============ function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, 'GreenwoodERC20: transfer amount exceeds allowance')); return true; } // ============ Internal methods ============ // ============ Creates `amount` tokens and assigns them to `account`, increasing the total supply ============ function _mint(address account, uint256 amount) internal { require(account != address(0), 'GreenwoodERC20: mint to the zero address'); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } // ============ Destroys `amount` tokens from `account`, reducing the total supply ============ function _burn(address account, uint256 amount) internal { require(account != address(0), 'GreenwoodERC20: burn from the zero address'); _balances[account] = _balances[account].sub(amount, 'GreenwoodERC20: burn amount exceeds balance'); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } // ============ Sets `amount` as the allowance of `spender` over the tokens of the `owner` ============ function _approve(address owner, address spender, uint256 amount) internal { require(owner != address(0), 'GreenwoodERC20: approve from the zero address'); require(spender != address(0), 'GreenwoodERC20: approve to the zero address'); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } // ============ Moves tokens `amount` from `sender` to `recipient` ============ function _transfer(address sender, address recipient, uint256 amount) internal { require(sender != address(0), 'GreenwoodERC20: transfer from the zero address'); require(recipient != address(0), 'GreenwoodERC20: transfer to the zero address'); _balances[sender] = _balances[sender].sub(amount, 'GreenwoodERC20: transfer amount exceeds balance'); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } }
// 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: Unlicensed pragma solidity 0.7.6; interface IGreenwoodERC20 { function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint256); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transfer(address recipient, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_underlier","type":"address"},{"internalType":"uint256","name":"_underlierDecimals","type":"uint256"},{"internalType":"address","name":"_adapter","type":"address"},{"internalType":"uint256","name":"_protocol","type":"uint256"},{"internalType":"uint256","name":"_direction","type":"uint256"},{"internalType":"uint256","name":"_durationInDays","type":"uint256"},{"internalType":"uint256","name":"_initialDeposit","type":"uint256"},{"internalType":"uint256","name":"_rateLimit","type":"uint256"},{"internalType":"uint256","name":"_rateSensitivity","type":"uint256"},{"internalType":"uint256","name":"_utilizationInflection","type":"uint256"},{"internalType":"uint256","name":"_rateMultiplier","type":"uint256"},{"internalType":"address","name":"_poolDeployer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"underlyingTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidityTokenAmount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"notional","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userToPay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ammToPay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fixedRate","type":"uint256"}],"name":"CloseSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"liquidityAmount","type":"uint256"}],"name":"DepositLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"liquidator","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"swapNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidatorReward","type":"uint256"}],"name":"Liquidate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"underlyingTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidityTokenAmount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"notional","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"activeLiquidity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fixedRate","type":"uint256"}],"name":"OpenSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"liquidityAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feesAccrued","type":"uint256"}],"name":"WithdrawLiquidity","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_notional","type":"uint256"},{"internalType":"uint256","name":"_fixedRate","type":"uint256"},{"internalType":"uint256","name":"_openBlock","type":"uint256"}],"name":"calculateFixedInterestAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculateFixedRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"liquidityTokenAmount","type":"uint256"}],"name":"calculateLiquidityTokenValue","outputs":[{"internalType":"uint256","name":"redeemableUnderlyingTokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculateMaxVariableRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_notional","type":"uint256"},{"internalType":"uint256","name":"_borrowIndex","type":"uint256"}],"name":"calculateVariableInterestAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculateVariableRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"changeMaxDepositLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_swapNumber","type":"uint256"}],"name":"closeSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimalDifference","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_liquidityAmount","type":"uint256"}],"name":"depositLiquidity","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"direction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"durationInDays","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fixedRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_swapNumber","type":"uint256"}],"name":"liquidate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"liquidityProviderLastDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDepositLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_notional","type":"uint256"}],"name":"openSwap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"protocol","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rateLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rateMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rateSensitivity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"swapNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"swaps","outputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"isClosed","type":"bool"},{"internalType":"uint256","name":"notional","type":"uint256"},{"internalType":"uint256","name":"swapCollateral","type":"uint256"},{"internalType":"uint256","name":"activeLiquidity","type":"uint256"},{"internalType":"uint256","name":"openBlock","type":"uint256"},{"internalType":"uint256","name":"underlierBorrowIndex","type":"uint256"},{"internalType":"uint256","name":"fixedRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalActiveLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAvailableLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupplementaryCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSwapCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"underlier","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"underlierDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"utilization","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"utilizationInflection","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_liquidityTokenAmount","type":"uint256"}],"name":"withdrawLiquidity","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620051c3380380620051c383398181016040526101808110156200003857600080fd5b81019080805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050600086116200012e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313400000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b33600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508a60108190555088600d8190555087600e8190555086600f81905550620001e16010546012620002f060201b60201c565b6011819055506000620001fa876200032360201b60201c565b9050806009819055508a600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508560128190555084601381905550836014819055508260158190555069d3c21bcecceda1000000601681905550620002816200033f60201b60201c565b600b8190555043601960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550620002dd8282620004b260201b60201c565b5050505050505050505050505062000b72565b6000808284101562000319576200031684846200072660201b6200293f1790919060201c565b90505b8091505092915050565b600062000338826001620007aa60201b60201c565b9050919050565b600080600080600e541415620003b157620003a960125462000395670de0b6b3a764000062000381601354600c546200081a60201b620029c21790919060201c565b620008a560201b62002a481790919060201c565b6200093060201b62002ad11790919060201c565b9050620003f7565b620003f0670de0b6b3a7640000620003dc601354600c546200081a60201b620029c21790919060201c565b620008a560201b62002a481790919060201c565b6012540390505b601454600c5410156200041b57600081136200041257600080fd5b80915062000490565b600062000477670de0b6b3a7640000620004636200044c601454600c546200072660201b6200293f1790919060201c565b6015546200081a60201b620029c21790919060201c565b620008a560201b62002a481790919060201c565b90506000818301136200048957600080fd5b8082019250505b620004ab606483620008a560201b62002a481790919060201c565b9250505090565b6000620004c4620009b960201b60201c565b9050600080821415620004da5782905062000641565b6000620005b3600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156200056a57600080fd5b505afa1580156200057f573d6000803e3d6000fd5b505050506040513d60208110156200059657600080fd5b81019080805190602001909291905050506200032360201b60201c565b905060006200060785620005f3600754620005df600654876200072660201b6200293f1790919060201c565b6200072660201b6200293f1790919060201c565b6200072660201b6200293f1790919060201c565b90506200063c816200062886886200081a60201b620029c21790919060201c565b620008a560201b62002a481790919060201c565b925050505b60008111620006b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f494e53554646494349454e545f4c49515549444954595f4d494e54454400000081525060200191505060405180910390fd5b620006ca8482620009c260201b60201c565b8373ffffffffffffffffffffffffffffffffffffffff167f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f8483604051808381526020018281526020019250505060405180910390a250505050565b6000828211156200079f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b600080601260105410156200080c5782620007e457620007de601154600a0a85620008a560201b62002a481790919060201c565b62000804565b62000803601154600a0a856200081a60201b620029c21790919060201c565b5b905062000810565b8390505b8091505092915050565b6000808314156200082f57600090506200089f565b60008284029050828482816200084157fe5b04146200089a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180620051a26021913960400191505060405180910390fd5b809150505b92915050565b60008082116200091d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b8183816200092757fe5b04905092915050565b600080828401905083811015620009af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008054905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000a4a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806200517a6028913960400191505060405180910390fd5b62000a66816000546200093060201b62002ad11790919060201c565b60008190555062000ac581600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546200093060201b62002ad11790919060201c565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6145f88062000b826000396000f3fe608060405234801561001057600080fd5b506004361061025e5760003560e01c80638064a05911610146578063c11eaae2116100c3578063e43c520d11610087578063e43c520d14610a69578063e588b50514610aad578063ea21cd9214610b03578063eb84e7f214610b21578063f3eb4f8a14610bac578063fa7e8d0114610bf05761025e565b8063c11eaae21461093f578063ce3f28f01461095d578063ce7539011461097b578063d14ab67d146109d3578063dd62ed3e146109f15761025e565b8063a9059cbb1161010a578063a9059cbb146107bf578063b2485f9714610823578063b63c44e714610865578063b6984be914610883578063bcbaf487146108db5761025e565b80638064a059146106705780638ce744261461069e5780638d7aeae5146106bc57806391cfad5a1461070857806395d89b411461073c5761025e565b8063330691ac116101df578063645539ed116101a3578063645539ed1461055c57806370a082311461057a578063735d80e3146105d257806376d58e1a146105f05780637b83002914610634578063802d1422146106525761025e565b8063330691ac146104c6578063356cd90a146104e45780633fc896a21461050257806354b6ba951461052057806361e08e721461053e5761025e565b806318160ddd1161022657806318160ddd146103ca57806323b872dd146103e857806327b380ea1461046c578063294164531461048a578063313ce567146104a85761025e565b806306fdde0314610263578063095ea7b3146102e65780630a2a8e781461034a5780630a861f2a1461036857806313114a9d146103ac575b600080fd5b61026b610c0e565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102ab578082015181840152602081019050610290565b50505050905090810190601f1680156102d85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610332600480360360408110156102fc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c47565b60405180821515815260200191505060405180910390f35b610352610c5e565b6040518082815260200191505060405180910390f35b6103946004803603602081101561037e57600080fd5b8101908080359060200190929190505050610d4b565b60405180821515815260200191505060405180910390f35b6103b4611027565b6040518082815260200191505060405180910390f35b6103d261102d565b6040518082815260200191505060405180910390f35b610454600480360360608110156103fe57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611036565b60405180821515815260200191505060405180910390f35b610474611101565b6040518082815260200191505060405180910390f35b610492611107565b6040518082815260200191505060405180910390f35b6104b061110d565b6040518082815260200191505060405180910390f35b6104ce611112565b6040518082815260200191505060405180910390f35b6104ec611118565b6040518082815260200191505060405180910390f35b61050a61111e565b6040518082815260200191505060405180910390f35b610528611124565b6040518082815260200191505060405180910390f35b61054661112a565b6040518082815260200191505060405180910390f35b610564611130565b6040518082815260200191505060405180910390f35b6105bc6004803603602081101561059057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611136565b6040518082815260200191505060405180910390f35b6105da61117f565b6040518082815260200191505060405180910390f35b61061c6004803603602081101561060657600080fd5b8101908080359060200190929190505050611185565b60405180821515815260200191505060405180910390f35b61063c61136b565b6040518082815260200191505060405180910390f35b61065a61137a565b6040518082815260200191505060405180910390f35b61069c6004803603602081101561068657600080fd5b8101908080359060200190929190505050611380565b005b6106a661143f565b6040518082815260200191505060405180910390f35b6106f2600480360360408110156106d257600080fd5b810190808035906020019092919080359060200190929190505050611445565b6040518082815260200191505060405180910390f35b610710611459565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61074461147f565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610784578082015181840152602081019050610769565b50505050905090810190601f1680156107b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61080b600480360360408110156107d557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506114b8565b60405180821515815260200191505060405180910390f35b61084f6004803603602081101561083957600080fd5b81019080803590602001909291905050506114cf565b6040518082815260200191505060405180910390f35b61086d611602565b6040518082815260200191505060405180910390f35b6108c56004803603602081101561089957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611608565b6040518082815260200191505060405180910390f35b610927600480360360408110156108f157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611620565b60405180821515815260200191505060405180910390f35b610947611c32565b6040518082815260200191505060405180910390f35b610965611c38565b6040518082815260200191505060405180910390f35b6109bd6004803603602081101561099157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c3e565b6040518082815260200191505060405180910390f35b6109db611c56565b6040518082815260200191505060405180910390f35b610a5360048036036040811015610a0757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c65565b6040518082815260200191505060405180910390f35b610a9560048036036020811015610a7f57600080fd5b8101908080359060200190929190505050611cec565b60405180821515815260200191505060405180910390f35b610aed60048036036060811015610ac357600080fd5b810190808035906020019092919080359060200190929190803590602001909291905050506122b7565b6040518082815260200191505060405180910390f35b610b0b6122cd565b6040518082815260200191505060405180910390f35b610b4d60048036036020811015610b3757600080fd5b81019080803590602001909291905050506122d3565b604051808973ffffffffffffffffffffffffffffffffffffffff16815260200188151581526020018781526020018681526020018581526020018481526020018381526020018281526020019850505050505050505060405180910390f35b610bd860048036036020811015610bc257600080fd5b8101908080359060200190929190505050612348565b60405180821515815260200191505060405180910390f35b610bf8612939565b6040518082815260200191505060405180910390f35b6040518060400160405280600981526020017f477265656e776f6f64000000000000000000000000000000000000000000000081525081565b6000610c54338484612b59565b6001905092915050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d71275f6600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610d0b57600080fd5b505afa158015610d1f573d6000803e3d6000fd5b505050506040513d6020811015610d3557600080fd5b8101908080519060200190929190505050905090565b600043601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610e01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313900000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008211610e77576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313400000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b610ea43330843073ffffffffffffffffffffffffffffffffffffffff16612d50909392919063ffffffff16565b6000610eaf836114cf565b9050806009541015610f29576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313000000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000610f68610f45600954600854612ad190919063ffffffff16565b610f5a84600a546129c290919063ffffffff16565b612a4890919063ffffffff16565b9050610f7f81600a5461293f90919063ffffffff16565b600a81905550610f9a8260095461293f90919063ffffffff16565b600981905550610fa8612e11565b600c81905550610fb6612e71565b600b81905550610fc63385612f9f565b3373ffffffffffffffffffffffffffffffffffffffff167fac927268ea9ae2e55027e6ab727fc2db8e3ea48c56c658223a1074567e4298c08583604051808381526020018281526020019250505060405180910390a2600192505050919050565b600a5481565b60008054905090565b60006110438484846130dc565b6110f684336110f18560405180606001604052806031815260200161441f60319139600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546133969092919063ffffffff16565b612b59565b600190509392505050565b60085481565b60065481565b601281565b60155481565b60105481565b60115481565b600f5481565b60125481565b600e5481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60095481565b60008061119183613450565b90506000811180156111cd57506016546111ca6009546111bc60085485612ad190919063ffffffff16565b612ad190919063ffffffff16565b11155b61123f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313400000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61128e333085600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612d50909392919063ffffffff16565b6112a381600954612ad190919063ffffffff16565b60098190555043601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506112f5612e11565b600c81905550611303612e71565b600b819055506113133382613464565b3373ffffffffffffffffffffffffffffffffffffffff167f3bdb4d376f46aac1bdcda94b03200364052b278ed93865d759bf61452bfabdba826040518082815260200191505060405180910390a26001915050919050565b6000611375613697565b905090565b600b5481565b73e3d5260cd7f8a4207f41c3b2ac87882489f9721373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611435576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313800000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8060168190555050565b600d5481565b600061145183836137cf565b905092915050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600381526020017f47524e000000000000000000000000000000000000000000000000000000000081525081565b60006114c53384846130dc565b6001905092915050565b6000806115c66007546115b86006546115aa600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561156a57600080fd5b505afa15801561157e573d6000803e3d6000fd5b505050506040513d602081101561159457600080fd5b8101908080519060200190929190505050613450565b61293f90919063ffffffff16565b61293f90919063ffffffff16565b905060006115d261102d565b90506115f9816115eb84876129c290919063ffffffff16565b612a4890919063ffffffff16565b92505050919050565b60165481565b60186020528060005260406000206000915090505481565b6000808383604051602001808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040528051906020012090508373ffffffffffffffffffffffffffffffffffffffff166017600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611741576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313100000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600060176000838152602001908152602001600020604051806101000160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815250509050806020015115611889576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313200000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006118b86118a56119aa600f546129c290919063ffffffff16565b8360a00151612ad190919063ffffffff16565b905080431015611930576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313700000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61198b33306119428560800151613934565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612d50909392919063ffffffff16565b60008061199784613948565b9150915060008183116119bc576119b7838361293f90919063ffffffff16565b6119d0565b6119cf828461293f90919063ffffffff16565b5b905060008560800151905060008085851115611a3f576119f48489608001516139ab565b9350611a0d848960800151612ad190919063ffffffff16565b9150611a3884611a2a8a6060015186612ad190919063ffffffff16565b61293f90919063ffffffff16565b9050611a9e565b85851015611a7c57611a558489606001516139ab565b9350611a7288606001518960800151612ad190919063ffffffff16565b9150829050611a9d565b87608001519150611a9a886060015184612ad190919063ffffffff16565b90505b5b611ab7886080015160085461293f90919063ffffffff16565b600881905550611ad6886060015160065461293f90919063ffffffff16565b600681905550611af18360075461293f90919063ffffffff16565b600781905550611b0c82600954612ad190919063ffffffff16565b6009819055506001601760008b815260200190815260200160002060000160146101000a81548160ff021916908315150217905550611b49612e11565b600c81905550611b57612e71565b600b81905550611bb233611b6a83613934565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166139c49092919063ffffffff16565b8b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ff3fa0eaee8f258c23b013654df25d1527f98a5c7ccd5e951dd77caca400ef9728d84604051808381526020018281526020019250505060405180910390a36001995050505050505050505092915050565b60135481565b60145481565b60196020528060005260406000206000915090505481565b6000611c60612e71565b905090565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000803383604051602001808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040528051906020012090503373ffffffffffffffffffffffffffffffffffffffff166017600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611e0d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313100000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6017600082815260200190815260200160002060000160149054906101000a900460ff1615611ea4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313200000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600060176000838152602001908152602001600020604051806101000160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815250509050600080611f8083613948565b915091508260a001514311611ffd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313300000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600081831161201e57612019838361293f90919063ffffffff16565b612032565b612031828461293f90919063ffffffff16565b5b9050600084608001519050600080858511156120a1576120568488608001516139ab565b935061206f84886080015161293f90919063ffffffff16565b915061209a8461208c858a60600151612ad190919063ffffffff16565b612ad190919063ffffffff16565b9050612124565b85851015612102576120b78488606001516139ab565b93506120d0848860800151612ad190919063ffffffff16565b91506120fb846120ed858a60600151612ad190919063ffffffff16565b61293f90919063ffffffff16565b9050612123565b86608001519150612120838860600151612ad190919063ffffffff16565b90505b5b61213d876080015160085461293f90919063ffffffff16565b60088190555061215c876060015160065461293f90919063ffffffff16565b6006819055506121778360075461293f90919063ffffffff16565b60078190555061219282600954612ad190919063ffffffff16565b6009819055506001601760008a815260200190815260200160002060000160146101000a81548160ff0219169083151502179055506121cf612e11565b600c819055506121dd612e71565b600b81905550612238336121f083613934565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166139c49092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f23723065e08b5ed8daf98778977a2e34c11a7d04208b2f12d629329d0a421a84886040015188888b60e001516040518085815260200184815260200183815260200182815260200194505050505060405180910390a2600198505050505050505050919050565b60006122c4848484613a66565b90509392505050565b600c5481565b60176020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060000160149054906101000a900460ff16908060010154908060020154908060030154908060040154908060050154908060060154905088565b60008082116123bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260018152602001807f390000000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006123ca83613450565b90506000806123d883613bad565b91509150600954811115612454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313000000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008190506000600b549050600061248a6103e861247c6003886129c290919063ffffffff16565b612a4890919063ffffffff16565b90506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d6feb980600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561253957600080fd5b505afa15801561254d573d6000803e3d6000fd5b505050506040513d602081101561256357600080fd5b8101908080519060200190929190505050905060006040518061010001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001898152602001888152602001878152602001438152602001838152602001858152509050600033601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054604051602001808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052805190602001209050816017600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff02191690831515021790555060408201518160010155606082015181600201556080820151816003015560a0820151816004015560c0820151816005015560e082015181600601559050506127626001601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ad190919063ffffffff16565b601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506127ba87600854612ad190919063ffffffff16565b6008819055506127d588600654612ad190919063ffffffff16565b6006819055506127f086600754612ad190919063ffffffff16565b60078190555061280b8760095461293f90919063ffffffff16565b60098190555061282684600a54612ad190919063ffffffff16565b600a81905550600061285387612845878c612ad190919063ffffffff16565b612ad190919063ffffffff16565b905061285d612e11565b600c8190555061286b612e71565b600b819055506128c8333061287f84613934565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612d50909392919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f1328235872d7c5c1d43227eadd2c10c1514932b9de248bc5f6c7a225288560768b8a8960405180848152602001838152602001828152602001935050505060405180910390a260019a5050505050505050505050919050565b60075481565b6000828211156129b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b6000808314156129d55760009050612a42565b60008284029050828482816129e657fe5b0414612a3d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806145236021913960400191505060405180910390fd5b809150505b92915050565b6000808211612abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b818381612ac857fe5b04905092915050565b600080828401905083811015612b4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612bdf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d8152602001806143f2602d913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612c65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180614598602b913960400191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b612e0b846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c18565b50505050565b600080612e2b600954600854612ad190919063ffffffff16565b90506000612e5e82612e50670de0b6b3a76400006008546129c290919063ffffffff16565b612a4890919063ffffffff16565b9050600060648202905080935050505090565b600080600080600e541415612ecc57612ec5601254612eb7670de0b6b3a7640000612ea9601354600c546129c290919063ffffffff16565b612a4890919063ffffffff16565b612ad190919063ffffffff16565b9050612f04565b612efd670de0b6b3a7640000612eef601354600c546129c290919063ffffffff16565b612a4890919063ffffffff16565b6012540390505b601454600c541015612f255760008113612f1d57600080fd5b809150612f84565b6000612f6c670de0b6b3a7640000612f5e612f4d601454600c5461293f90919063ffffffff16565b6015546129c290919063ffffffff16565b612a4890919063ffffffff16565b9050600081830113612f7d57600080fd5b8082019250505b612f98606483612a4890919063ffffffff16565b9250505090565b6000612faa826114cf565b905060008111613022576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f494e53554646494349454e545f4c49515549444954595f4255524e454400000081525060200191505060405180910390fd5b61302c3083613d07565b6130818361303983613934565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166139c49092919063ffffffff16565b8273ffffffffffffffffffffffffffffffffffffffff167f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f8284604051808381526020018281526020019250505060405180910390a2505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415613162576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614450602e913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156131e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806144f7602c913960400191505060405180910390fd5b613254816040518060600160405280602f81526020016143c3602f9139600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546133969092919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506132e981600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ad190919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290613443576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156134085780820151818401526020810190506133ed565b50505050905090810190601f1680156134355780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082840390509392505050565b600061345d826001613ec1565b9050919050565b600061346e61102d565b9050600080821415613482578290506135bb565b6000613550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561351057600080fd5b505afa158015613524573d6000803e3d6000fd5b505050506040513d602081101561353a57600080fd5b8101908080519060200190929190505050613450565b9050600061358f856135816007546135736006548761293f90919063ffffffff16565b61293f90919063ffffffff16565b61293f90919063ffffffff16565b90506135b6816135a886886129c290919063ffffffff16565b612a4890919063ffffffff16565b925050505b60008111613631576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f494e53554646494349454e545f4c49515549444954595f4d494e54454400000081525060200191505060405180910390fd5b61363b8482613f1f565b8373ffffffffffffffffffffffffffffffffffffffff167f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f8483604051808381526020018281526020019250505060405180910390a250505050565b600080600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d71275f6600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561374557600080fd5b505afa158015613759573d6000803e3d6000fd5b505050506040513d602081101561376f57600080fd5b8101908080519060200190929190505050905060006137b360646137a5670de0b6b3a7640000600a6129c290919063ffffffff16565b612a4890919063ffffffff16565b90506137c88183612ad190919063ffffffff16565b9250505090565b600080600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d6feb980600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561387d57600080fd5b505afa158015613891573d6000803e3d6000fd5b505050506040513d60208110156138a757600080fd5b8101908080519060200190929190505050905060006138e9846138db670de0b6b3a7640000856129c290919063ffffffff16565b612a4890919063ffffffff16565b905061392a8561391c670de0b6b3a764000061390e858a6129c290919063ffffffff16565b612a4890919063ffffffff16565b61293f90919063ffffffff16565b9250505092915050565b6000613941826000613ec1565b9050919050565b600080600080600061396786604001518760e001518860a00151613a66565b9050600061397d87604001518860c001516137cf565b90506000600e5414156139955781935080925061399c565b8093508192505b83839550955050505050915091565b60008183106139ba57816139bc565b825b905092915050565b613a618363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c18565b505050565b600080613a9a610168613a8c670de0b6b3a7640000600f546129c290919063ffffffff16565b612a4890919063ffffffff16565b90506000613af7670de0b6b3a7640000613ae984613adb670de0b6b3a7640000613acd8b8d6129c290919063ffffffff16565b612a4890919063ffffffff16565b6129c290919063ffffffff16565b612a4890919063ffffffff16565b90506000613b0e854361293f90919063ffffffff16565b90506000613b296119aa600f546129c290919063ffffffff16565b90506000818310613b4257670de0b6b3a7640000613b70565b613b6f82613b61670de0b6b3a7640000866129c290919063ffffffff16565b612a4890919063ffffffff16565b5b9050613b9f670de0b6b3a7640000613b9183876129c290919063ffffffff16565b612a4890919063ffffffff16565b955050505050509392505050565b600080600080600e5414613bc857613bc3613697565b613bcc565b600b545b905060006001600e5414613be757613be2613697565b613beb565b600b545b90506000613bf986846140bf565b90506000613c0787846140bf565b905081819550955050505050915091565b6000613c7a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166141239092919063ffffffff16565b9050600081511115613d0257808060200190516020811015613c9b57600080fd5b8101908080519060200190929190505050613d01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061456e602a913960400191505060405180910390fd5b5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613d8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614544602a913960400191505060405180910390fd5b613df9816040518060600160405280602b81526020016144a6602b9139600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546133969092919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550613e518160005461293f90919063ffffffff16565b600081905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60008060126010541015613f115782613ef157613eec601154600a0a85612a4890919063ffffffff16565b613f0a565b613f09601154600a0a856129c290919063ffffffff16565b5b9050613f15565b8390505b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613fa5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061447e6028913960400191505060405180910390fd5b613fba81600054612ad190919063ffffffff16565b60008190555061401281600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ad190919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6000806140d9600f54610168612a4890919063ffffffff16565b905061411a8161410c670de0b6b3a76400006140fe87896129c290919063ffffffff16565b612a4890919063ffffffff16565b612a4890919063ffffffff16565b91505092915050565b6060614132848460008561413b565b90509392505050565b606082471015614196576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806144d16026913960400191505060405180910390fd5b61419f856142e3565b614211576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310614260578051825260208201915060208101905060208303925061423d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146142c2576040519150601f19603f3d011682016040523d82523d6000602084013e6142c7565b606091505b50915091506142d78282866142f6565b92505050949350505050565b600080823b905060008111915050919050565b60608315614306578290506143bb565b6000835111156143195782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614380578082015181840152602081019050614365565b50505050905090810190601f1680156143ad5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b939250505056fe477265656e776f6f6445524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365477265656e776f6f6445524332303a20617070726f76652066726f6d20746865207a65726f2061646472657373477265656e776f6f6445524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365477265656e776f6f6445524332303a207472616e736665722066726f6d20746865207a65726f2061646472657373477265656e776f6f6445524332303a206d696e7420746f20746865207a65726f2061646472657373477265656e776f6f6445524332303a206275726e20616d6f756e7420657863656564732062616c616e6365416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c477265656e776f6f6445524332303a207472616e7366657220746f20746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77477265656e776f6f6445524332303a206275726e2066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564477265656e776f6f6445524332303a20617070726f766520746f20746865207a65726f2061646472657373a2646970667358221220a296b8d7a92001e6cb1edd19c222cdc3cf016bdb6cd95e1fa6dbbb7bd010b4ea64736f6c63430007060033477265656e776f6f6445524332303a206d696e7420746f20746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000006000000000000000000000000888d6a7ab9a8a6cbe884f6e7e90adf1e24d247c300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000004563918244f400000000000000000000000000000000000000000000000000000c249fdd3277800000000000000000000000000000000000000000000000000004563918244f40000000000000000000000000000000000000000000000000000c0e6b85ac9ee0000000000000000000000000000bf469ba05900e3c50a7aed5074da5353bca79199
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061025e5760003560e01c80638064a05911610146578063c11eaae2116100c3578063e43c520d11610087578063e43c520d14610a69578063e588b50514610aad578063ea21cd9214610b03578063eb84e7f214610b21578063f3eb4f8a14610bac578063fa7e8d0114610bf05761025e565b8063c11eaae21461093f578063ce3f28f01461095d578063ce7539011461097b578063d14ab67d146109d3578063dd62ed3e146109f15761025e565b8063a9059cbb1161010a578063a9059cbb146107bf578063b2485f9714610823578063b63c44e714610865578063b6984be914610883578063bcbaf487146108db5761025e565b80638064a059146106705780638ce744261461069e5780638d7aeae5146106bc57806391cfad5a1461070857806395d89b411461073c5761025e565b8063330691ac116101df578063645539ed116101a3578063645539ed1461055c57806370a082311461057a578063735d80e3146105d257806376d58e1a146105f05780637b83002914610634578063802d1422146106525761025e565b8063330691ac146104c6578063356cd90a146104e45780633fc896a21461050257806354b6ba951461052057806361e08e721461053e5761025e565b806318160ddd1161022657806318160ddd146103ca57806323b872dd146103e857806327b380ea1461046c578063294164531461048a578063313ce567146104a85761025e565b806306fdde0314610263578063095ea7b3146102e65780630a2a8e781461034a5780630a861f2a1461036857806313114a9d146103ac575b600080fd5b61026b610c0e565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102ab578082015181840152602081019050610290565b50505050905090810190601f1680156102d85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610332600480360360408110156102fc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c47565b60405180821515815260200191505060405180910390f35b610352610c5e565b6040518082815260200191505060405180910390f35b6103946004803603602081101561037e57600080fd5b8101908080359060200190929190505050610d4b565b60405180821515815260200191505060405180910390f35b6103b4611027565b6040518082815260200191505060405180910390f35b6103d261102d565b6040518082815260200191505060405180910390f35b610454600480360360608110156103fe57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611036565b60405180821515815260200191505060405180910390f35b610474611101565b6040518082815260200191505060405180910390f35b610492611107565b6040518082815260200191505060405180910390f35b6104b061110d565b6040518082815260200191505060405180910390f35b6104ce611112565b6040518082815260200191505060405180910390f35b6104ec611118565b6040518082815260200191505060405180910390f35b61050a61111e565b6040518082815260200191505060405180910390f35b610528611124565b6040518082815260200191505060405180910390f35b61054661112a565b6040518082815260200191505060405180910390f35b610564611130565b6040518082815260200191505060405180910390f35b6105bc6004803603602081101561059057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611136565b6040518082815260200191505060405180910390f35b6105da61117f565b6040518082815260200191505060405180910390f35b61061c6004803603602081101561060657600080fd5b8101908080359060200190929190505050611185565b60405180821515815260200191505060405180910390f35b61063c61136b565b6040518082815260200191505060405180910390f35b61065a61137a565b6040518082815260200191505060405180910390f35b61069c6004803603602081101561068657600080fd5b8101908080359060200190929190505050611380565b005b6106a661143f565b6040518082815260200191505060405180910390f35b6106f2600480360360408110156106d257600080fd5b810190808035906020019092919080359060200190929190505050611445565b6040518082815260200191505060405180910390f35b610710611459565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61074461147f565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610784578082015181840152602081019050610769565b50505050905090810190601f1680156107b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61080b600480360360408110156107d557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506114b8565b60405180821515815260200191505060405180910390f35b61084f6004803603602081101561083957600080fd5b81019080803590602001909291905050506114cf565b6040518082815260200191505060405180910390f35b61086d611602565b6040518082815260200191505060405180910390f35b6108c56004803603602081101561089957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611608565b6040518082815260200191505060405180910390f35b610927600480360360408110156108f157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611620565b60405180821515815260200191505060405180910390f35b610947611c32565b6040518082815260200191505060405180910390f35b610965611c38565b6040518082815260200191505060405180910390f35b6109bd6004803603602081101561099157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c3e565b6040518082815260200191505060405180910390f35b6109db611c56565b6040518082815260200191505060405180910390f35b610a5360048036036040811015610a0757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c65565b6040518082815260200191505060405180910390f35b610a9560048036036020811015610a7f57600080fd5b8101908080359060200190929190505050611cec565b60405180821515815260200191505060405180910390f35b610aed60048036036060811015610ac357600080fd5b810190808035906020019092919080359060200190929190803590602001909291905050506122b7565b6040518082815260200191505060405180910390f35b610b0b6122cd565b6040518082815260200191505060405180910390f35b610b4d60048036036020811015610b3757600080fd5b81019080803590602001909291905050506122d3565b604051808973ffffffffffffffffffffffffffffffffffffffff16815260200188151581526020018781526020018681526020018581526020018481526020018381526020018281526020019850505050505050505060405180910390f35b610bd860048036036020811015610bc257600080fd5b8101908080359060200190929190505050612348565b60405180821515815260200191505060405180910390f35b610bf8612939565b6040518082815260200191505060405180910390f35b6040518060400160405280600981526020017f477265656e776f6f64000000000000000000000000000000000000000000000081525081565b6000610c54338484612b59565b6001905092915050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d71275f6600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610d0b57600080fd5b505afa158015610d1f573d6000803e3d6000fd5b505050506040513d6020811015610d3557600080fd5b8101908080519060200190929190505050905090565b600043601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610e01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313900000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008211610e77576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313400000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b610ea43330843073ffffffffffffffffffffffffffffffffffffffff16612d50909392919063ffffffff16565b6000610eaf836114cf565b9050806009541015610f29576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313000000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000610f68610f45600954600854612ad190919063ffffffff16565b610f5a84600a546129c290919063ffffffff16565b612a4890919063ffffffff16565b9050610f7f81600a5461293f90919063ffffffff16565b600a81905550610f9a8260095461293f90919063ffffffff16565b600981905550610fa8612e11565b600c81905550610fb6612e71565b600b81905550610fc63385612f9f565b3373ffffffffffffffffffffffffffffffffffffffff167fac927268ea9ae2e55027e6ab727fc2db8e3ea48c56c658223a1074567e4298c08583604051808381526020018281526020019250505060405180910390a2600192505050919050565b600a5481565b60008054905090565b60006110438484846130dc565b6110f684336110f18560405180606001604052806031815260200161441f60319139600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546133969092919063ffffffff16565b612b59565b600190509392505050565b60085481565b60065481565b601281565b60155481565b60105481565b60115481565b600f5481565b60125481565b600e5481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60095481565b60008061119183613450565b90506000811180156111cd57506016546111ca6009546111bc60085485612ad190919063ffffffff16565b612ad190919063ffffffff16565b11155b61123f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313400000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61128e333085600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612d50909392919063ffffffff16565b6112a381600954612ad190919063ffffffff16565b60098190555043601960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506112f5612e11565b600c81905550611303612e71565b600b819055506113133382613464565b3373ffffffffffffffffffffffffffffffffffffffff167f3bdb4d376f46aac1bdcda94b03200364052b278ed93865d759bf61452bfabdba826040518082815260200191505060405180910390a26001915050919050565b6000611375613697565b905090565b600b5481565b73e3d5260cd7f8a4207f41c3b2ac87882489f9721373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611435576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313800000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8060168190555050565b600d5481565b600061145183836137cf565b905092915050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600381526020017f47524e000000000000000000000000000000000000000000000000000000000081525081565b60006114c53384846130dc565b6001905092915050565b6000806115c66007546115b86006546115aa600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561156a57600080fd5b505afa15801561157e573d6000803e3d6000fd5b505050506040513d602081101561159457600080fd5b8101908080519060200190929190505050613450565b61293f90919063ffffffff16565b61293f90919063ffffffff16565b905060006115d261102d565b90506115f9816115eb84876129c290919063ffffffff16565b612a4890919063ffffffff16565b92505050919050565b60165481565b60186020528060005260406000206000915090505481565b6000808383604051602001808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040528051906020012090508373ffffffffffffffffffffffffffffffffffffffff166017600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611741576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313100000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600060176000838152602001908152602001600020604051806101000160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815250509050806020015115611889576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313200000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006118b86118a56119aa600f546129c290919063ffffffff16565b8360a00151612ad190919063ffffffff16565b905080431015611930576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313700000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61198b33306119428560800151613934565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612d50909392919063ffffffff16565b60008061199784613948565b9150915060008183116119bc576119b7838361293f90919063ffffffff16565b6119d0565b6119cf828461293f90919063ffffffff16565b5b905060008560800151905060008085851115611a3f576119f48489608001516139ab565b9350611a0d848960800151612ad190919063ffffffff16565b9150611a3884611a2a8a6060015186612ad190919063ffffffff16565b61293f90919063ffffffff16565b9050611a9e565b85851015611a7c57611a558489606001516139ab565b9350611a7288606001518960800151612ad190919063ffffffff16565b9150829050611a9d565b87608001519150611a9a886060015184612ad190919063ffffffff16565b90505b5b611ab7886080015160085461293f90919063ffffffff16565b600881905550611ad6886060015160065461293f90919063ffffffff16565b600681905550611af18360075461293f90919063ffffffff16565b600781905550611b0c82600954612ad190919063ffffffff16565b6009819055506001601760008b815260200190815260200160002060000160146101000a81548160ff021916908315150217905550611b49612e11565b600c81905550611b57612e71565b600b81905550611bb233611b6a83613934565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166139c49092919063ffffffff16565b8b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ff3fa0eaee8f258c23b013654df25d1527f98a5c7ccd5e951dd77caca400ef9728d84604051808381526020018281526020019250505060405180910390a36001995050505050505050505092915050565b60135481565b60145481565b60196020528060005260406000206000915090505481565b6000611c60612e71565b905090565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000803383604051602001808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040528051906020012090503373ffffffffffffffffffffffffffffffffffffffff166017600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611e0d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313100000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6017600082815260200190815260200160002060000160149054906101000a900460ff1615611ea4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313200000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600060176000838152602001908152602001600020604051806101000160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815250509050600080611f8083613948565b915091508260a001514311611ffd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313300000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600081831161201e57612019838361293f90919063ffffffff16565b612032565b612031828461293f90919063ffffffff16565b5b9050600084608001519050600080858511156120a1576120568488608001516139ab565b935061206f84886080015161293f90919063ffffffff16565b915061209a8461208c858a60600151612ad190919063ffffffff16565b612ad190919063ffffffff16565b9050612124565b85851015612102576120b78488606001516139ab565b93506120d0848860800151612ad190919063ffffffff16565b91506120fb846120ed858a60600151612ad190919063ffffffff16565b61293f90919063ffffffff16565b9050612123565b86608001519150612120838860600151612ad190919063ffffffff16565b90505b5b61213d876080015160085461293f90919063ffffffff16565b60088190555061215c876060015160065461293f90919063ffffffff16565b6006819055506121778360075461293f90919063ffffffff16565b60078190555061219282600954612ad190919063ffffffff16565b6009819055506001601760008a815260200190815260200160002060000160146101000a81548160ff0219169083151502179055506121cf612e11565b600c819055506121dd612e71565b600b81905550612238336121f083613934565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166139c49092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f23723065e08b5ed8daf98778977a2e34c11a7d04208b2f12d629329d0a421a84886040015188888b60e001516040518085815260200184815260200183815260200182815260200194505050505060405180910390a2600198505050505050505050919050565b60006122c4848484613a66565b90509392505050565b600c5481565b60176020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060000160149054906101000a900460ff16908060010154908060020154908060030154908060040154908060050154908060060154905088565b60008082116123bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260018152602001807f390000000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006123ca83613450565b90506000806123d883613bad565b91509150600954811115612454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f313000000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60008190506000600b549050600061248a6103e861247c6003886129c290919063ffffffff16565b612a4890919063ffffffff16565b90506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d6feb980600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561253957600080fd5b505afa15801561254d573d6000803e3d6000fd5b505050506040513d602081101561256357600080fd5b8101908080519060200190929190505050905060006040518061010001604052803373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001898152602001888152602001878152602001438152602001838152602001858152509050600033601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054604051602001808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052805190602001209050816017600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff02191690831515021790555060408201518160010155606082015181600201556080820151816003015560a0820151816004015560c0820151816005015560e082015181600601559050506127626001601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ad190919063ffffffff16565b601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506127ba87600854612ad190919063ffffffff16565b6008819055506127d588600654612ad190919063ffffffff16565b6006819055506127f086600754612ad190919063ffffffff16565b60078190555061280b8760095461293f90919063ffffffff16565b60098190555061282684600a54612ad190919063ffffffff16565b600a81905550600061285387612845878c612ad190919063ffffffff16565b612ad190919063ffffffff16565b905061285d612e11565b600c8190555061286b612e71565b600b819055506128c8333061287f84613934565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612d50909392919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f1328235872d7c5c1d43227eadd2c10c1514932b9de248bc5f6c7a225288560768b8a8960405180848152602001838152602001828152602001935050505060405180910390a260019a5050505050505050505050919050565b60075481565b6000828211156129b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b6000808314156129d55760009050612a42565b60008284029050828482816129e657fe5b0414612a3d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806145236021913960400191505060405180910390fd5b809150505b92915050565b6000808211612abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b818381612ac857fe5b04905092915050565b600080828401905083811015612b4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612bdf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d8152602001806143f2602d913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612c65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180614598602b913960400191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b612e0b846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c18565b50505050565b600080612e2b600954600854612ad190919063ffffffff16565b90506000612e5e82612e50670de0b6b3a76400006008546129c290919063ffffffff16565b612a4890919063ffffffff16565b9050600060648202905080935050505090565b600080600080600e541415612ecc57612ec5601254612eb7670de0b6b3a7640000612ea9601354600c546129c290919063ffffffff16565b612a4890919063ffffffff16565b612ad190919063ffffffff16565b9050612f04565b612efd670de0b6b3a7640000612eef601354600c546129c290919063ffffffff16565b612a4890919063ffffffff16565b6012540390505b601454600c541015612f255760008113612f1d57600080fd5b809150612f84565b6000612f6c670de0b6b3a7640000612f5e612f4d601454600c5461293f90919063ffffffff16565b6015546129c290919063ffffffff16565b612a4890919063ffffffff16565b9050600081830113612f7d57600080fd5b8082019250505b612f98606483612a4890919063ffffffff16565b9250505090565b6000612faa826114cf565b905060008111613022576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f494e53554646494349454e545f4c49515549444954595f4255524e454400000081525060200191505060405180910390fd5b61302c3083613d07565b6130818361303983613934565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166139c49092919063ffffffff16565b8273ffffffffffffffffffffffffffffffffffffffff167f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f8284604051808381526020018281526020019250505060405180910390a2505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415613162576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180614450602e913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156131e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806144f7602c913960400191505060405180910390fd5b613254816040518060600160405280602f81526020016143c3602f9139600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546133969092919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506132e981600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ad190919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290613443576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156134085780820151818401526020810190506133ed565b50505050905090810190601f1680156134355780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082840390509392505050565b600061345d826001613ec1565b9050919050565b600061346e61102d565b9050600080821415613482578290506135bb565b6000613550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561351057600080fd5b505afa158015613524573d6000803e3d6000fd5b505050506040513d602081101561353a57600080fd5b8101908080519060200190929190505050613450565b9050600061358f856135816007546135736006548761293f90919063ffffffff16565b61293f90919063ffffffff16565b61293f90919063ffffffff16565b90506135b6816135a886886129c290919063ffffffff16565b612a4890919063ffffffff16565b925050505b60008111613631576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f494e53554646494349454e545f4c49515549444954595f4d494e54454400000081525060200191505060405180910390fd5b61363b8482613f1f565b8373ffffffffffffffffffffffffffffffffffffffff167f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f8483604051808381526020018281526020019250505060405180910390a250505050565b600080600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d71275f6600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561374557600080fd5b505afa158015613759573d6000803e3d6000fd5b505050506040513d602081101561376f57600080fd5b8101908080519060200190929190505050905060006137b360646137a5670de0b6b3a7640000600a6129c290919063ffffffff16565b612a4890919063ffffffff16565b90506137c88183612ad190919063ffffffff16565b9250505090565b600080600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d6feb980600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561387d57600080fd5b505afa158015613891573d6000803e3d6000fd5b505050506040513d60208110156138a757600080fd5b8101908080519060200190929190505050905060006138e9846138db670de0b6b3a7640000856129c290919063ffffffff16565b612a4890919063ffffffff16565b905061392a8561391c670de0b6b3a764000061390e858a6129c290919063ffffffff16565b612a4890919063ffffffff16565b61293f90919063ffffffff16565b9250505092915050565b6000613941826000613ec1565b9050919050565b600080600080600061396786604001518760e001518860a00151613a66565b9050600061397d87604001518860c001516137cf565b90506000600e5414156139955781935080925061399c565b8093508192505b83839550955050505050915091565b60008183106139ba57816139bc565b825b905092915050565b613a618363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c18565b505050565b600080613a9a610168613a8c670de0b6b3a7640000600f546129c290919063ffffffff16565b612a4890919063ffffffff16565b90506000613af7670de0b6b3a7640000613ae984613adb670de0b6b3a7640000613acd8b8d6129c290919063ffffffff16565b612a4890919063ffffffff16565b6129c290919063ffffffff16565b612a4890919063ffffffff16565b90506000613b0e854361293f90919063ffffffff16565b90506000613b296119aa600f546129c290919063ffffffff16565b90506000818310613b4257670de0b6b3a7640000613b70565b613b6f82613b61670de0b6b3a7640000866129c290919063ffffffff16565b612a4890919063ffffffff16565b5b9050613b9f670de0b6b3a7640000613b9183876129c290919063ffffffff16565b612a4890919063ffffffff16565b955050505050509392505050565b600080600080600e5414613bc857613bc3613697565b613bcc565b600b545b905060006001600e5414613be757613be2613697565b613beb565b600b545b90506000613bf986846140bf565b90506000613c0787846140bf565b905081819550955050505050915091565b6000613c7a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166141239092919063ffffffff16565b9050600081511115613d0257808060200190516020811015613c9b57600080fd5b8101908080519060200190929190505050613d01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061456e602a913960400191505060405180910390fd5b5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613d8d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614544602a913960400191505060405180910390fd5b613df9816040518060600160405280602b81526020016144a6602b9139600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546133969092919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550613e518160005461293f90919063ffffffff16565b600081905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60008060126010541015613f115782613ef157613eec601154600a0a85612a4890919063ffffffff16565b613f0a565b613f09601154600a0a856129c290919063ffffffff16565b5b9050613f15565b8390505b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613fa5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061447e6028913960400191505060405180910390fd5b613fba81600054612ad190919063ffffffff16565b60008190555061401281600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ad190919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6000806140d9600f54610168612a4890919063ffffffff16565b905061411a8161410c670de0b6b3a76400006140fe87896129c290919063ffffffff16565b612a4890919063ffffffff16565b612a4890919063ffffffff16565b91505092915050565b6060614132848460008561413b565b90509392505050565b606082471015614196576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806144d16026913960400191505060405180910390fd5b61419f856142e3565b614211576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310614260578051825260208201915060208101905060208303925061423d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146142c2576040519150601f19603f3d011682016040523d82523d6000602084013e6142c7565b606091505b50915091506142d78282866142f6565b92505050949350505050565b600080823b905060008111915050919050565b60608315614306578290506143bb565b6000835111156143195782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614380578082015181840152602081019050614365565b50505050905090810190601f1680156143ad5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b939250505056fe477265656e776f6f6445524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365477265656e776f6f6445524332303a20617070726f76652066726f6d20746865207a65726f2061646472657373477265656e776f6f6445524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365477265656e776f6f6445524332303a207472616e736665722066726f6d20746865207a65726f2061646472657373477265656e776f6f6445524332303a206d696e7420746f20746865207a65726f2061646472657373477265656e776f6f6445524332303a206275726e20616d6f756e7420657863656564732062616c616e6365416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c477265656e776f6f6445524332303a207472616e7366657220746f20746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77477265656e776f6f6445524332303a206275726e2066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564477265656e776f6f6445524332303a20617070726f766520746f20746865207a65726f2061646472657373a2646970667358221220a296b8d7a92001e6cb1edd19c222cdc3cf016bdb6cd95e1fa6dbbb7bd010b4ea64736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000006000000000000000000000000888d6a7ab9a8a6cbe884f6e7e90adf1e24d247c300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000004563918244f400000000000000000000000000000000000000000000000000000c249fdd3277800000000000000000000000000000000000000000000000000004563918244f40000000000000000000000000000000000000000000000000000c0e6b85ac9ee0000000000000000000000000000bf469ba05900e3c50a7aed5074da5353bca79199
-----Decoded View---------------
Arg [0] : _underlier (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [1] : _underlierDecimals (uint256): 6
Arg [2] : _adapter (address): 0x888D6A7Ab9a8a6CbE884F6e7E90ADF1E24d247c3
Arg [3] : _protocol (uint256): 0
Arg [4] : _direction (uint256): 1
Arg [5] : _durationInDays (uint256): 5
Arg [6] : _initialDeposit (uint256): 1000000
Arg [7] : _rateLimit (uint256): 80000000000000000000
Arg [8] : _rateSensitivity (uint256): 14000000000000000000
Arg [9] : _utilizationInflection (uint256): 5000000000000000000
Arg [10] : _rateMultiplier (uint256): 13900000000000000000
Arg [11] : _poolDeployer (address): 0xbF469Ba05900e3C50a7AED5074Da5353BCa79199
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [2] : 000000000000000000000000888d6a7ab9a8a6cbe884f6e7e90adf1e24d247c3
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [6] : 00000000000000000000000000000000000000000000000000000000000f4240
Arg [7] : 000000000000000000000000000000000000000000000004563918244f400000
Arg [8] : 000000000000000000000000000000000000000000000000c249fdd327780000
Arg [9] : 0000000000000000000000000000000000000000000000004563918244f40000
Arg [10] : 000000000000000000000000000000000000000000000000c0e6b85ac9ee0000
Arg [11] : 000000000000000000000000bf469ba05900e3c50a7aed5074da5353bca79199
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.999905 | 385.9253 | $385.89 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.