ERC-20
Overview
Max Total Supply
10,186.090192352165020306 ibexS
Holders
9
Market
Price
$0.00 @ 0.000000 S
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
2.302747331537513517 ibexSValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
LendingVaultV1
Compiler Version
v0.5.16+commit.9c3226ce
Optimization Enabled:
Yes with 999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity =0.5.16; import "./LVSetterV1.sol"; import "./interfaces/ILendingVaultV1Factory.sol"; contract LendingVaultV1 is LVSetterV1 { function _getTotalSupplied() internal returns (uint totalSupplied) { for (uint i = 0; i < borrowables.length; i++) { address borrowable = borrowables[i]; totalSupplied = totalSupplied.add(borrowable.myUnderlyingBalance()); } } function _mintReserves(uint _exchangeRate, uint _totalSupply) internal returns (uint) { uint _exchangeRateLast = exchangeRateLast; if (_exchangeRate > _exchangeRateLast) { uint _exchangeRateNew = _exchangeRate.sub( _exchangeRate.sub(_exchangeRateLast).mul(reserveFactor).div(1e18) ); uint liquidity = _totalSupply.mul(_exchangeRate).div(_exchangeRateNew).sub(_totalSupply); if (liquidity > 0) { address reservesManager = ILendingVaultV1Factory(factory).reservesManager(); _mint(reservesManager, liquidity); } exchangeRateLast = _exchangeRateNew; return _exchangeRateNew; } else return _exchangeRate; } function exchangeRate() public returns (uint) { uint _totalSupply = totalSupply; uint _actualBalance = totalBalance.add(_getTotalSupplied()); if (_totalSupply == 0 || _actualBalance == 0) return initialExchangeRate; uint _exchangeRate = _actualBalance.mul(1e18).div(_totalSupply); return _mintReserves(_exchangeRate, _totalSupply); } // this low-level function should be called from another contract function mint(address minter) external nonReentrant update returns (uint mintTokens) { uint balance = underlying.myBalance(); uint mintAmount = balance.sub(totalBalance); mintTokens = mintAmount.mul(1e18).div(exchangeRate()); if(totalSupply == 0) { // permanently lock the first MINIMUM_LIQUIDITY tokens mintTokens = mintTokens.sub(MINIMUM_LIQUIDITY); _mint(address(0), MINIMUM_LIQUIDITY); } require(mintTokens > 0, "LendingVaultV1: MINT_AMOUNT_ZERO"); _mint(minter, mintTokens); _withdrawAndReallocate(0); emit Mint(msg.sender, minter, mintAmount, mintTokens); } // this low-level function should be called from another contract function redeem(address redeemer) external nonReentrant update returns (uint redeemAmount) { uint redeemTokens = balanceOf[address(this)]; redeemAmount = redeemTokens.mul(exchangeRate()).div(1e18); require(redeemAmount > 0, "LendingVaultV1: REDEEM_AMOUNT_ZERO"); _burn(address(this), redeemTokens); _withdrawAndReallocate(redeemAmount); underlying.safeTransfer(redeemer, redeemAmount); emit Redeem(msg.sender, redeemer, redeemAmount, redeemTokens); } function reallocate() external nonReentrant update { _withdrawAndReallocate(0); } }
pragma solidity =0.5.16; import "./libraries/SafeMath.sol"; // This contract is basically UniswapV2ERC20 with small modifications // src: https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol contract ImpermaxERC20 { using SafeMath for uint; string public name; string public symbol; uint8 public decimals = 18; uint public totalSupply; mapping(address => uint) public balanceOf; mapping(address => mapping(address => uint)) public allowance; bytes32 public DOMAIN_SEPARATOR; mapping(address => uint) public nonces; event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); constructor() public {} function _setName(string memory _name, string memory _symbol) internal { name = _name; symbol = _symbol; uint chainId; assembly { chainId := chainid } DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(_name)), keccak256(bytes("1")), chainId, address(this) ) ); } function _mint(address to, uint value) internal { totalSupply = totalSupply.add(value); balanceOf[to] = balanceOf[to].add(value); emit Transfer(address(0), to, value); } function _burn(address from, uint value) internal { balanceOf[from] = balanceOf[from].sub(value); totalSupply = totalSupply.sub(value); emit Transfer(from, address(0), value); } function _approve(address owner, address spender, uint value) private { allowance[owner][spender] = value; emit Approval(owner, spender, value); } function _transfer(address from, address to, uint value) internal { balanceOf[from] = balanceOf[from].sub(value, "Impermax: TRANSFER_TOO_HIGH"); balanceOf[to] = balanceOf[to].add(value); emit Transfer(from, to, value); } function approve(address spender, uint value) external returns (bool) { _approve(msg.sender, spender, value); return true; } function transfer(address to, uint value) external returns (bool) { _transfer(msg.sender, to, value); return true; } function transferFrom(address from, address to, uint value) external returns (bool) { if (allowance[from][msg.sender] != uint(-1)) { allowance[from][msg.sender] = allowance[from][msg.sender].sub(value, "Impermax: TRANSFER_NOT_ALLOWED"); } _transfer(from, to, value); return true; } function _checkSignature(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s, bytes32 typehash) internal { require(deadline >= block.timestamp, "Impermax: EXPIRED"); bytes32 digest = keccak256( abi.encodePacked( '\x19\x01', DOMAIN_SEPARATOR, keccak256(abi.encode(typehash, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, "Impermax: INVALID_SIGNATURE"); } // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { _checkSignature(owner, spender, value, deadline, v, r, s, PERMIT_TYPEHASH); _approve(owner, spender, value); } }
pragma solidity >=0.5.0; interface IBorrowable { /*** Impermax ERC20 ***/ event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; /*** Pool Token ***/ event Mint(address indexed sender, address indexed minter, uint mintAmount, uint mintTokens); event Redeem(address indexed sender, address indexed redeemer, uint redeemAmount, uint redeemTokens); event Sync(uint totalBalance); function underlying() external view returns (address); function factory() external view returns (address); function totalBalance() external view returns (uint); function MINIMUM_LIQUIDITY() external pure returns (uint); function exchangeRate() external returns (uint); function mint(address minter) external returns (uint mintTokens); function redeem(address redeemer) external returns (uint redeemAmount); function skim(address to) external; function sync() external; function _setFactory() external; /*** Borrowable ***/ event BorrowApproval(address indexed owner, address indexed spender, uint value); event Borrow(address indexed sender, address indexed borrower, address indexed receiver, uint borrowAmount, uint repayAmount, uint accountBorrowsPrior, uint accountBorrows, uint totalBorrows); event Liquidate(address indexed sender, address indexed borrower, address indexed liquidator, uint seizeTokens, uint repayAmount, uint accountBorrowsPrior, uint accountBorrows, uint totalBorrows); function BORROW_FEE() external pure returns (uint); function collateral() external view returns (address); function reserveFactor() external view returns (uint); function exchangeRateLast() external view returns (uint); function borrowIndex() external view returns (uint); function totalBorrows() external view returns (uint); function borrowAllowance(address owner, address spender) external view returns (uint); function borrowBalance(address borrower) external view returns (uint); function borrowTracker() external view returns (address); function BORROW_PERMIT_TYPEHASH() external pure returns (bytes32); function borrowApprove(address spender, uint256 value) external returns (bool); function borrowPermit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; function borrow(address borrower, address receiver, uint borrowAmount, bytes calldata data) external; function liquidate(address borrower, address liquidator) external returns (uint seizeTokens); function trackBorrow(address borrower) external; /*** Borrowable Interest Rate Model ***/ event AccrueInterest(uint interestAccumulated, uint borrowIndex, uint totalBorrows); event CalculateKink(uint kinkRate); event CalculateBorrowRate(uint borrowRate); function KINK_BORROW_RATE_MAX() external pure returns (uint); function KINK_BORROW_RATE_MIN() external pure returns (uint); function KINK_MULTIPLIER() external pure returns (uint); function borrowRate() external view returns (uint); function kinkBorrowRate() external view returns (uint); function kinkUtilizationRate() external view returns (uint); function adjustSpeed() external view returns (uint); function rateUpdateTimestamp() external view returns (uint32); function accrualTimestamp() external view returns (uint32); function accrueInterest() external; /*** Borrowable Setter ***/ event NewReserveFactor(uint newReserveFactor); event NewKinkUtilizationRate(uint newKinkUtilizationRate); event NewAdjustSpeed(uint newAdjustSpeed); event NewBorrowTracker(address newBorrowTracker); function RESERVE_FACTOR_MAX() external pure returns (uint); function KINK_UR_MIN() external pure returns (uint); function KINK_UR_MAX() external pure returns (uint); function ADJUST_SPEED_MIN() external pure returns (uint); function ADJUST_SPEED_MAX() external pure returns (uint); function _initialize ( string calldata _name, string calldata _symbol, address _underlying, address _collateral ) external; function _setReserveFactor(uint newReserveFactor) external; function _setKinkUtilizationRate(uint newKinkUtilizationRate) external; function _setAdjustSpeed(uint newAdjustSpeed) external; function _setBorrowTracker(address newBorrowTracker) external; }
pragma solidity >=0.5.0; interface IERC20 { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); }
pragma solidity >=0.5.0; interface ILendingVaultV1 { /*** Impermax ERC20 ***/ event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; /*** Pool Token ***/ event Mint(address indexed sender, address indexed minter, uint mintAmount, uint mintTokens); event Redeem(address indexed sender, address indexed redeemer, uint redeemAmount, uint redeemTokens); event Sync(uint totalBalance); function underlying() external view returns (address); function factory() external view returns (address); function totalBalance() external view returns (uint); function MINIMUM_LIQUIDITY() external pure returns (uint); function exchangeRate() external returns (uint); function mint(address minter) external returns (uint mintTokens); function redeem(address redeemer) external returns (uint redeemAmount); function skim(address to) external; function sync() external; function _setFactory() external; /*** Lending Vault V1 ***/ event AddBorrowable(address indexed borrowable); event RemoveBorrowable(address indexed borrowable); event EnableBorrowable(address indexed borrowable); event DisableBorrowable(address indexed borrowable); event UnwindBorrowable(address indexed borrowable, uint256 underlyingBalance, uint256 actualRedeemAmount); event AllocateIntoBorrowable(address indexed borrowable, uint256 mintAmount, uint256 mintTokens); event DeallocateFromBorrowable(address indexed borrowable, uint256 redeemAmount, uint256 redeemTokens); function borrowables(uint) external view returns (address borrowable); function borrowableInfo(address borrowable) external view returns ( bool enabled, bool exists ); function getBorrowablesLength() external view returns (uint); function indexOfBorrowable(address borrowable) external view returns (uint); function reserveFactor() external view returns (uint); function exchangeRateLast() external view returns (uint); function addBorrowable(address borrowable) external; function removeBorrowable(address borrowable) external; function disableBorrowable(address borrowable) external; function enableBorrowable(address borrowable) external; function unwindBorrowable(address borrowable) external; function reallocate() external; /*** Lending Vault Setter ***/ event NewReserveFactor(uint newReserveFactor); function RESERVE_FACTOR_MAX() external pure returns (uint); function _initialize ( address _underlying, string calldata _name, string calldata _symbol ) external; function _setReserveFactor(uint newReserveFactor) external; }
pragma solidity >=0.5.0; interface ILendingVaultV1Factory { event VaultCreated(address indexed underlying, address vault, uint); event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin); event NewAdmin(address oldAdmin, address newAdmin); event NewReservesPendingAdmin(address oldReservesPendingAdmin, address newReservesPendingAdmin); event NewReservesAdmin(address oldReservesAdmin, address newReservesAdmin); event NewReservesManager(address oldReservesManager, address newReservesManager); function admin() external view returns (address); function pendingAdmin() external view returns (address); function reservesAdmin() external view returns (address); function reservesPendingAdmin() external view returns (address); function reservesManager() external view returns (address); function allVaults(uint) external view returns (address); function allVaultsLength() external view returns (uint); function createVault(address underlying, string calldata _name, string calldata _symbol) external returns (address vault); function _setPendingAdmin(address newPendingAdmin) external; function _acceptAdmin() external; function _setReservesPendingAdmin(address newPendingAdmin) external; function _acceptReservesAdmin() external; function _setReservesManager(address newReservesManager) external; }
pragma solidity >=0.5.0; interface IPoolToken { /*** Impermax ERC20 ***/ event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; /*** Pool Token ***/ event Mint(address indexed sender, address indexed minter, uint mintAmount, uint mintTokens); event Redeem(address indexed sender, address indexed redeemer, uint redeemAmount, uint redeemTokens); event Sync(uint totalBalance); function underlying() external view returns (address); function factory() external view returns (address); function totalBalance() external view returns (uint); function MINIMUM_LIQUIDITY() external pure returns (uint); function exchangeRate() external returns (uint); function mint(address minter) external returns (uint mintTokens); function redeem(address redeemer) external returns (uint redeemAmount); function skim(address to) external; function sync() external; function _setFactory() external; }
pragma solidity =0.5.16; import "./SafeMath.sol"; import "../interfaces/IBorrowable.sol"; import "../interfaces/IERC20.sol"; library BorrowableHelpers { using SafeMath for uint256; function underlyingValueOf(address borrowable, uint256 borrowableAmount) internal returns (uint256) { uint256 exchangeRate = IBorrowable(borrowable).exchangeRate(); return borrowableAmount.mul(exchangeRate).div(1e18); } function underlyingBalanceOf(address borrowable, address account) internal returns (uint256) { return underlyingValueOf(borrowable, IBorrowable(borrowable).balanceOf(account)); } function myUnderlyingBalance(address borrowable) internal returns (uint256) { return underlyingValueOf(borrowable, IBorrowable(borrowable).balanceOf(address(this))); } /*** AMOUNT TO TOKENS CONVERSION ***/ function tokensFor(uint redeemAmount, uint exchangeRate, bool atMost) internal pure returns (uint redeemTokens) { uint redeemTokensLow = redeemAmount.mul(1e18).div(exchangeRate); uint redeemTokensHigh = redeemTokensLow.add(1); if (atMost) { uint actualRedeemAmountHigh = redeemTokensHigh.mul(exchangeRate).div(1e18); return actualRedeemAmountHigh <= redeemAmount ? redeemTokensHigh : redeemTokensLow; } else { uint actualRedeemAmountLow = redeemTokensLow.mul(exchangeRate).div(1e18); return actualRedeemAmountLow >= redeemAmount ? redeemTokensLow : redeemTokensHigh; } } function tokensForAtMost(uint redeemAmount, uint exchangeRate) internal pure returns (uint redeemTokens) { return tokensFor(redeemAmount, exchangeRate, true); } function tokensForAtLeast(uint redeemAmount, uint exchangeRate) internal pure returns (uint redeemTokens) { return tokensFor(redeemAmount, exchangeRate, false); } }
pragma solidity =0.5.16; pragma experimental ABIEncoderV2; import "./SafeMath.sol"; import "./Math.sol"; import "../interfaces/IBorrowable.sol"; library BorrowableObject { using SafeMath for uint; using BorrowableObject for Borrowable; struct Borrowable { IBorrowable borrowableContract; uint exchangeRate; uint totalBorrows; // in underlyings uint externalSupply; // in underlyings uint initialOwnedSupply; // in underlyings uint ownedSupply; // in underlyings uint kinkBorrowRate; uint kinkUtilizationRate; uint reserveFactor; uint kinkMultiplier; uint cachedSupplyRate; } function newBorrowable(IBorrowable borrowableContract, address lendingVault) internal returns (Borrowable memory borrowable) { borrowableContract.sync(); uint exchangeRate = borrowableContract.exchangeRate(); uint totalSupplyInTokens = borrowableContract.totalSupply(); uint ownedSupplyInTokens = borrowableContract.balanceOf(lendingVault); uint externalSupplyInTokens = totalSupplyInTokens.sub(ownedSupplyInTokens); borrowable = Borrowable({ borrowableContract: borrowableContract, exchangeRate: exchangeRate, totalBorrows: borrowableContract.totalBorrows(), externalSupply: externalSupplyInTokens.mul(exchangeRate).div(1e18), initialOwnedSupply: ownedSupplyInTokens.mul(exchangeRate).div(1e18), ownedSupply: ownedSupplyInTokens.mul(exchangeRate).div(1e18), kinkBorrowRate: borrowableContract.kinkBorrowRate(), kinkUtilizationRate: borrowableContract.kinkUtilizationRate(), reserveFactor: borrowableContract.reserveFactor(), kinkMultiplier: borrowableContract.KINK_MULTIPLIER(), cachedSupplyRate: 0 }); borrowable.cachedSupplyRate = supplyRate(borrowable); return borrowable; } function totalSupply(Borrowable memory borrowable) internal pure returns (uint) { return borrowable.externalSupply.add(borrowable.ownedSupply); } function utilizationRate(Borrowable memory borrowable) internal pure returns (uint) { uint _totalSupply = totalSupply(borrowable); if (_totalSupply == 0) return 0; return borrowable.totalBorrows.mul(1e18).div(_totalSupply); } function kinkRate(Borrowable memory borrowable) internal pure returns (uint) { return borrowable.kinkUtilizationRate .mul(borrowable.kinkBorrowRate).div(1e18) .mul(uint(1e18).sub(borrowable.reserveFactor)).div(1e18); } function supplyRate(Borrowable memory borrowable) internal pure returns (uint rate) { uint utilizationRate_ = utilizationRate(borrowable); uint ratio = utilizationRate_.mul(1e18).div(borrowable.kinkUtilizationRate); uint borrowFactor; //borrowRate to kinkBorrowRate ratio if (utilizationRate_ < borrowable.kinkUtilizationRate) { borrowFactor = ratio; } else { uint excessRatio = utilizationRate_.sub(borrowable.kinkUtilizationRate) .mul(1e18).div(uint(1e18).sub(borrowable.kinkUtilizationRate)); borrowFactor = excessRatio.mul(borrowable.kinkMultiplier.sub(1)).add(1e18); } rate = borrowFactor.mul(kinkRate(borrowable)).div(1e18).mul(ratio).div(1e18); } function allocate(Borrowable memory borrowable, uint amount) internal pure returns (Borrowable memory) { borrowable.ownedSupply = borrowable.ownedSupply.add(amount); borrowable.cachedSupplyRate = supplyRate(borrowable); return borrowable; } function deallocate(Borrowable memory borrowable, uint amount) internal pure returns (Borrowable memory) { uint availableLiquidity = totalSupply(borrowable).sub(borrowable.totalBorrows, "ERROR: NEGATIVE AVAILABLE LIQUIDITY"); require(amount <= availableLiquidity, "ERROR: DEALLOCATE AMOUNT > AVAILABLE LIQUIDITY"); borrowable.ownedSupply = borrowable.ownedSupply.sub(amount); borrowable.cachedSupplyRate = supplyRate(borrowable); return borrowable; } function deallocateMax(Borrowable memory borrowable) internal pure returns (Borrowable memory, uint) { if (totalSupply(borrowable) < borrowable.totalBorrows) return (borrowable, 0); uint availableLiquidity = totalSupply(borrowable).sub(borrowable.totalBorrows); uint amount = Math.min(borrowable.ownedSupply, availableLiquidity); return (deallocate(borrowable, amount), amount); } function calculateUtilizationForRate(Borrowable memory borrowable, uint rate) internal pure returns (uint targetUtilizationRate) { if (rate <= kinkRate(borrowable)) { targetUtilizationRate = Math.sqrt( rate.mul(1e18).div(kinkRate(borrowable)).mul(1e18) ).mul(borrowable.kinkUtilizationRate).div(1e18); } else { uint a = borrowable.kinkMultiplier.sub(1); uint b = borrowable.kinkUtilizationRate.mul(borrowable.kinkMultiplier).sub(1e18); uint c = rate.mul(borrowable.kinkUtilizationRate).div(1e18) .mul(uint(1e18).sub(borrowable.kinkUtilizationRate)).div(kinkRate(borrowable)); uint tmp = Math.sqrt( b.mul(b).div(1e18).add(a.mul(c).mul(4)).mul(1e18) ); targetUtilizationRate = tmp.add(b).div(a).div(2); } require(targetUtilizationRate <= 1e18, "ERROR: TARGET UTILIZATION > 100%"); } function calculateAmountForRate(Borrowable memory borrowable, uint rate) internal pure returns (uint) { require(rate > 0, "ERROR: rate = 0"); require(rate <= borrowable.cachedSupplyRate, "ERROR: TARGET RATE > CACHED RATE"); uint targetUtilizationRate = calculateUtilizationForRate(borrowable, rate); require(targetUtilizationRate <= utilizationRate(borrowable), "ERROR: TARGET UTILIZATION > CURRENT UTILIZATION"); uint targetSupply = borrowable.totalBorrows.mul(1e18).div(targetUtilizationRate); return targetSupply.sub(totalSupply(borrowable), "ERROR: TARGET SUPPLY > TOTAL SUPPLY"); } function compare(Borrowable memory borrowableA, Borrowable memory borrowableB) internal pure returns (bool) { return borrowableA.cachedSupplyRate > borrowableB.cachedSupplyRate; } }
pragma solidity =0.5.16; // a library for performing various math operations // forked from: https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/libraries/Math.sol library Math { function min(uint x, uint y) internal pure returns (uint z) { z = x < y ? x : y; } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint y) internal pure returns (uint z) { if (y > 3) { z = y; uint x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }
pragma solidity =0.5.16; // From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol // Subject to the MIT license. /** * @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, 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 addition of two unsigned integers, reverting with custom message on overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, errorMessage); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot underflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction underflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot underflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @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) { // 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 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @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, string memory errorMessage) internal pure returns (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 0; } uint256 c = a * b; require(c / a == b, errorMessage); return c; } /** * @dev Returns the integer division of two unsigned integers. * Reverts 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) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts 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) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
pragma solidity =0.5.16; interface ERC20Interface { function balanceOf(address user) external view returns (uint256); } library SafeToken { function myBalance(address token) internal view returns (uint256) { return ERC20Interface(token).balanceOf(address(this)); } function balanceOf(address token, address user) internal view returns (uint256) { return ERC20Interface(token).balanceOf(user); } function safeApprove(address token, address to, uint256 value) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "!safeApprove"); } function safeTransfer(address token, address to, uint256 value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "!safeTransfer"); } function safeTransferFrom(address token, address from, address to, uint256 value) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "!safeTransferFrom"); } function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call.value(value)(new bytes(0)); require(success, "!safeTransferETH"); } }
pragma solidity =0.5.16; import "./PoolToken.sol"; import "./LVStorageV1.sol"; import "./interfaces/ILendingVaultV1.sol"; import "./libraries/BorrowableHelpers.sol"; import "./libraries/BorrowableObject.sol"; contract LVAllocatorV1 is ILendingVaultV1, PoolToken, LVStorageV1 { using BorrowableHelpers for address; using BorrowableObject for BorrowableObject.Borrowable; function _allocate(IBorrowable borrowable, uint mintAmount, uint _exchangeRate) internal returns (uint mintTokens) { mintTokens = mintAmount.mul(1e18).div(_exchangeRate); if (mintTokens == 0) return 0; underlying.safeTransfer(address(borrowable), mintAmount); mintTokens = borrowable.mint(address(this)); emit AllocateIntoBorrowable(address(borrowable), mintAmount, mintTokens); } function _allocate(IBorrowable borrowable, uint mintAmount) internal returns (uint mintTokens) { mintTokens = _allocate(borrowable, mintAmount, borrowable.exchangeRate()); } function _deallocate(IBorrowable borrowable, uint redeemTokens, uint _exchangeRate) internal returns (uint redeemAmount) { redeemAmount = redeemTokens.mul(_exchangeRate).div(1e18); if (redeemAmount == 0) return 0; uint totalBalance = borrowable.totalBalance(); if (redeemAmount > totalBalance) { redeemTokens = totalBalance.mul(1e18).div(_exchangeRate); } address(borrowable).safeTransfer(address(borrowable), redeemTokens); redeemAmount = borrowable.redeem(address(this)); emit DeallocateFromBorrowable(address(borrowable), redeemAmount, redeemTokens); } function _deallocate(IBorrowable borrowable, uint redeemTokens) internal returns (uint redeemAmount) { redeemAmount = _deallocate(borrowable, redeemTokens, borrowable.exchangeRate()); } function _deallocateAtLeastOrMax(IBorrowable borrowable, uint redeemAmount, uint _exchangeRate) internal returns (uint actualRedeemAmount) { actualRedeemAmount = _deallocate(IBorrowable(borrowable), BorrowableHelpers.tokensForAtLeast(redeemAmount, _exchangeRate), _exchangeRate); } function _deallocateAtLeastOrMax(IBorrowable borrowable, uint redeemAmount) internal returns (uint actualRedeemAmount) { actualRedeemAmount = _deallocateAtLeastOrMax(borrowable, redeemAmount, borrowable.exchangeRate()); } function _withdrawAndReallocate(uint withdrawAmount) internal { // initialize borrowablesObj BorrowableObject.Borrowable[] memory borrowablesObj = new BorrowableObject.Borrowable[](borrowables.length); uint borrowablesLength = borrowables.length; for(uint i = 0; i < borrowables.length; i++) { if (!borrowableInfo[borrowables[i]].enabled) { borrowablesLength--; continue; } uint delta = uint(borrowables.length).sub(borrowablesLength); borrowablesObj[i - delta] = BorrowableObject.newBorrowable(IBorrowable(borrowables[i]), address(this)); } // deallocate everything uint amountToAllocate = underlying.myBalance(); for(uint i = 0; i < borrowablesLength; i++) { uint amount; (borrowablesObj[i], amount) = borrowablesObj[i].deallocateMax(); amountToAllocate = amountToAllocate.add(amount); } amountToAllocate = amountToAllocate.sub(withdrawAmount, "LendingVaultV1: INSUFFICIENT_LIQUIDITY"); // bubblesort borrowablesObj for (uint i = 0; i < borrowablesLength - 1; i++) { for (uint j = 0; j < borrowablesLength - 1 - i; j++) { if (!borrowablesObj[j].compare(borrowablesObj[j+1])) { BorrowableObject.Borrowable memory tmp = borrowablesObj[j]; borrowablesObj[j] = borrowablesObj[j+1]; borrowablesObj[j+1] = tmp; } } } // Allocate in the pool with the highest APR an amount such that the next APR matches the one // of the pool with the second highest APR. // Repeat until all the pools with the highest APR have the same APR. uint lastCycle = borrowablesLength; for(uint i = 1; i < borrowablesLength; i++) { uint targetRate = borrowablesObj[i].cachedSupplyRate; uint amountThisCycle = 0; uint[] memory amounts = new uint[](i); if (targetRate == 0) { // Unachievable APR lastCycle = i; break; } for (uint j = 0; j < i; j++) { if (borrowablesObj[j].cachedSupplyRate <= targetRate) break; amounts[j] = borrowablesObj[j].calculateAmountForRate(targetRate); amountThisCycle = amountThisCycle.add(amounts[j]); } if (amountThisCycle > amountToAllocate) { // We can't afford to complete this cycle lastCycle = i; break; } for (uint j = 0; j < i; j++) { if (amounts[j] == 0) continue; borrowablesObj[j] = borrowablesObj[j].allocate(amounts[j]); amountToAllocate = amountToAllocate.sub(amounts[j]); } } // distribute the amount left equally among pools with highest APR proportionally to their total supply uint globalTotalSupply = 0; uint totalAmountToAllocate = amountToAllocate; for (uint i = 0; i < lastCycle; i++) { globalTotalSupply = globalTotalSupply.add(borrowablesObj[i].totalSupply()); } for (uint i = 0; i < lastCycle; i++) { uint amount = globalTotalSupply > 0 ? borrowablesObj[i].totalSupply().mul(totalAmountToAllocate).div(globalTotalSupply) : amountToAllocate; if (amount > amountToAllocate) amount = amountToAllocate; borrowablesObj[i] = borrowablesObj[i].allocate(amount); amountToAllocate = amountToAllocate.sub(amount); } // redeem for(uint i = 0; i < borrowablesLength; i++) { if (borrowablesObj[i].ownedSupply < borrowablesObj[i].initialOwnedSupply) { uint redeemAmount = borrowablesObj[i].initialOwnedSupply.sub(borrowablesObj[i].ownedSupply); _deallocateAtLeastOrMax(borrowablesObj[i].borrowableContract, redeemAmount, borrowablesObj[i].exchangeRate); } } // mint amountToAllocate = underlying.myBalance().sub(withdrawAmount, "LendingVaultV1: NEGATIVE AMOUNT TO ALLOCATE"); for(uint i = 0; i < borrowablesLength; i++) { if (borrowablesObj[i].ownedSupply > borrowablesObj[i].initialOwnedSupply) { uint mintAmount = borrowablesObj[i].ownedSupply.sub(borrowablesObj[i].initialOwnedSupply); if (mintAmount > amountToAllocate) mintAmount = amountToAllocate; amountToAllocate = amountToAllocate.sub(mintAmount); _allocate(borrowablesObj[i].borrowableContract, mintAmount, borrowablesObj[i].exchangeRate); } } } }
pragma solidity =0.5.16; import "./LVAllocatorV1.sol"; import "./interfaces/ILendingVaultV1Factory.sol"; contract LVSetterV1 is LVAllocatorV1 { uint public constant RESERVE_FACTOR_MAX = 0.90e18; //90% uint private constant MAX_BORROWABLES_LENGTH = 10; function _initialize( address _underlying, string calldata _name, string calldata _symbol ) external { require(msg.sender == factory, "LendingVaultV1: UNAUTHORIZED"); // sufficient check _setName(_name, _symbol); underlying = _underlying; exchangeRateLast = initialExchangeRate; } function _setReserveFactor(uint newReserveFactor) external onlyAdmin nonReentrant { require(newReserveFactor <= RESERVE_FACTOR_MAX, "LendingVaultV1: INVALID_SETTING"); reserveFactor = newReserveFactor; emit NewReserveFactor(newReserveFactor); } /*** Borrowables management ***/ function addBorrowable(address borrowable) external onlyAdmin nonReentrant { require(IBorrowable(borrowable).underlying() == underlying, "LendingVaultV1: INVALID_UNDERLYING"); require(!borrowableInfo[borrowable].exists, "LendingVaultV1: BORROWABLE_EXISTS"); require(borrowables.length < MAX_BORROWABLES_LENGTH, "LendingVaultV1: MAX_BORROWABLES_LENGTH"); borrowableInfo[borrowable].exists = true; borrowableInfo[borrowable].enabled = true; borrowables.push(borrowable); emit AddBorrowable(address(borrowable)); } function removeBorrowable(address borrowable) external onlyAdmin nonReentrant { require(borrowableInfo[borrowable].exists, "LendingVaultV1: BORROWABLE_DOESNT_EXISTS"); require(!borrowableInfo[borrowable].enabled, "LendingVaultV1: BORROWABLE_ENABLED"); require(borrowable.balanceOf(address(this)) == 0, "LendingVaultV1: NOT_EMPTY"); uint lastIndex = borrowables.length - 1; uint index = indexOfBorrowable(borrowable); borrowables[index] = borrowables[lastIndex]; borrowables.pop(); delete borrowableInfo[borrowable]; emit RemoveBorrowable(address(borrowable)); } function disableBorrowable(address borrowable) external onlyAdmin nonReentrant { require(borrowableInfo[borrowable].exists, "LendingVaultV1: BORROWABLE_DOESNT_EXISTS"); require(borrowableInfo[borrowable].enabled, "LendingVaultV1: BORROWABLE_DISABLED"); borrowableInfo[borrowable].enabled = false; emit DisableBorrowable(address(borrowable)); } function enableBorrowable(address borrowable) external onlyAdmin nonReentrant { require(borrowableInfo[borrowable].exists, "LendingVaultV1: BORROWABLE_DOESNT_EXISTS"); require(!borrowableInfo[borrowable].enabled, "LendingVaultV1: BORROWABLE_ENABLED"); borrowableInfo[borrowable].enabled = true; emit EnableBorrowable(address(borrowable)); } function unwindBorrowable(address borrowable) external onlyAdmin nonReentrant update { require(borrowableInfo[borrowable].exists, "LendingVaultV1: BORROWABLE_DOESNT_EXISTS"); require(!borrowableInfo[borrowable].enabled, "LendingVaultV1: BORROWABLE_ENABLED"); uint underlyingBalance = borrowable.myUnderlyingBalance(); require(underlyingBalance > 0, "LendingVaultV1: ZERO_AMOUNT"); uint actualRedeemAmount = _deallocateAtLeastOrMax(IBorrowable(borrowable), underlyingBalance); emit UnwindBorrowable(address(borrowable), underlyingBalance, actualRedeemAmount); } modifier onlyAdmin() { require(msg.sender == ILendingVaultV1Factory(factory).admin(), "LendingVaultV1: UNAUTHORIZED"); _; } }
pragma solidity =0.5.16; contract LVStorageV1 { address[] public borrowables; struct BorrowableInfo { bool enabled; bool exists; } mapping(address => BorrowableInfo) public borrowableInfo; function getBorrowablesLength() external view returns (uint) { return borrowables.length; } function indexOfBorrowable(address borrowable) public view returns (uint) { for (uint i = 0; i < borrowables.length; i++) { if (borrowables[i] == borrowable) { return i; } } require(false, "LendingVaultV1: BORROWABLE_NOT_FOUND"); } uint public exchangeRateLast; uint public reserveFactor = 0.10e18; //10% }
pragma solidity =0.5.16; import "./ImpermaxERC20.sol"; import "./interfaces/IPoolToken.sol"; import "./libraries/SafeToken.sol"; contract PoolToken is IPoolToken, ImpermaxERC20 { using SafeToken for address; uint internal constant initialExchangeRate = 1e18; address public underlying; address public factory; uint public totalBalance; uint public constant MINIMUM_LIQUIDITY = 1000; event Mint(address indexed sender, address indexed minter, uint mintAmount, uint mintTokens); event Redeem(address indexed sender, address indexed redeemer, uint redeemAmount, uint redeemTokens); event Sync(uint totalBalance); /*** Initialize ***/ // called once by the factory function _setFactory() external { require(factory == address(0), "Impermax: FACTORY_ALREADY_SET"); factory = msg.sender; } /*** PoolToken ***/ function _update() internal { totalBalance = underlying.myBalance(); emit Sync(totalBalance); } function exchangeRate() public returns (uint) { uint _totalSupply = totalSupply; // gas savings uint _totalBalance = totalBalance; // gas savings if (_totalSupply == 0 || _totalBalance == 0) return initialExchangeRate; return _totalBalance.mul(1e18).div(_totalSupply); } // this low-level function should be called from another contract function mint(address minter) external nonReentrant update returns (uint mintTokens) { uint balance = underlying.myBalance(); uint mintAmount = balance.sub(totalBalance); mintTokens = mintAmount.mul(1e18).div(exchangeRate()); if(totalSupply == 0) { // permanently lock the first MINIMUM_LIQUIDITY tokens mintTokens = mintTokens.sub(MINIMUM_LIQUIDITY); _mint(address(0), MINIMUM_LIQUIDITY); } require(mintTokens > 0, "Impermax: MINT_AMOUNT_ZERO"); _mint(minter, mintTokens); emit Mint(msg.sender, minter, mintAmount, mintTokens); } // this low-level function should be called from another contract function redeem(address redeemer) external nonReentrant update returns (uint redeemAmount) { uint redeemTokens = balanceOf[address(this)]; redeemAmount = redeemTokens.mul(exchangeRate()).div(1e18); require(redeemAmount > 0, "Impermax: REDEEM_AMOUNT_ZERO"); require(redeemAmount <= totalBalance, "Impermax: INSUFFICIENT_CASH"); _burn(address(this), redeemTokens); underlying.safeTransfer(redeemer, redeemAmount); emit Redeem(msg.sender, redeemer, redeemAmount, redeemTokens); } // force real balance to match totalBalance function skim(address to) external nonReentrant { underlying.safeTransfer(to, underlying.myBalance().sub(totalBalance)); } // force totalBalance to match real balance function sync() external nonReentrant update {} /*** Utilities ***/ // prevents a contract from calling itself, directly or indirectly. bool internal _notEntered = true; modifier nonReentrant() { require(_notEntered, "Impermax: REENTERED"); _notEntered = false; _; _notEntered = true; } // update totalBalance with current balance modifier update() { _; _update(); } }
{ "optimizer": { "enabled": true, "runs": 999999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrowable","type":"address"}],"name":"AddBorrowable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrowable","type":"address"},{"indexed":false,"internalType":"uint256","name":"mintAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintTokens","type":"uint256"}],"name":"AllocateIntoBorrowable","type":"event"},{"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":"borrowable","type":"address"},{"indexed":false,"internalType":"uint256","name":"redeemAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeemTokens","type":"uint256"}],"name":"DeallocateFromBorrowable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrowable","type":"address"}],"name":"DisableBorrowable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrowable","type":"address"}],"name":"EnableBorrowable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"mintAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintTokens","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newReserveFactor","type":"uint256"}],"name":"NewReserveFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"redeemer","type":"address"},{"indexed":false,"internalType":"uint256","name":"redeemAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeemTokens","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrowable","type":"address"}],"name":"RemoveBorrowable","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalBalance","type":"uint256"}],"name":"Sync","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":"borrowable","type":"address"},{"indexed":false,"internalType":"uint256","name":"underlyingBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"actualRedeemAmount","type":"uint256"}],"name":"UnwindBorrowable","type":"event"},{"constant":true,"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MINIMUM_LIQUIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"RESERVE_FACTOR_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_underlying","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"_initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"_setFactory","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newReserveFactor","type":"uint256"}],"name":"_setReserveFactor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"borrowable","type":"address"}],"name":"addBorrowable","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"borrowableInfo","outputs":[{"internalType":"bool","name":"enabled","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"borrowables","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"borrowable","type":"address"}],"name":"disableBorrowable","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"borrowable","type":"address"}],"name":"enableBorrowable","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"exchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"exchangeRateLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBorrowablesLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"borrowable","type":"address"}],"name":"indexOfBorrowable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"mintTokens","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"reallocate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"redeemer","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"redeemAmount","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"borrowable","type":"address"}],"name":"removeBorrowable","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"reserveFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"skim","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"sync","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"underlying","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"borrowable","type":"address"}],"name":"unwindBorrowable","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526002805460ff19908116601217909155600b8054909116600117905567016345785d8a0000600f5561592f8061003b6000396000f3fe608060405234801561001057600080fd5b50600436106102925760003560e01c80637ecebe0011610160578063bc25cf77116100d8578063d505accf1161008c578063eb1ea9f411610071578063eb1ea9f414610891578063fca7820b146108c4578063fff6cae9146108e157610292565b8063d505accf146107f8578063dd62ed3e1461085657610292565b8063c45a0155116100bd578063c45a0155146107b5578063c5b7e148146107bd578063c72f3fbb146107f057610292565b8063bc25cf771461077a578063be340e32146107ad57610292565b806398084db71161012f578063ad7a672f11610114578063ad7a672f1461074d578063ade37c1314610755578063ba9a7a561461077257610292565b806398084db71461070c578063a9059cbb1461071457610292565b80637ecebe0014610696578063821beaf5146106c957806395a2251f146106d157806395d89b411461070457610292565b80633ba0b9a91161020e57806352ac4b02116101c25780636a627842116101a75780636a627842146105ff5780636f307dc31461063257806370a082311461066357610292565b806352ac4b021461057e578063579ce367146105b157610292565b80634643ec58116101f35780634643ec58146104645780634a5d316c14610543578063506fb0861461054b57610292565b80633ba0b9a9146104545780634322b7141461045c57610292565b806323b872dd11610265578063313ce5671161024a578063313ce567146103fb57806332fe35fd146104195780633644e5151461044c57610292565b806323b872dd146103b057806330adf81f146103f357610292565b806306fdde0314610297578063095ea7b31461031457806318160ddd14610361578063218b5b811461037b575b600080fd5b61029f6108e9565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102d95781810151838201526020016102c1565b50505050905090810190601f1680156103065780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61034d6004803603604081101561032a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610995565b604080519115158252519081900360200190f35b6103696109ac565b60408051918252519081900360200190f35b6103ae6004803603602081101561039157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166109b2565b005b61034d600480360360608110156103c657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610e68565b610369610f7d565b610403610fa1565b6040805160ff9092168252519081900360200190f35b6103ae6004803603602081101561042f57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610faa565b6103696112fe565b610369611304565b610369611388565b6103ae6004803603606081101561047a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156104b257600080fd5b8201836020820111156104c457600080fd5b803590602001918460018302840111640100000000831117156104e657600080fd5b91939092909160208101903564010000000081111561050457600080fd5b82018360208201111561051657600080fd5b8035906020019184600183028401116401000000008311171561053857600080fd5b50909250905061138e565b6103ae6114df565b6103696004803603602081101561056157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611590565b6103ae6004803603602081101561059457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611650565b6105e4600480360360208110156105c757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166119a0565b60408051921515835290151560208301528051918290030190f35b6103696004803603602081101561061557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166119be565b61063a611bfd565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103696004803603602081101561067957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611c19565b610369600480360360208110156106ac57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611c2b565b610369611c3d565b610369600480360360208110156106e757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611c43565b61029f611e09565b6103ae611e81565b61034d6004803603604081101561072a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611f59565b610369611f66565b61063a6004803603602081101561076b57600080fd5b5035611f6c565b610369611fa0565b6103ae6004803603602081101561079057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611fa6565b6103696120cf565b61063a6120d5565b6103ae600480360360208110156107d357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166120f1565b6103696124a3565b6103ae600480360360e081101561080e57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c001356124af565b6103696004803603604081101561086c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166124f3565b6103ae600480360360208110156108a757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612510565b6103ae600480360360208110156108da57600080fd5b5035612a15565b6103ae612ca2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561098d5780601f106109625761010080835404028352916020019161098d565b820191906000526020600020905b81548152906001019060200180831161097057829003601f168201915b505050505081565b60006109a2338484612d43565b5060015b92915050565b60035481565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1a57600080fd5b505afa158015610a2e573d6000803e3d6000fd5b505050506040513d6020811015610a4457600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314610ac957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff16610b3a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600854604080517f6f307dc3000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff92831692841691636f307dc3916004808301926020929190829003018186803b158015610bcf57600080fd5b505afa158015610be3573d6000803e3d6000fd5b505050506040513d6020811015610bf957600080fd5b505173ffffffffffffffffffffffffffffffffffffffff1614610c67576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806158186022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff1615610ceb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806156c96021913960400191505060405180910390fd5b600c54600a11610d46576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806158d56026913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff90911661010017166001908117909155600c8054918201815583527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055517f3b94e6c56297c3ab2913d31d1c1adf8279146dbfb5624cc473e7af7a22d9c8469190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b73ffffffffffffffffffffffffffffffffffffffff831660009081526005602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14610f6757604080518082018252601e81527f496d7065726d61783a205452414e534645525f4e4f545f414c4c4f574544000060208083019190915273ffffffffffffffffffffffffffffffffffffffff87166000908152600582528381203382529091529190912054610f3591849063ffffffff612db216565b73ffffffffffffffffffffffffffffffffffffffff851660009081526005602090815260408083203384529091529020555b610f72848484612e63565b5060015b9392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025460ff1681565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561101257600080fd5b505afa158015611026573d6000803e3d6000fd5b505050506040513d602081101561103c57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff1633146110c157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661113257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff166111dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061583a6028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff161561125c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806156a76022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f54ba33e4b0861b4d81b3384c3b5130b25b55df191223d9e48b317dc289fac3a99190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60065481565b60035460009081611325611316612f7c565b600a549063ffffffff612fe516565b9050811580611332575080155b1561134957670de0b6b3a764000092505050611385565b60006113738361136784670de0b6b3a764000063ffffffff61305916565b9063ffffffff6130cc16565b905061137f818461310e565b93505050505b90565b600f5481565b60095473ffffffffffffffffffffffffffffffffffffffff16331461141457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b61148784848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152925086915085908190840183828082843760009201919091525061324092505050565b5050600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94909416939093179092555050670de0b6b3a7640000600e55565b60095473ffffffffffffffffffffffffffffffffffffffff161561156457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496d7065726d61783a20464143544f52595f414c52454144595f534554000000604482015290519081900360640190fd5b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055565b6000805b600c548110156115f9578273ffffffffffffffffffffffffffffffffffffffff16600c82815481106115c257fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156115f157905061164b565b600101611594565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018061570d6024913960400191505060405180910390fd5b919050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b1580156116b857600080fd5b505afa1580156116cc573d6000803e3d6000fd5b505050506040513d60208110156116e257600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16331461176757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff166117d857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff16611883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061583a6028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff16611901576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806157316023913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f6149acc591caf5f3d506cb615abb39ea3847de4e2aa83f4382531de216bdc6809190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600d6020526000908152604090205460ff8082169161010090041682565b600b5460009060ff16611a3257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600854600090611a7f9073ffffffffffffffffffffffffffffffffffffffff16613324565b90506000611a98600a54836133c690919063ffffffff16565b9050611abd611aa5611304565b61136783670de0b6b3a764000063ffffffff61305916565b925060035460001415611aeb57611adc836103e863ffffffff6133c616565b9250611aeb60006103e8613408565b60008311611b5a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656e64696e675661756c7456313a204d494e545f414d4f554e545f5a45524f604482015290519081900360640190fd5b611b648484613408565b611b6e60006134b9565b6040805182815260208101859052815173ffffffffffffffffffffffffffffffffffffffff87169233927f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee929081900390910190a35050611bcd613c21565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055919050565b60085473ffffffffffffffffffffffffffffffffffffffff1681565b60046020526000908152604090205481565b60076020526000908152604090205481565b600c5490565b600b5460009060ff16611cb757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905530600090815260046020526040902054611d13670de0b6b3a7640000611367611d06611304565b849063ffffffff61305916565b915060008211611d6e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806158b36022913960400191505060405180910390fd5b611d783082613c7c565b611d81826134b9565b600854611dab9073ffffffffffffffffffffffffffffffffffffffff16848463ffffffff613d4016565b6040805183815260208101839052815173ffffffffffffffffffffffffffffffffffffffff86169233927f3f693fff038bb8a046aa76d9516190ac7444f7d69cf952c4cbdc086fdef2d6fc929081900390910190a350611bcd613c21565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561098d5780601f106109625761010080835404028352916020019161098d565b600b5460ff16611ef257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611f2460006134b9565b611f2c613c21565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60006109a2338484612e63565b600a5481565b600c8181548110611f7957fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6103e881565b600b5460ff1661201757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600a546008546120a191839161207b919061206f9073ffffffffffffffffffffffffffffffffffffffff16613324565b9063ffffffff6133c616565b60085473ffffffffffffffffffffffffffffffffffffffff16919063ffffffff613d4016565b50600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600e5481565b60095473ffffffffffffffffffffffffffffffffffffffff1681565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561215957600080fd5b505afa15801561216d573d6000803e3d6000fd5b505050506040513d602081101561218357600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16331461220857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661227957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff16612324576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061583a6028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff16156123a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806156a76022913960400191505060405180910390fd5b60006123c48273ffffffffffffffffffffffffffffffffffffffff16613f1d565b90506000811161243557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c656e64696e675661756c7456313a205a45524f5f414d4f554e540000000000604482015290519081900360640190fd5b60006124418383613fd1565b90508273ffffffffffffffffffffffffffffffffffffffff167f05750bc9042b6da04fdebec7b024caed5c2e2b35c707bd1fde571f31cdaeb5668383604051808381526020018281526020019250505060405180910390a250506120a1613c21565b670c7d713b49da000081565b6124df878787878787877f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9614051565b6124ea878787612d43565b50505050505050565b600560209081526000928352604080842090915290825290205481565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561257857600080fd5b505afa15801561258c573d6000803e3d6000fd5b505050506040513d60208110156125a257600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16331461262757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661269857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff16612743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061583a6028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff16156127c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806156a76022913960400191505060405180910390fd5b6127e873ffffffffffffffffffffffffffffffffffffffff82163063ffffffff6142f416565b1561285457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4c656e64696e675661756c7456313a204e4f545f454d50545900000000000000604482015290519081900360640190fd5b600c547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600061288483611590565b9050600c828154811061289357fe5b600091825260209091200154600c805473ffffffffffffffffffffffffffffffffffffffff90921691839081106128c657fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600c80548061291957fe5b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff8516808352600d909152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690555190917f1f537c1571c0e7fa29083762436cadb3e57564c0f78e857e498cf428124c710e91a25050600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015612a7d57600080fd5b505afa158015612a91573d6000803e3d6000fd5b505050506040513d6020811015612aa757600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314612b2c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff16612b9d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055670c7d713b49da0000811115612c3c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4c656e64696e675661756c7456313a20494e56414c49445f53455454494e4700604482015290519081900360640190fd5b600f8190556040805182815290517f9d9cd27245b4e6b06dcf523ac57b6e851b934e199eee376313f906e94bfbfd559181900360200190a150600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600b5460ff16612d1357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611f2c613c21565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260056020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b60008184841115612e5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612e20578181015183820152602001612e08565b50505050905090810190601f168015612e4d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b604080518082018252601b81527f496d7065726d61783a205452414e534645525f544f4f5f48494748000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff8616600090815260049091529190912054612ed191839063ffffffff612db216565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600460205260408082209390935590841681522054612f13908263ffffffff612fe516565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526004602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000805b600c54811015612fe1576000600c8281548110612f9957fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169050612fd6612fc982613f1d565b849063ffffffff612fe516565b925050600101612f80565b5090565b600082820183811015610f7657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082613068575060006109a6565b8282028284828161307557fe5b0414610f76576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806157d16021913960400191505060405180910390fd5b6000610f7683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506143a6565b600e546000908084111561323757600061315f613152670de0b6b3a7640000611367600f54613146878b6133c690919063ffffffff16565b9063ffffffff61305916565b869063ffffffff6133c616565b9050600061317b8561206f84611367838b63ffffffff61305916565b9050801561322857600954604080517f345ef941000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163345ef941916004808301926020929190829003018186803b1580156131ee57600080fd5b505afa158015613202573d6000803e3d6000fd5b505050506040513d602081101561321857600080fd5b505190506132268183613408565b505b50600e81905591506109a69050565b839150506109a6565b8151613253906000906020850190615573565b508051613267906001906020840190615573565b50604051469080605261577f82396040805191829003605201822086516020978801208383018352600184527f310000000000000000000000000000000000000000000000000000000000000093880193909352815180880191909152808201929092527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606083015260808201939093523060a0808301919091528351808303909101815260c090910190925250805192019190912060065550565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905160009173ffffffffffffffffffffffffffffffffffffffff8416916370a0823191602480820192602092909190829003018186803b15801561339457600080fd5b505afa1580156133a8573d6000803e3d6000fd5b505050506040513d60208110156133be57600080fd5b505192915050565b6000610f7683836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f7700815250612db2565b60035461341b908263ffffffff612fe516565b60035573ffffffffffffffffffffffffffffffffffffffff8216600090815260046020526040902054613454908263ffffffff612fe516565b73ffffffffffffffffffffffffffffffffffffffff831660008181526004602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600c5460408051828152602080840282010190915260609180156134f757816020015b6134e46155ed565b8152602001906001900390816134dc5790505b50600c5490915060005b600c548110156135f257600d6000600c838154811061351c57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1661357f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101906135ea565b600c54600090613595908463ffffffff6133c616565b90506135cf600c83815481106135a757fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1630614425565b84828403815181106135dd57fe5b6020026020010181905250505b600101613501565b506008546000906136189073ffffffffffffffffffffffffffffffffffffffff16613324565b905060005b8281101561367c57600061364385838151811061363657fe5b60200260200101516149b4565b865187908590811061365157fe5b60209081029190910101919091529050613671838263ffffffff612fe516565b92505060010161361d565b506136a8846040518060600160405280602681526020016157f26026913983919063ffffffff612db216565b905060005b600183038110156137825760005b816001850303811015613779576137048582600101815181106136da57fe5b60200260200101518683815181106136ee57fe5b6020026020010151614a1990919063ffffffff16565b613771576137106155ed565b85828151811061371c57fe5b6020026020010151905085826001018151811061373557fe5b602002602001015186838151811061374957fe5b60200260200101819052508086836001018151811061376457fe5b6020026020010181905250505b6001016136bb565b506001016136ad565b508160015b8381101561395e57600085828151811061379d57fe5b60200260200101516101400151905060008090506060836040519080825280602002602001820160405280156137dd578160200160208202803883390190505b509050826137f05783945050505061395e565b60005b8481101561388d578389828151811061380857fe5b602002602001015161014001511161381f5761388d565b613845848a838151811061382f57fe5b6020026020010151614a2790919063ffffffff16565b82828151811061385157fe5b60200260200101818152505061388382828151811061386c57fe5b602002602001015184612fe590919063ffffffff16565b92506001016137f3565b50858211156138a15783945050505061395e565b60005b8481101561394e578181815181106138b857fe5b6020026020010151600014156138cd57613946565b6139068282815181106138dc57fe5b60200260200101518a83815181106138f057fe5b6020026020010151614bdd90919063ffffffff16565b89828151811061391257fe5b602002602001018190525061394382828151811061392c57fe5b6020026020010151886133c690919063ffffffff16565b96505b6001016138a4565b5050600190920191506137879050565b50600082815b838110156139955761398b612fc988838151811061397e57fe5b6020026020010151614c15565b9250600101613964565b5060005b83811015613a165760008084116139b057856139c7565b6139c784611367856131468c878151811061397e57fe5b9050858111156139d45750845b6139e4818984815181106138f057fe5b8883815181106139f057fe5b6020908102919091010152613a0b868263ffffffff6133c616565b955050600101613999565b5060005b85811015613ae157868181518110613a2e57fe5b602002602001015160800151878281518110613a4657fe5b602002602001015160a001511015613ad9576000613a9b888381518110613a6957fe5b602002602001015160a00151898481518110613a8157fe5b6020026020010151608001516133c690919063ffffffff16565b9050613ad6888381518110613aac57fe5b602002602001015160000151828a8581518110613ac557fe5b602002602001015160200151614c32565b50505b600101613a1a565b50613b2e876040518060600160405280602b8152602001615754602b9139600854613b219073ffffffffffffffffffffffffffffffffffffffff16613324565b919063ffffffff612db216565b935060005b85811015613c1757868181518110613b4757fe5b602002602001015160800151878281518110613b5f57fe5b602002602001015160a001511115613c0f576000613bb4888381518110613b8257fe5b602002602001015160800151898481518110613b9a57fe5b602002602001015160a001516133c690919063ffffffff16565b905085811115613bc15750845b613bd1868263ffffffff6133c616565b9550613c0c888381518110613be257fe5b602002602001015160000151828a8581518110613bfb57fe5b602002602001015160200151614c50565b50505b600101613b33565b5050505050505050565b600854613c439073ffffffffffffffffffffffffffffffffffffffff16613324565b600a81905560408051918252517f8a0df8ef054fae2c3d2d19a7b322e864870cc9fd3cb07fb9526309c596244bf49181900360200190a1565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020526040902054613cb2908263ffffffff6133c616565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260046020526040902055600354613ceb908263ffffffff6133c616565b60035560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000178152925182516000946060949389169392918291908083835b60208310613e1657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613dd9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613e78576040519150601f19603f3d011682016040523d82523d6000602084013e613e7d565b606091505b5091509150818015613eab575080511580613eab5750808060200190516020811015613ea857600080fd5b50515b613f1657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f21736166655472616e7366657200000000000000000000000000000000000000604482015290519081900360640190fd5b5050505050565b60006109a6828373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015613fa057600080fd5b505afa158015613fb4573d6000803e3d6000fd5b505050506040513d6020811015613fca57600080fd5b5051614d9e565b6000610f7683838573ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561402057600080fd5b505af1158015614034573d6000803e3d6000fd5b505050506040513d602081101561404a57600080fd5b5051614c32565b428510156140c057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496d7065726d61783a2045585049524544000000000000000000000000000000604482015290519081900360640190fd5b60065473ffffffffffffffffffffffffffffffffffffffff808a1660008181526007602090815260408083208054600180820190925582518085018a905280840196909652958e166060860152608085018d905260a085019590955260c08085018c90528151808603909101815260e0850182528051908301207f19010000000000000000000000000000000000000000000000000000000000006101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff8a166101828501526101a284018990526101c28401889052519193926101e2808201937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081019281900390910190855afa158015614202573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81161580159061427d57508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6142e857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496d7065726d61783a20494e56414c49445f5349474e41545552450000000000604482015290519081900360640190fd5b50505050505050505050565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561437357600080fd5b505afa158015614387573d6000803e3d6000fd5b505050506040513d602081101561439d57600080fd5b50519392505050565b6000818361440f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152835160248401528351909283926044909101919085019080838360008315612e20578181015183820152602001612e08565b50600083858161441b57fe5b0495945050505050565b61442d6155ed565b8273ffffffffffffffffffffffffffffffffffffffff1663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561447557600080fd5b505af1158015614489573d6000803e3d6000fd5b5050505060008373ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156144d757600080fd5b505af11580156144eb573d6000803e3d6000fd5b505050506040513d602081101561450157600080fd5b5051604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905191925060009173ffffffffffffffffffffffffffffffffffffffff8716916318160ddd916004808301926020929190829003018186803b15801561456f57600080fd5b505afa158015614583573d6000803e3d6000fd5b505050506040513d602081101561459957600080fd5b5051604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301529151929350600092918816916370a0823191602480820192602092909190829003018186803b15801561461157600080fd5b505afa158015614625573d6000803e3d6000fd5b505050506040513d602081101561463b57600080fd5b505190506000614651838363ffffffff6133c616565b90506040518061016001604052808873ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018873ffffffffffffffffffffffffffffffffffffffff166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b1580156146c757600080fd5b505afa1580156146db573d6000803e3d6000fd5b505050506040513d60208110156146f157600080fd5b50518152602001614714670de0b6b3a7640000611367858963ffffffff61305916565b8152602001614735670de0b6b3a7640000611367868963ffffffff61305916565b8152602001614756670de0b6b3a7640000611367868963ffffffff61305916565b81526020018873ffffffffffffffffffffffffffffffffffffffff166391b427456040518163ffffffff1660e01b815260040160206040518083038186803b1580156147a157600080fd5b505afa1580156147b5573d6000803e3d6000fd5b505050506040513d60208110156147cb57600080fd5b50518152604080517f1aebf12f000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692631aebf12f9260048083019392829003018186803b15801561483757600080fd5b505afa15801561484b573d6000803e3d6000fd5b505050506040513d602081101561486157600080fd5b50518152604080517f4322b714000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692634322b7149260048083019392829003018186803b1580156148cd57600080fd5b505afa1580156148e1573d6000803e3d6000fd5b505050506040513d60208110156148f757600080fd5b50518152604080517f5b2b9d1a000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692635b2b9d1a9260048083019392829003018186803b15801561496357600080fd5b505afa158015614977573d6000803e3d6000fd5b505050506040513d602081101561498d57600080fd5b50518152600060209091015294506149a485614e33565b6101408601525050505092915050565b6149bc6155ed565b600082604001516149cc84614c15565b10156149dd57508190506000614a14565b60006149f0846040015161206f86614c15565b90506000614a028560a0015183614f33565b9050614a0e8582614f49565b93509150505b915091565b610140908101519101511190565b6000808211614a9757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4552524f523a2072617465203d20300000000000000000000000000000000000604482015290519081900360640190fd5b826101400151821115614b0b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552524f523a205441524745542052415445203e204341434845442052415445604482015290519081900360640190fd5b6000614b178484615009565b9050614b22846151e4565b811115614b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180615678602f913960400191505060405180910390fd5b6000614b9f82611367670de0b6b3a7640000886040015161305990919063ffffffff16565b9050614bd4614bad86614c15565b6040518060600160405280602381526020016158906023913983919063ffffffff612db216565b95945050505050565b614be56155ed565b60a0830151614bfa908363ffffffff612fe516565b60a0840152614c0883614e33565b6101408401525090919050565b60006109a68260a001518360600151612fe590919063ffffffff16565b6000614c4884614c428585615224565b84615232565b949350505050565b6000614c6e8261136785670de0b6b3a764000063ffffffff61305916565b905080614c7d57506000610f76565b600854614ca79073ffffffffffffffffffffffffffffffffffffffff16858563ffffffff613d4016565b604080517f6a627842000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff861691636a6278429160248083019260209291908290030181600087803b158015614d1557600080fd5b505af1158015614d29573d6000803e3d6000fd5b505050506040513d6020811015614d3f57600080fd5b50516040805185815260208101839052815192935073ffffffffffffffffffffffffffffffffffffffff8716927f20541ba081e1e2ed9b41701070442c1fe618b0fec04825ba790aea8373f4e237929181900390910190a29392505050565b6000808373ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b158015614de957600080fd5b505af1158015614dfd573d6000803e3d6000fd5b505050506040513d6020811015614e1357600080fd5b50519050614c48670de0b6b3a7640000611367858463ffffffff61305916565b600080614e3f836151e4565b90506000614e668460e00151611367670de0b6b3a76400008561305990919063ffffffff16565b905060008460e00151831015614e7d575080614efe565b6000614ec4614ea18760e00151670de0b6b3a76400006133c690919063ffffffff16565b611367670de0b6b3a76400006131468a60e00151896133c690919063ffffffff16565b9050614efa670de0b6b3a7640000614eee611d0660018a61012001516133c690919063ffffffff16565b9063ffffffff612fe516565b9150505b614bd4670de0b6b3a764000061136784613146670de0b6b3a7640000611367614f268c61541b565b889063ffffffff61305916565b6000818310614f425781610f76565b5090919050565b614f516155ed565b6000614f7d84604001516040518060600160405280602381526020016156ea60239139613b2187614c15565b905080831115614fd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180615862602e913960400191505060405180910390fd5b60a0840151614fed908463ffffffff6133c616565b60a0850152614ffb84614e33565b610140850152509192915050565b60006150148361541b565b821161506d57615066670de0b6b3a76400006113678560e00151613146615061670de0b6b3a76400006131466150498b61541b565b6113678b670de0b6b3a764000063ffffffff61305916565b615473565b905061516d565b61012083015160009061508790600163ffffffff6133c616565b905060006150b3670de0b6b3a764000061206f8761012001518860e0015161305990919063ffffffff16565b905060006151086150c38761541b565b6113676150e58960e00151670de0b6b3a76400006133c690919063ffffffff16565b613146670de0b6b3a76400006113678c60e001518c61305990919063ffffffff16565b9050600061514d615061670de0b6b3a76400006131466151316004828a8963ffffffff61305916565b614eee670de0b6b3a76400006113678a8063ffffffff61305916565b905061516660026113678681858863ffffffff612fe516565b9450505050505b670de0b6b3a76400008111156109a657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552524f523a20544152474554205554494c495a4154494f4e203e2031303025604482015290519081900360640190fd5b6000806151f083614c15565b90508061520157600091505061164b565b610f7681611367670de0b6b3a7640000866040015161305990919063ffffffff16565b6000610f76838360006154c4565b6000615250670de0b6b3a7640000611367858563ffffffff61305916565b90508061525f57506000610f76565b60008473ffffffffffffffffffffffffffffffffffffffff1663ad7a672f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156152a757600080fd5b505afa1580156152bb573d6000803e3d6000fd5b505050506040513d60208110156152d157600080fd5b50519050808211156152fc576152f98361136783670de0b6b3a764000063ffffffff61305916565b93505b61532373ffffffffffffffffffffffffffffffffffffffff8616868663ffffffff613d4016565b604080517f95a2251f000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8716916395a2251f9160248083019260209291908290030181600087803b15801561539157600080fd5b505af11580156153a5573d6000803e3d6000fd5b505050506040513d60208110156153bb57600080fd5b50516040805182815260208101879052815192945073ffffffffffffffffffffffffffffffffffffffff8816927f8d69ef09150dd510133bc8e54e6ca115e8cf3370ea49a4a5ae56a1cdefc835e9929181900390910190a2509392505050565b60006109a6670de0b6b3a764000061136761544c856101000151670de0b6b3a76400006133c690919063ffffffff16565b613146670de0b6b3a76400006113678860c001518960e0015161305990919063ffffffff16565b600060038211156154b6575080600160028204015b818110156154b05780915060028182858161549f57fe5b0401816154a857fe5b049050615488565b5061164b565b811561164b57506001919050565b6000806154e38461136787670de0b6b3a764000063ffffffff61305916565b905060006154f882600163ffffffff612fe516565b9050831561553a57600061551e670de0b6b3a7640000611367848963ffffffff61305916565b90508681111561552e5782615530565b815b9350505050610f76565b6000615558670de0b6b3a7640000611367858963ffffffff61305916565b9050868110156155685781615530565b829350505050610f76565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106155b457805160ff19168380011785556155e1565b828001600101855582156155e1579182015b828111156155e15782518255916020019190600101906155c6565b50612fe192915061565d565b604051806101600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61138591905b80821115612fe1576000815560010161566356fe4552524f523a20544152474554205554494c495a4154494f4e203e2043555252454e54205554494c495a4154494f4e4c656e64696e675661756c7456313a20424f52524f5741424c455f454e41424c45444c656e64696e675661756c7456313a20424f52524f5741424c455f4558495354534552524f523a204e4547415449564520415641494c41424c45204c49515549444954594c656e64696e675661756c7456313a20424f52524f5741424c455f4e4f545f464f554e444c656e64696e675661756c7456313a20424f52524f5741424c455f44495341424c45444c656e64696e675661756c7456313a204e4547415449564520414d4f554e5420544f20414c4c4f43415445454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774c656e64696e675661756c7456313a20494e53554646494349454e545f4c49515549444954594c656e64696e675661756c7456313a20494e56414c49445f554e4445524c59494e474c656e64696e675661756c7456313a20424f52524f5741424c455f444f45534e545f4558495354534552524f523a204445414c4c4f4341544520414d4f554e54203e20415641494c41424c45204c49515549444954594552524f523a2054415247455420535550504c59203e20544f54414c20535550504c594c656e64696e675661756c7456313a2052454445454d5f414d4f554e545f5a45524f4c656e64696e675661756c7456313a204d41585f424f52524f5741424c45535f4c454e475448a265627a7a72315820272b1ff2f5bdfb5ffe4ff85e7b931a1776d5924d30728d423cc60a2c786295d764736f6c63430005100032
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102925760003560e01c80637ecebe0011610160578063bc25cf77116100d8578063d505accf1161008c578063eb1ea9f411610071578063eb1ea9f414610891578063fca7820b146108c4578063fff6cae9146108e157610292565b8063d505accf146107f8578063dd62ed3e1461085657610292565b8063c45a0155116100bd578063c45a0155146107b5578063c5b7e148146107bd578063c72f3fbb146107f057610292565b8063bc25cf771461077a578063be340e32146107ad57610292565b806398084db71161012f578063ad7a672f11610114578063ad7a672f1461074d578063ade37c1314610755578063ba9a7a561461077257610292565b806398084db71461070c578063a9059cbb1461071457610292565b80637ecebe0014610696578063821beaf5146106c957806395a2251f146106d157806395d89b411461070457610292565b80633ba0b9a91161020e57806352ac4b02116101c25780636a627842116101a75780636a627842146105ff5780636f307dc31461063257806370a082311461066357610292565b806352ac4b021461057e578063579ce367146105b157610292565b80634643ec58116101f35780634643ec58146104645780634a5d316c14610543578063506fb0861461054b57610292565b80633ba0b9a9146104545780634322b7141461045c57610292565b806323b872dd11610265578063313ce5671161024a578063313ce567146103fb57806332fe35fd146104195780633644e5151461044c57610292565b806323b872dd146103b057806330adf81f146103f357610292565b806306fdde0314610297578063095ea7b31461031457806318160ddd14610361578063218b5b811461037b575b600080fd5b61029f6108e9565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102d95781810151838201526020016102c1565b50505050905090810190601f1680156103065780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61034d6004803603604081101561032a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610995565b604080519115158252519081900360200190f35b6103696109ac565b60408051918252519081900360200190f35b6103ae6004803603602081101561039157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166109b2565b005b61034d600480360360608110156103c657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610e68565b610369610f7d565b610403610fa1565b6040805160ff9092168252519081900360200190f35b6103ae6004803603602081101561042f57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610faa565b6103696112fe565b610369611304565b610369611388565b6103ae6004803603606081101561047a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156104b257600080fd5b8201836020820111156104c457600080fd5b803590602001918460018302840111640100000000831117156104e657600080fd5b91939092909160208101903564010000000081111561050457600080fd5b82018360208201111561051657600080fd5b8035906020019184600183028401116401000000008311171561053857600080fd5b50909250905061138e565b6103ae6114df565b6103696004803603602081101561056157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611590565b6103ae6004803603602081101561059457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611650565b6105e4600480360360208110156105c757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166119a0565b60408051921515835290151560208301528051918290030190f35b6103696004803603602081101561061557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166119be565b61063a611bfd565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103696004803603602081101561067957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611c19565b610369600480360360208110156106ac57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611c2b565b610369611c3d565b610369600480360360208110156106e757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611c43565b61029f611e09565b6103ae611e81565b61034d6004803603604081101561072a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611f59565b610369611f66565b61063a6004803603602081101561076b57600080fd5b5035611f6c565b610369611fa0565b6103ae6004803603602081101561079057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611fa6565b6103696120cf565b61063a6120d5565b6103ae600480360360208110156107d357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166120f1565b6103696124a3565b6103ae600480360360e081101561080e57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c001356124af565b6103696004803603604081101561086c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166124f3565b6103ae600480360360208110156108a757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612510565b6103ae600480360360208110156108da57600080fd5b5035612a15565b6103ae612ca2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561098d5780601f106109625761010080835404028352916020019161098d565b820191906000526020600020905b81548152906001019060200180831161097057829003601f168201915b505050505081565b60006109a2338484612d43565b5060015b92915050565b60035481565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1a57600080fd5b505afa158015610a2e573d6000803e3d6000fd5b505050506040513d6020811015610a4457600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314610ac957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff16610b3a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600854604080517f6f307dc3000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff92831692841691636f307dc3916004808301926020929190829003018186803b158015610bcf57600080fd5b505afa158015610be3573d6000803e3d6000fd5b505050506040513d6020811015610bf957600080fd5b505173ffffffffffffffffffffffffffffffffffffffff1614610c67576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806158186022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff1615610ceb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806156c96021913960400191505060405180910390fd5b600c54600a11610d46576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806158d56026913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff90911661010017166001908117909155600c8054918201815583527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055517f3b94e6c56297c3ab2913d31d1c1adf8279146dbfb5624cc473e7af7a22d9c8469190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b73ffffffffffffffffffffffffffffffffffffffff831660009081526005602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14610f6757604080518082018252601e81527f496d7065726d61783a205452414e534645525f4e4f545f414c4c4f574544000060208083019190915273ffffffffffffffffffffffffffffffffffffffff87166000908152600582528381203382529091529190912054610f3591849063ffffffff612db216565b73ffffffffffffffffffffffffffffffffffffffff851660009081526005602090815260408083203384529091529020555b610f72848484612e63565b5060015b9392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025460ff1681565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561101257600080fd5b505afa158015611026573d6000803e3d6000fd5b505050506040513d602081101561103c57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff1633146110c157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661113257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff166111dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061583a6028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff161561125c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806156a76022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f54ba33e4b0861b4d81b3384c3b5130b25b55df191223d9e48b317dc289fac3a99190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60065481565b60035460009081611325611316612f7c565b600a549063ffffffff612fe516565b9050811580611332575080155b1561134957670de0b6b3a764000092505050611385565b60006113738361136784670de0b6b3a764000063ffffffff61305916565b9063ffffffff6130cc16565b905061137f818461310e565b93505050505b90565b600f5481565b60095473ffffffffffffffffffffffffffffffffffffffff16331461141457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b61148784848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152925086915085908190840183828082843760009201919091525061324092505050565b5050600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94909416939093179092555050670de0b6b3a7640000600e55565b60095473ffffffffffffffffffffffffffffffffffffffff161561156457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496d7065726d61783a20464143544f52595f414c52454144595f534554000000604482015290519081900360640190fd5b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055565b6000805b600c548110156115f9578273ffffffffffffffffffffffffffffffffffffffff16600c82815481106115c257fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156115f157905061164b565b600101611594565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018061570d6024913960400191505060405180910390fd5b919050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b1580156116b857600080fd5b505afa1580156116cc573d6000803e3d6000fd5b505050506040513d60208110156116e257600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16331461176757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff166117d857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff16611883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061583a6028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff16611901576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806157316023913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f6149acc591caf5f3d506cb615abb39ea3847de4e2aa83f4382531de216bdc6809190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600d6020526000908152604090205460ff8082169161010090041682565b600b5460009060ff16611a3257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600854600090611a7f9073ffffffffffffffffffffffffffffffffffffffff16613324565b90506000611a98600a54836133c690919063ffffffff16565b9050611abd611aa5611304565b61136783670de0b6b3a764000063ffffffff61305916565b925060035460001415611aeb57611adc836103e863ffffffff6133c616565b9250611aeb60006103e8613408565b60008311611b5a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656e64696e675661756c7456313a204d494e545f414d4f554e545f5a45524f604482015290519081900360640190fd5b611b648484613408565b611b6e60006134b9565b6040805182815260208101859052815173ffffffffffffffffffffffffffffffffffffffff87169233927f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee929081900390910190a35050611bcd613c21565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055919050565b60085473ffffffffffffffffffffffffffffffffffffffff1681565b60046020526000908152604090205481565b60076020526000908152604090205481565b600c5490565b600b5460009060ff16611cb757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905530600090815260046020526040902054611d13670de0b6b3a7640000611367611d06611304565b849063ffffffff61305916565b915060008211611d6e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806158b36022913960400191505060405180910390fd5b611d783082613c7c565b611d81826134b9565b600854611dab9073ffffffffffffffffffffffffffffffffffffffff16848463ffffffff613d4016565b6040805183815260208101839052815173ffffffffffffffffffffffffffffffffffffffff86169233927f3f693fff038bb8a046aa76d9516190ac7444f7d69cf952c4cbdc086fdef2d6fc929081900390910190a350611bcd613c21565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561098d5780601f106109625761010080835404028352916020019161098d565b600b5460ff16611ef257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611f2460006134b9565b611f2c613c21565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60006109a2338484612e63565b600a5481565b600c8181548110611f7957fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6103e881565b600b5460ff1661201757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600a546008546120a191839161207b919061206f9073ffffffffffffffffffffffffffffffffffffffff16613324565b9063ffffffff6133c616565b60085473ffffffffffffffffffffffffffffffffffffffff16919063ffffffff613d4016565b50600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600e5481565b60095473ffffffffffffffffffffffffffffffffffffffff1681565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561215957600080fd5b505afa15801561216d573d6000803e3d6000fd5b505050506040513d602081101561218357600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16331461220857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661227957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff16612324576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061583a6028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff16156123a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806156a76022913960400191505060405180910390fd5b60006123c48273ffffffffffffffffffffffffffffffffffffffff16613f1d565b90506000811161243557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c656e64696e675661756c7456313a205a45524f5f414d4f554e540000000000604482015290519081900360640190fd5b60006124418383613fd1565b90508273ffffffffffffffffffffffffffffffffffffffff167f05750bc9042b6da04fdebec7b024caed5c2e2b35c707bd1fde571f31cdaeb5668383604051808381526020018281526020019250505060405180910390a250506120a1613c21565b670c7d713b49da000081565b6124df878787878787877f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9614051565b6124ea878787612d43565b50505050505050565b600560209081526000928352604080842090915290825290205481565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561257857600080fd5b505afa15801561258c573d6000803e3d6000fd5b505050506040513d60208110156125a257600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16331461262757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661269857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff16612743576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061583a6028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff16156127c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806156a76022913960400191505060405180910390fd5b6127e873ffffffffffffffffffffffffffffffffffffffff82163063ffffffff6142f416565b1561285457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4c656e64696e675661756c7456313a204e4f545f454d50545900000000000000604482015290519081900360640190fd5b600c547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600061288483611590565b9050600c828154811061289357fe5b600091825260209091200154600c805473ffffffffffffffffffffffffffffffffffffffff90921691839081106128c657fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600c80548061291957fe5b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff8516808352600d909152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690555190917f1f537c1571c0e7fa29083762436cadb3e57564c0f78e857e498cf428124c710e91a25050600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015612a7d57600080fd5b505afa158015612a91573d6000803e3d6000fd5b505050506040513d6020811015612aa757600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314612b2c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456313a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff16612b9d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055670c7d713b49da0000811115612c3c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4c656e64696e675661756c7456313a20494e56414c49445f53455454494e4700604482015290519081900360640190fd5b600f8190556040805182815290517f9d9cd27245b4e6b06dcf523ac57b6e851b934e199eee376313f906e94bfbfd559181900360200190a150600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600b5460ff16612d1357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611f2c613c21565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260056020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b60008184841115612e5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612e20578181015183820152602001612e08565b50505050905090810190601f168015612e4d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b604080518082018252601b81527f496d7065726d61783a205452414e534645525f544f4f5f48494748000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff8616600090815260049091529190912054612ed191839063ffffffff612db216565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600460205260408082209390935590841681522054612f13908263ffffffff612fe516565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526004602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000805b600c54811015612fe1576000600c8281548110612f9957fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169050612fd6612fc982613f1d565b849063ffffffff612fe516565b925050600101612f80565b5090565b600082820183811015610f7657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082613068575060006109a6565b8282028284828161307557fe5b0414610f76576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806157d16021913960400191505060405180910390fd5b6000610f7683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506143a6565b600e546000908084111561323757600061315f613152670de0b6b3a7640000611367600f54613146878b6133c690919063ffffffff16565b9063ffffffff61305916565b869063ffffffff6133c616565b9050600061317b8561206f84611367838b63ffffffff61305916565b9050801561322857600954604080517f345ef941000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163345ef941916004808301926020929190829003018186803b1580156131ee57600080fd5b505afa158015613202573d6000803e3d6000fd5b505050506040513d602081101561321857600080fd5b505190506132268183613408565b505b50600e81905591506109a69050565b839150506109a6565b8151613253906000906020850190615573565b508051613267906001906020840190615573565b50604051469080605261577f82396040805191829003605201822086516020978801208383018352600184527f310000000000000000000000000000000000000000000000000000000000000093880193909352815180880191909152808201929092527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606083015260808201939093523060a0808301919091528351808303909101815260c090910190925250805192019190912060065550565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905160009173ffffffffffffffffffffffffffffffffffffffff8416916370a0823191602480820192602092909190829003018186803b15801561339457600080fd5b505afa1580156133a8573d6000803e3d6000fd5b505050506040513d60208110156133be57600080fd5b505192915050565b6000610f7683836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f7700815250612db2565b60035461341b908263ffffffff612fe516565b60035573ffffffffffffffffffffffffffffffffffffffff8216600090815260046020526040902054613454908263ffffffff612fe516565b73ffffffffffffffffffffffffffffffffffffffff831660008181526004602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600c5460408051828152602080840282010190915260609180156134f757816020015b6134e46155ed565b8152602001906001900390816134dc5790505b50600c5490915060005b600c548110156135f257600d6000600c838154811061351c57fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff1661357f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101906135ea565b600c54600090613595908463ffffffff6133c616565b90506135cf600c83815481106135a757fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1630614425565b84828403815181106135dd57fe5b6020026020010181905250505b600101613501565b506008546000906136189073ffffffffffffffffffffffffffffffffffffffff16613324565b905060005b8281101561367c57600061364385838151811061363657fe5b60200260200101516149b4565b865187908590811061365157fe5b60209081029190910101919091529050613671838263ffffffff612fe516565b92505060010161361d565b506136a8846040518060600160405280602681526020016157f26026913983919063ffffffff612db216565b905060005b600183038110156137825760005b816001850303811015613779576137048582600101815181106136da57fe5b60200260200101518683815181106136ee57fe5b6020026020010151614a1990919063ffffffff16565b613771576137106155ed565b85828151811061371c57fe5b6020026020010151905085826001018151811061373557fe5b602002602001015186838151811061374957fe5b60200260200101819052508086836001018151811061376457fe5b6020026020010181905250505b6001016136bb565b506001016136ad565b508160015b8381101561395e57600085828151811061379d57fe5b60200260200101516101400151905060008090506060836040519080825280602002602001820160405280156137dd578160200160208202803883390190505b509050826137f05783945050505061395e565b60005b8481101561388d578389828151811061380857fe5b602002602001015161014001511161381f5761388d565b613845848a838151811061382f57fe5b6020026020010151614a2790919063ffffffff16565b82828151811061385157fe5b60200260200101818152505061388382828151811061386c57fe5b602002602001015184612fe590919063ffffffff16565b92506001016137f3565b50858211156138a15783945050505061395e565b60005b8481101561394e578181815181106138b857fe5b6020026020010151600014156138cd57613946565b6139068282815181106138dc57fe5b60200260200101518a83815181106138f057fe5b6020026020010151614bdd90919063ffffffff16565b89828151811061391257fe5b602002602001018190525061394382828151811061392c57fe5b6020026020010151886133c690919063ffffffff16565b96505b6001016138a4565b5050600190920191506137879050565b50600082815b838110156139955761398b612fc988838151811061397e57fe5b6020026020010151614c15565b9250600101613964565b5060005b83811015613a165760008084116139b057856139c7565b6139c784611367856131468c878151811061397e57fe5b9050858111156139d45750845b6139e4818984815181106138f057fe5b8883815181106139f057fe5b6020908102919091010152613a0b868263ffffffff6133c616565b955050600101613999565b5060005b85811015613ae157868181518110613a2e57fe5b602002602001015160800151878281518110613a4657fe5b602002602001015160a001511015613ad9576000613a9b888381518110613a6957fe5b602002602001015160a00151898481518110613a8157fe5b6020026020010151608001516133c690919063ffffffff16565b9050613ad6888381518110613aac57fe5b602002602001015160000151828a8581518110613ac557fe5b602002602001015160200151614c32565b50505b600101613a1a565b50613b2e876040518060600160405280602b8152602001615754602b9139600854613b219073ffffffffffffffffffffffffffffffffffffffff16613324565b919063ffffffff612db216565b935060005b85811015613c1757868181518110613b4757fe5b602002602001015160800151878281518110613b5f57fe5b602002602001015160a001511115613c0f576000613bb4888381518110613b8257fe5b602002602001015160800151898481518110613b9a57fe5b602002602001015160a001516133c690919063ffffffff16565b905085811115613bc15750845b613bd1868263ffffffff6133c616565b9550613c0c888381518110613be257fe5b602002602001015160000151828a8581518110613bfb57fe5b602002602001015160200151614c50565b50505b600101613b33565b5050505050505050565b600854613c439073ffffffffffffffffffffffffffffffffffffffff16613324565b600a81905560408051918252517f8a0df8ef054fae2c3d2d19a7b322e864870cc9fd3cb07fb9526309c596244bf49181900360200190a1565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020526040902054613cb2908263ffffffff6133c616565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260046020526040902055600354613ceb908263ffffffff6133c616565b60035560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000178152925182516000946060949389169392918291908083835b60208310613e1657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613dd9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613e78576040519150601f19603f3d011682016040523d82523d6000602084013e613e7d565b606091505b5091509150818015613eab575080511580613eab5750808060200190516020811015613ea857600080fd5b50515b613f1657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f21736166655472616e7366657200000000000000000000000000000000000000604482015290519081900360640190fd5b5050505050565b60006109a6828373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015613fa057600080fd5b505afa158015613fb4573d6000803e3d6000fd5b505050506040513d6020811015613fca57600080fd5b5051614d9e565b6000610f7683838573ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561402057600080fd5b505af1158015614034573d6000803e3d6000fd5b505050506040513d602081101561404a57600080fd5b5051614c32565b428510156140c057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496d7065726d61783a2045585049524544000000000000000000000000000000604482015290519081900360640190fd5b60065473ffffffffffffffffffffffffffffffffffffffff808a1660008181526007602090815260408083208054600180820190925582518085018a905280840196909652958e166060860152608085018d905260a085019590955260c08085018c90528151808603909101815260e0850182528051908301207f19010000000000000000000000000000000000000000000000000000000000006101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff8a166101828501526101a284018990526101c28401889052519193926101e2808201937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081019281900390910190855afa158015614202573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81161580159061427d57508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6142e857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496d7065726d61783a20494e56414c49445f5349474e41545552450000000000604482015290519081900360640190fd5b50505050505050505050565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561437357600080fd5b505afa158015614387573d6000803e3d6000fd5b505050506040513d602081101561439d57600080fd5b50519392505050565b6000818361440f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152835160248401528351909283926044909101919085019080838360008315612e20578181015183820152602001612e08565b50600083858161441b57fe5b0495945050505050565b61442d6155ed565b8273ffffffffffffffffffffffffffffffffffffffff1663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561447557600080fd5b505af1158015614489573d6000803e3d6000fd5b5050505060008373ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156144d757600080fd5b505af11580156144eb573d6000803e3d6000fd5b505050506040513d602081101561450157600080fd5b5051604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905191925060009173ffffffffffffffffffffffffffffffffffffffff8716916318160ddd916004808301926020929190829003018186803b15801561456f57600080fd5b505afa158015614583573d6000803e3d6000fd5b505050506040513d602081101561459957600080fd5b5051604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301529151929350600092918816916370a0823191602480820192602092909190829003018186803b15801561461157600080fd5b505afa158015614625573d6000803e3d6000fd5b505050506040513d602081101561463b57600080fd5b505190506000614651838363ffffffff6133c616565b90506040518061016001604052808873ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018873ffffffffffffffffffffffffffffffffffffffff166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b1580156146c757600080fd5b505afa1580156146db573d6000803e3d6000fd5b505050506040513d60208110156146f157600080fd5b50518152602001614714670de0b6b3a7640000611367858963ffffffff61305916565b8152602001614735670de0b6b3a7640000611367868963ffffffff61305916565b8152602001614756670de0b6b3a7640000611367868963ffffffff61305916565b81526020018873ffffffffffffffffffffffffffffffffffffffff166391b427456040518163ffffffff1660e01b815260040160206040518083038186803b1580156147a157600080fd5b505afa1580156147b5573d6000803e3d6000fd5b505050506040513d60208110156147cb57600080fd5b50518152604080517f1aebf12f000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692631aebf12f9260048083019392829003018186803b15801561483757600080fd5b505afa15801561484b573d6000803e3d6000fd5b505050506040513d602081101561486157600080fd5b50518152604080517f4322b714000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692634322b7149260048083019392829003018186803b1580156148cd57600080fd5b505afa1580156148e1573d6000803e3d6000fd5b505050506040513d60208110156148f757600080fd5b50518152604080517f5b2b9d1a000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692635b2b9d1a9260048083019392829003018186803b15801561496357600080fd5b505afa158015614977573d6000803e3d6000fd5b505050506040513d602081101561498d57600080fd5b50518152600060209091015294506149a485614e33565b6101408601525050505092915050565b6149bc6155ed565b600082604001516149cc84614c15565b10156149dd57508190506000614a14565b60006149f0846040015161206f86614c15565b90506000614a028560a0015183614f33565b9050614a0e8582614f49565b93509150505b915091565b610140908101519101511190565b6000808211614a9757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4552524f523a2072617465203d20300000000000000000000000000000000000604482015290519081900360640190fd5b826101400151821115614b0b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552524f523a205441524745542052415445203e204341434845442052415445604482015290519081900360640190fd5b6000614b178484615009565b9050614b22846151e4565b811115614b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180615678602f913960400191505060405180910390fd5b6000614b9f82611367670de0b6b3a7640000886040015161305990919063ffffffff16565b9050614bd4614bad86614c15565b6040518060600160405280602381526020016158906023913983919063ffffffff612db216565b95945050505050565b614be56155ed565b60a0830151614bfa908363ffffffff612fe516565b60a0840152614c0883614e33565b6101408401525090919050565b60006109a68260a001518360600151612fe590919063ffffffff16565b6000614c4884614c428585615224565b84615232565b949350505050565b6000614c6e8261136785670de0b6b3a764000063ffffffff61305916565b905080614c7d57506000610f76565b600854614ca79073ffffffffffffffffffffffffffffffffffffffff16858563ffffffff613d4016565b604080517f6a627842000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff861691636a6278429160248083019260209291908290030181600087803b158015614d1557600080fd5b505af1158015614d29573d6000803e3d6000fd5b505050506040513d6020811015614d3f57600080fd5b50516040805185815260208101839052815192935073ffffffffffffffffffffffffffffffffffffffff8716927f20541ba081e1e2ed9b41701070442c1fe618b0fec04825ba790aea8373f4e237929181900390910190a29392505050565b6000808373ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b158015614de957600080fd5b505af1158015614dfd573d6000803e3d6000fd5b505050506040513d6020811015614e1357600080fd5b50519050614c48670de0b6b3a7640000611367858463ffffffff61305916565b600080614e3f836151e4565b90506000614e668460e00151611367670de0b6b3a76400008561305990919063ffffffff16565b905060008460e00151831015614e7d575080614efe565b6000614ec4614ea18760e00151670de0b6b3a76400006133c690919063ffffffff16565b611367670de0b6b3a76400006131468a60e00151896133c690919063ffffffff16565b9050614efa670de0b6b3a7640000614eee611d0660018a61012001516133c690919063ffffffff16565b9063ffffffff612fe516565b9150505b614bd4670de0b6b3a764000061136784613146670de0b6b3a7640000611367614f268c61541b565b889063ffffffff61305916565b6000818310614f425781610f76565b5090919050565b614f516155ed565b6000614f7d84604001516040518060600160405280602381526020016156ea60239139613b2187614c15565b905080831115614fd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180615862602e913960400191505060405180910390fd5b60a0840151614fed908463ffffffff6133c616565b60a0850152614ffb84614e33565b610140850152509192915050565b60006150148361541b565b821161506d57615066670de0b6b3a76400006113678560e00151613146615061670de0b6b3a76400006131466150498b61541b565b6113678b670de0b6b3a764000063ffffffff61305916565b615473565b905061516d565b61012083015160009061508790600163ffffffff6133c616565b905060006150b3670de0b6b3a764000061206f8761012001518860e0015161305990919063ffffffff16565b905060006151086150c38761541b565b6113676150e58960e00151670de0b6b3a76400006133c690919063ffffffff16565b613146670de0b6b3a76400006113678c60e001518c61305990919063ffffffff16565b9050600061514d615061670de0b6b3a76400006131466151316004828a8963ffffffff61305916565b614eee670de0b6b3a76400006113678a8063ffffffff61305916565b905061516660026113678681858863ffffffff612fe516565b9450505050505b670de0b6b3a76400008111156109a657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552524f523a20544152474554205554494c495a4154494f4e203e2031303025604482015290519081900360640190fd5b6000806151f083614c15565b90508061520157600091505061164b565b610f7681611367670de0b6b3a7640000866040015161305990919063ffffffff16565b6000610f76838360006154c4565b6000615250670de0b6b3a7640000611367858563ffffffff61305916565b90508061525f57506000610f76565b60008473ffffffffffffffffffffffffffffffffffffffff1663ad7a672f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156152a757600080fd5b505afa1580156152bb573d6000803e3d6000fd5b505050506040513d60208110156152d157600080fd5b50519050808211156152fc576152f98361136783670de0b6b3a764000063ffffffff61305916565b93505b61532373ffffffffffffffffffffffffffffffffffffffff8616868663ffffffff613d4016565b604080517f95a2251f000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8716916395a2251f9160248083019260209291908290030181600087803b15801561539157600080fd5b505af11580156153a5573d6000803e3d6000fd5b505050506040513d60208110156153bb57600080fd5b50516040805182815260208101879052815192945073ffffffffffffffffffffffffffffffffffffffff8816927f8d69ef09150dd510133bc8e54e6ca115e8cf3370ea49a4a5ae56a1cdefc835e9929181900390910190a2509392505050565b60006109a6670de0b6b3a764000061136761544c856101000151670de0b6b3a76400006133c690919063ffffffff16565b613146670de0b6b3a76400006113678860c001518960e0015161305990919063ffffffff16565b600060038211156154b6575080600160028204015b818110156154b05780915060028182858161549f57fe5b0401816154a857fe5b049050615488565b5061164b565b811561164b57506001919050565b6000806154e38461136787670de0b6b3a764000063ffffffff61305916565b905060006154f882600163ffffffff612fe516565b9050831561553a57600061551e670de0b6b3a7640000611367848963ffffffff61305916565b90508681111561552e5782615530565b815b9350505050610f76565b6000615558670de0b6b3a7640000611367858963ffffffff61305916565b9050868110156155685781615530565b829350505050610f76565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106155b457805160ff19168380011785556155e1565b828001600101855582156155e1579182015b828111156155e15782518255916020019190600101906155c6565b50612fe192915061565d565b604051806101600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61138591905b80821115612fe1576000815560010161566356fe4552524f523a20544152474554205554494c495a4154494f4e203e2043555252454e54205554494c495a4154494f4e4c656e64696e675661756c7456313a20424f52524f5741424c455f454e41424c45444c656e64696e675661756c7456313a20424f52524f5741424c455f4558495354534552524f523a204e4547415449564520415641494c41424c45204c49515549444954594c656e64696e675661756c7456313a20424f52524f5741424c455f4e4f545f464f554e444c656e64696e675661756c7456313a20424f52524f5741424c455f44495341424c45444c656e64696e675661756c7456313a204e4547415449564520414d4f554e5420544f20414c4c4f43415445454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774c656e64696e675661756c7456313a20494e53554646494349454e545f4c49515549444954594c656e64696e675661756c7456313a20494e56414c49445f554e4445524c59494e474c656e64696e675661756c7456313a20424f52524f5741424c455f444f45534e545f4558495354534552524f523a204445414c4c4f4341544520414d4f554e54203e20415641494c41424c45204c49515549444954594552524f523a2054415247455420535550504c59203e20544f54414c20535550504c594c656e64696e675661756c7456313a2052454445454d5f414d4f554e545f5a45524f4c656e64696e675661756c7456313a204d41585f424f52524f5741424c45535f4c454e475448a265627a7a72315820272b1ff2f5bdfb5ffe4ff85e7b931a1776d5924d30728d423cc60a2c786295d764736f6c63430005100032
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.