More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 15 from a total of 15 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Add Borrowable | 322586297 | 19 days ago | IN | 0 ETH | 0.00000221 | ||||
Add Borrowable | 322586259 | 19 days ago | IN | 0 ETH | 0.00000224 | ||||
Add Borrowable | 322586225 | 19 days ago | IN | 0 ETH | 0.00000233 | ||||
Add Borrowable | 322586188 | 19 days ago | IN | 0 ETH | 0.00000231 | ||||
Remove Borrowabl... | 316672449 | 36 days ago | IN | 0 ETH | 0.00000185 | ||||
Disable Borrowab... | 316672428 | 36 days ago | IN | 0 ETH | 0.00000126 | ||||
Remove Borrowabl... | 316672379 | 36 days ago | IN | 0 ETH | 0.00000189 | ||||
Disable Borrowab... | 316672355 | 36 days ago | IN | 0 ETH | 0.00000125 | ||||
Add Borrowable | 316625378 | 36 days ago | IN | 0 ETH | 0.00000323 | ||||
Add Borrowable | 316625336 | 36 days ago | IN | 0 ETH | 0.00000332 | ||||
Add Borrowable | 316625289 | 36 days ago | IN | 0 ETH | 0.00000342 | ||||
Add Borrowable | 316625219 | 36 days ago | IN | 0 ETH | 0.00000342 | ||||
Add Borrowable | 316625171 | 36 days ago | IN | 0 ETH | 0.00000325 | ||||
Add Borrowable | 314865408 | 41 days ago | IN | 0 ETH | 0.00000944 | ||||
Add Borrowable | 314865396 | 41 days ago | IN | 0 ETH | 0.00001109 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
314865381 | 41 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
LendingVaultV2
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 "./LVSetterV2.sol"; import "./interfaces/ILendingVaultV2Factory.sol"; import "./interfaces/ILendingVaultCallee.sol"; import "./interfaces/IBorrowable.sol"; contract LendingVaultV2 is LVSetterV2 { 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 = ILendingVaultV2Factory(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, "LendingVaultV2: 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, "LendingVaultV2: 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); } function flashAllocate(address borrowable, uint allocateAmount, bytes calldata data) external nonReentrant update { require(borrowableInfo[borrowable].exists, "LendingVaultV2: BORROWABLE_DOESNT_EXISTS"); require(borrowableInfo[borrowable].enabled, "LendingVaultV2: BORROWABLE_DISABLED"); _withdrawAndReallocate(allocateAmount); uint exchangeRate = IBorrowable(borrowable).exchangeRate(); _allocate(IBorrowable(borrowable), allocateAmount, exchangeRate); ILendingVaultCallee(msg.sender).lendingVaultAllocate(borrowable, allocateAmount, data); _withdrawAndReallocate(0); require(IBorrowable(borrowable).totalBalance() > exchangeRate / 1e15, "LendingVaultV2: INCONVENIENT_REALLOCATION"); } }
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); 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 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; /*** 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); 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; }
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 ILendingVaultCallee { function lendingVaultAllocate(address borrowable, uint allocateAmount, bytes calldata data) external; }
pragma solidity >=0.5.0; interface ILendingVaultV2 { /*** 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 V2 ***/ 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 ILendingVaultV2Factory { 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); } } 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); uint targetSupply = borrowable.totalBorrows.mul(1e18).div(targetUtilizationRate); if (targetSupply < totalSupply(borrowable)) { // catch any edge scenarios... return 0; } return targetSupply.sub(totalSupply(borrowable)); } 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 "./LVStorageV2.sol"; import "./interfaces/ILendingVaultV2.sol"; import "./libraries/BorrowableHelpers.sol"; import "./libraries/BorrowableObject.sol"; contract LVAllocatorV2 is ILendingVaultV2, PoolToken, LVStorageV2 { 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, "LendingVaultV2: INSUFFICIENT_LIQUIDITY"); if (borrowablesLength == 0) return; // 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, "LendingVaultV2: 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 "./LVAllocatorV2.sol"; import "./interfaces/ILendingVaultV2Factory.sol"; contract LVSetterV2 is LVAllocatorV2 { 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, "LendingVaultV2: UNAUTHORIZED"); // sufficient check _setName(_name, _symbol); underlying = _underlying; exchangeRateLast = initialExchangeRate; } function _setReserveFactor(uint newReserveFactor) external onlyAdmin nonReentrant { require(newReserveFactor <= RESERVE_FACTOR_MAX, "LendingVaultV2: INVALID_SETTING"); reserveFactor = newReserveFactor; emit NewReserveFactor(newReserveFactor); } /*** Borrowables management ***/ function addBorrowable(address borrowable) external onlyAdmin nonReentrant { require(IBorrowable(borrowable).underlying() == underlying, "LendingVaultV2: INVALID_UNDERLYING"); require(!borrowableInfo[borrowable].exists, "LendingVaultV2: BORROWABLE_EXISTS"); require(borrowables.length < MAX_BORROWABLES_LENGTH, "LendingVaultV2: 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, "LendingVaultV2: BORROWABLE_DOESNT_EXISTS"); require(!borrowableInfo[borrowable].enabled, "LendingVaultV2: BORROWABLE_ENABLED"); require(borrowable.myUnderlyingBalance() == 0, "LendingVaultV2: 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, "LendingVaultV2: BORROWABLE_DOESNT_EXISTS"); require(borrowableInfo[borrowable].enabled, "LendingVaultV2: BORROWABLE_DISABLED"); borrowableInfo[borrowable].enabled = false; emit DisableBorrowable(address(borrowable)); } function enableBorrowable(address borrowable) external onlyAdmin nonReentrant { require(borrowableInfo[borrowable].exists, "LendingVaultV2: BORROWABLE_DOESNT_EXISTS"); require(!borrowableInfo[borrowable].enabled, "LendingVaultV2: BORROWABLE_ENABLED"); borrowableInfo[borrowable].enabled = true; emit EnableBorrowable(address(borrowable)); } function unwindBorrowable(address borrowable) external onlyAdmin nonReentrant update { require(borrowableInfo[borrowable].exists, "LendingVaultV2: BORROWABLE_DOESNT_EXISTS"); require(!borrowableInfo[borrowable].enabled, "LendingVaultV2: BORROWABLE_ENABLED"); uint underlyingBalance = borrowable.myUnderlyingBalance(); require(underlyingBalance > 0, "LendingVaultV2: ZERO_AMOUNT"); uint redeemTokens = borrowable.myBalance(); uint actualRedeemAmount = _deallocate(IBorrowable(borrowable), redeemTokens); emit UnwindBorrowable(address(borrowable), underlyingBalance, actualRedeemAmount); } modifier onlyAdmin() { require(msg.sender == ILendingVaultV2Factory(factory).admin(), "LendingVaultV2: UNAUTHORIZED"); _; } }
pragma solidity =0.5.16; contract LVStorageV2 { 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, "LendingVaultV2: BORROWABLE_NOT_FOUND"); } uint public exchangeRateLast; uint public reserveFactor = 0.00e18; //0% }
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
Contract ABI
API[{"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":false,"inputs":[{"internalType":"address","name":"borrowable","type":"address"},{"internalType":"uint256","name":"allocateAmount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flashAllocate","outputs":[],"payable":false,"stateMutability":"nonpayable","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
60806040526002805460ff19908116601217909155600b805490911660011790556000600f55615c5c806100346000396000f3fe608060405234801561001057600080fd5b50600436106102ad5760003560e01c80637ecebe001161017b578063be340e32116100d8578063d505accf1161008c578063eb1ea9f411610071578063eb1ea9f41461093e578063fca7820b14610971578063fff6cae91461098e576102ad565b8063d505accf146108a5578063dd62ed3e14610903576102ad565b8063c5b7e148116100bd578063c5b7e148146107d8578063c72f3fbb1461080b578063ccc9564a14610813576102ad565b8063be340e32146107c8578063c45a0155146107d0576102ad565b8063a9059cbb1161012f578063ade37c1311610114578063ade37c1314610770578063ba9a7a561461078d578063bc25cf7714610795576102ad565b8063a9059cbb1461072f578063ad7a672f14610768576102ad565b806395a2251f1161016057806395a2251f146106ec57806395d89b411461071f57806398084db714610727576102ad565b80637ecebe00146106b1578063821beaf5146106e4576102ad565b80633ba0b9a91161022957806352ac4b02116101dd5780636a627842116101c25780636a6278421461061a5780636f307dc31461064d57806370a082311461067e576102ad565b806352ac4b0214610599578063579ce367146105cc576102ad565b80634643ec581161020e5780634643ec581461047f5780634a5d316c1461055e578063506fb08614610566576102ad565b80633ba0b9a91461046f5780634322b71414610477576102ad565b806323b872dd11610280578063313ce56711610265578063313ce5671461041657806332fe35fd146104345780633644e51514610467576102ad565b806323b872dd146103cb57806330adf81f1461040e576102ad565b806306fdde03146102b2578063095ea7b31461032f57806318160ddd1461037c578063218b5b8114610396575b600080fd5b6102ba610996565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102f45781810151838201526020016102dc565b50505050905090810190601f1680156103215780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103686004803603604081101561034557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610a42565b604080519115158252519081900360200190f35b610384610a59565b60408051918252519081900360200190f35b6103c9600480360360208110156103ac57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610a5f565b005b610368600480360360608110156103e157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610f15565b61038461102a565b61041e61104e565b6040805160ff9092168252519081900360200190f35b6103c96004803603602081101561044a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611057565b6103846113ab565b6103846113b1565b610384611435565b6103c96004803603606081101561049557600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156104cd57600080fd5b8201836020820111156104df57600080fd5b8035906020019184600183028401116401000000008311171561050157600080fd5b91939092909160208101903564010000000081111561051f57600080fd5b82018360208201111561053157600080fd5b8035906020019184600183028401116401000000008311171561055357600080fd5b50909250905061143b565b6103c961158c565b6103846004803603602081101561057c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661163d565b6103c9600480360360208110156105af57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166116fd565b6105ff600480360360208110156105e257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a4d565b60408051921515835290151560208301528051918290030190f35b6103846004803603602081101561063057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a6b565b610655611caa565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103846004803603602081101561069457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611cc6565b610384600480360360208110156106c757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611cd8565b610384611cea565b6103846004803603602081101561070257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611cf0565b6102ba611eb6565b6103c9611f2e565b6103686004803603604081101561074557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612006565b610384612013565b6106556004803603602081101561078657600080fd5b5035612019565b61038461204d565b6103c9600480360360208110156107ab57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612053565b61038461217c565b610655612182565b6103c9600480360360208110156107ee57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661219e565b610384612574565b6103c96004803603606081101561082957600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561086657600080fd5b82018360208201111561087857600080fd5b8035906020019184600183028401116401000000008311171561089a57600080fd5b509092509050612580565b6103c9600480360360e08110156108bb57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135612983565b6103846004803603604081101561091957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166129c7565b6103c96004803603602081101561095457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166129e4565b6103c96004803603602081101561098757600080fd5b5035612ee2565b6103c961316f565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f81018490048402820184019092528181529291830182828015610a3a5780601f10610a0f57610100808354040283529160200191610a3a565b820191906000526020600020905b815481529060010190602001808311610a1d57829003601f168201915b505050505081565b6000610a4f338484613210565b5060015b92915050565b60035481565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015610ac757600080fd5b505afa158015610adb573d6000803e3d6000fd5b505050506040513d6020811015610af157600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314610b7657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff16610be757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600854604080517f6f307dc3000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff92831692841691636f307dc3916004808301926020929190829003018186803b158015610c7c57600080fd5b505afa158015610c90573d6000803e3d6000fd5b505050506040513d6020811015610ca657600080fd5b505173ffffffffffffffffffffffffffffffffffffffff1614610d14576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615bbc6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff1615610d98576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806159ce6021913960400191505060405180910390fd5b600c54600a11610df3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180615a126026913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff90911661010017166001908117909155600c8054918201815583527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055517f3b94e6c56297c3ab2913d31d1c1adf8279146dbfb5624cc473e7af7a22d9c8469190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b73ffffffffffffffffffffffffffffffffffffffff831660009081526005602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461101457604080518082018252601e81527f496d7065726d61783a205452414e534645525f4e4f545f414c4c4f574544000060208083019190915273ffffffffffffffffffffffffffffffffffffffff87166000908152600582528381203382529091529190912054610fe291849063ffffffff61327f16565b73ffffffffffffffffffffffffffffffffffffffff851660009081526005602090815260408083203384529091529020555b61101f848484613330565b5060015b9392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025460ff1681565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b1580156110bf57600080fd5b505afa1580156110d3573d6000803e3d6000fd5b505050506040513d60208110156110e957600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16331461116e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff166111df57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff1661128a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615b196028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff1615611309576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615a386022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f54ba33e4b0861b4d81b3384c3b5130b25b55df191223d9e48b317dc289fac3a99190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60065481565b600354600090816113d26113c3613449565b600a549063ffffffff6134b216565b90508115806113df575080155b156113f657670de0b6b3a764000092505050611432565b60006114208361141484670de0b6b3a764000063ffffffff61352616565b9063ffffffff61359916565b905061142c81846135db565b93505050505b90565b600f5481565b60095473ffffffffffffffffffffffffffffffffffffffff1633146114c157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b61153484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152925086915085908190840183828082843760009201919091525061370d92505050565b5050600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94909416939093179092555050670de0b6b3a7640000600e55565b60095473ffffffffffffffffffffffffffffffffffffffff161561161157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496d7065726d61783a20464143544f52595f414c52454144595f534554000000604482015290519081900360640190fd5b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055565b6000805b600c548110156116a6578273ffffffffffffffffffffffffffffffffffffffff16600c828154811061166f57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141561169e5790506116f8565b600101611641565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615bde6024913960400191505060405180910390fd5b919050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561176557600080fd5b505afa158015611779573d6000803e3d6000fd5b505050506040513d602081101561178f57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16331461181457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661188557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff16611930576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615b196028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff166119ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806159ef6023913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f6149acc591caf5f3d506cb615abb39ea3847de4e2aa83f4382531de216bdc6809190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600d6020526000908152604090205460ff8082169161010090041682565b600b5460009060ff16611adf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600854600090611b2c9073ffffffffffffffffffffffffffffffffffffffff166137f1565b90506000611b45600a548361389390919063ffffffff16565b9050611b6a611b526113b1565b61141483670de0b6b3a764000063ffffffff61352616565b925060035460001415611b9857611b89836103e863ffffffff61389316565b9250611b9860006103e86138d5565b60008311611c0757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656e64696e675661756c7456323a204d494e545f414d4f554e545f5a45524f604482015290519081900360640190fd5b611c1184846138d5565b611c1b6000613986565b6040805182815260208101859052815173ffffffffffffffffffffffffffffffffffffffff87169233927f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee929081900390910190a35050611c7a6140fc565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055919050565b60085473ffffffffffffffffffffffffffffffffffffffff1681565b60046020526000908152604090205481565b60076020526000908152604090205481565b600c5490565b600b5460009060ff16611d6457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905530600090815260046020526040902054611dc0670de0b6b3a7640000611414611db36113b1565b849063ffffffff61352616565b915060008211611e1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615b416022913960400191505060405180910390fd5b611e253082614157565b611e2e82613986565b600854611e589073ffffffffffffffffffffffffffffffffffffffff16848463ffffffff61421b16565b6040805183815260208101839052815173ffffffffffffffffffffffffffffffffffffffff86169233927f3f693fff038bb8a046aa76d9516190ac7444f7d69cf952c4cbdc086fdef2d6fc929081900390910190a350611c7a6140fc565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f81018490048402820184019092528181529291830182828015610a3a5780601f10610a0f57610100808354040283529160200191610a3a565b600b5460ff16611f9f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611fd16000613986565b611fd96140fc565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000610a4f338484613330565b600a5481565b600c818154811061202657fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6103e881565b600b5460ff166120c457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600a5460085461214e918391612128919061211c9073ffffffffffffffffffffffffffffffffffffffff166137f1565b9063ffffffff61389316565b60085473ffffffffffffffffffffffffffffffffffffffff16919063ffffffff61421b16565b50600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600e5481565b60095473ffffffffffffffffffffffffffffffffffffffff1681565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561220657600080fd5b505afa15801561221a573d6000803e3d6000fd5b505050506040513d602081101561223057600080fd5b505173ffffffffffffffffffffffffffffffffffffffff1633146122b557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661232657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff166123d1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615b196028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff1615612450576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615a386022913960400191505060405180910390fd5b60006124718273ffffffffffffffffffffffffffffffffffffffff166143f8565b9050600081116124e257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c656e64696e675661756c7456323a205a45524f5f414d4f554e540000000000604482015290519081900360640190fd5b60006125038373ffffffffffffffffffffffffffffffffffffffff166137f1565b9050600061251184836144ac565b90508373ffffffffffffffffffffffffffffffffffffffff167f05750bc9042b6da04fdebec7b024caed5c2e2b35c707bd1fde571f31cdaeb5668483604051808381526020018281526020019250505060405180910390a250505061214e6140fc565b670c7d713b49da000081565b600b5460ff166125f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff84166000908152600d6020526040902054610100900460ff1661269c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615b196028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600d602052604090205460ff1661271a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806159ef6023913960400191505060405180910390fd5b61272383613986565b60008473ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561276d57600080fd5b505af1158015612781573d6000803e3d6000fd5b505050506040513d602081101561279757600080fd5b505190506127a685858361452c565b506040517f86e4709b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201908152602482018690526060604483019081526064830185905233926386e4709b9289928992899289929091608401848480828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561285557600080fd5b505af1158015612869573d6000803e3d6000fd5b505050506128776000613986565b66038d7ea4c6800081048573ffffffffffffffffffffffffffffffffffffffff1663ad7a672f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156128c757600080fd5b505afa1580156128db573d6000803e3d6000fd5b505050506040513d60208110156128f157600080fd5b505111612949576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180615af06029913960400191505060405180910390fd5b506129526140fc565b5050600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555050565b6129b3878787878787877f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c961467a565b6129be878787613210565b50505050505050565b600560209081526000928352604080842090915290825290205481565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015612a4c57600080fd5b505afa158015612a60573d6000803e3d6000fd5b505050506040513d6020811015612a7657600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314612afb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff16612b6c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff16612c17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615b196028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff1615612c96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615a386022913960400191505060405180910390fd5b612cb58173ffffffffffffffffffffffffffffffffffffffff166143f8565b15612d2157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4c656e64696e675661756c7456323a204e4f545f454d50545900000000000000604482015290519081900360640190fd5b600c547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016000612d518361163d565b9050600c8281548110612d6057fe5b600091825260209091200154600c805473ffffffffffffffffffffffffffffffffffffffff9092169183908110612d9357fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600c805480612de657fe5b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff8516808352600d909152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690555190917f1f537c1571c0e7fa29083762436cadb3e57564c0f78e857e498cf428124c710e91a25050600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015612f4a57600080fd5b505afa158015612f5e573d6000803e3d6000fd5b505050506040513d6020811015612f7457600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314612ff957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661306a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055670c7d713b49da000081111561310957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4c656e64696e675661756c7456323a20494e56414c49445f53455454494e4700604482015290519081900360640190fd5b600f8190556040805182815290517f9d9cd27245b4e6b06dcf523ac57b6e851b934e199eee376313f906e94bfbfd559181900360200190a150600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600b5460ff166131e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611fd96140fc565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260056020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b60008184841115613328576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156132ed5781810151838201526020016132d5565b50505050905090810190601f16801561331a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b604080518082018252601b81527f496d7065726d61783a205452414e534645525f544f4f5f48494748000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff861660009081526004909152919091205461339e91839063ffffffff61327f16565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526004602052604080822093909355908416815220546133e0908263ffffffff6134b216565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526004602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000805b600c548110156134ae576000600c828154811061346657fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690506134a3613496826143f8565b849063ffffffff6134b216565b92505060010161344d565b5090565b60008282018381101561102357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008261353557506000610a53565b8282028284828161354257fe5b0414611023576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615acf6021913960400191505060405180910390fd5b600061102383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061491d565b600e546000908084111561370457600061362c61361f670de0b6b3a7640000611414600f54613613878b61389390919063ffffffff16565b9063ffffffff61352616565b869063ffffffff61389316565b905060006136488561211c84611414838b63ffffffff61352616565b905080156136f557600954604080517f345ef941000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163345ef941916004808301926020929190829003018186803b1580156136bb57600080fd5b505afa1580156136cf573d6000803e3d6000fd5b505050506040513d60208110156136e557600080fd5b505190506136f381836138d5565b505b50600e8190559150610a539050565b83915050610a53565b81516137209060009060208501906158c9565b5080516137349060019060208401906158c9565b506040514690806052615a7d82396040805191829003605201822086516020978801208383018352600184527f310000000000000000000000000000000000000000000000000000000000000093880193909352815180880191909152808201929092527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606083015260808201939093523060a0808301919091528351808303909101815260c090910190925250805192019190912060065550565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905160009173ffffffffffffffffffffffffffffffffffffffff8416916370a0823191602480820192602092909190829003018186803b15801561386157600080fd5b505afa158015613875573d6000803e3d6000fd5b505050506040513d602081101561388b57600080fd5b505192915050565b600061102383836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f770081525061327f565b6003546138e8908263ffffffff6134b216565b60035573ffffffffffffffffffffffffffffffffffffffff8216600090815260046020526040902054613921908263ffffffff6134b216565b73ffffffffffffffffffffffffffffffffffffffff831660008181526004602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600c5460408051828152602080840282010190915260609180156139c457816020015b6139b1615943565b8152602001906001900390816139a95790505b50600c5490915060005b600c54811015613abf57600d6000600c83815481106139e957fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff16613a4c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190613ab7565b600c54600090613a62908463ffffffff61389316565b9050613a9c600c8381548110613a7457fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff163061499c565b8482840381518110613aaa57fe5b6020026020010181905250505b6001016139ce565b50600854600090613ae59073ffffffffffffffffffffffffffffffffffffffff166137f1565b905060005b82811015613b49576000613b10858381518110613b0357fe5b6020026020010151614f2b565b8651879085908110613b1e57fe5b60209081029190910101919091529050613b3e838263ffffffff6134b216565b925050600101613aea565b50613b7584604051806060016040528060268152602001615c026026913983919063ffffffff61327f16565b905081613b84575050506140f9565b60005b60018303811015613c5c5760005b816001850303811015613c5357613bde858260010181518110613bb457fe5b6020026020010151868381518110613bc857fe5b6020026020010151614f9090919063ffffffff16565b613c4b57613bea615943565b858281518110613bf657fe5b60200260200101519050858260010181518110613c0f57fe5b6020026020010151868381518110613c2357fe5b602002602001018190525080868360010181518110613c3e57fe5b6020026020010181905250505b600101613b95565b50600101613b87565b508160015b83811015613e38576000858281518110613c7757fe5b6020026020010151610140015190506000809050606083604051908082528060200260200182016040528015613cb7578160200160208202803883390190505b50905082613cca57839450505050613e38565b60005b84811015613d675783898281518110613ce257fe5b6020026020010151610140015111613cf957613d67565b613d1f848a8381518110613d0957fe5b6020026020010151614f9e90919063ffffffff16565b828281518110613d2b57fe5b602002602001018181525050613d5d828281518110613d4657fe5b6020026020010151846134b290919063ffffffff16565b9250600101613ccd565b5085821115613d7b57839450505050613e38565b60005b84811015613e2857818181518110613d9257fe5b602002602001015160001415613da757613e20565b613de0828281518110613db657fe5b60200260200101518a8381518110613dca57fe5b60200260200101516150f490919063ffffffff16565b898281518110613dec57fe5b6020026020010181905250613e1d828281518110613e0657fe5b60200260200101518861389390919063ffffffff16565b96505b600101613d7e565b505060019092019150613c619050565b50600082815b83811015613e6f57613e65613496888381518110613e5857fe5b602002602001015161512c565b9250600101613e3e565b5060005b83811015613ef0576000808411613e8a5785613ea1565b613ea184611414856136138c8781518110613e5857fe5b905085811115613eae5750845b613ebe81898481518110613dca57fe5b888381518110613eca57fe5b6020908102919091010152613ee5868263ffffffff61389316565b955050600101613e73565b5060005b85811015613fbb57868181518110613f0857fe5b602002602001015160800151878281518110613f2057fe5b602002602001015160a001511015613fb3576000613f75888381518110613f4357fe5b602002602001015160a00151898481518110613f5b57fe5b60200260200101516080015161389390919063ffffffff16565b9050613fb0888381518110613f8657fe5b602002602001015160000151828a8581518110613f9f57fe5b602002602001015160200151615149565b50505b600101613ef4565b50614008876040518060600160405280602b8152602001615b63602b9139600854613ffb9073ffffffffffffffffffffffffffffffffffffffff166137f1565b919063ffffffff61327f16565b935060005b858110156140f15786818151811061402157fe5b60200260200101516080015187828151811061403957fe5b602002602001015160a0015111156140e957600061408e88838151811061405c57fe5b60200260200101516080015189848151811061407457fe5b602002602001015160a0015161389390919063ffffffff16565b90508581111561409b5750845b6140ab868263ffffffff61389316565b95506140e68883815181106140bc57fe5b602002602001015160000151828a85815181106140d557fe5b60200260200101516020015161452c565b50505b60010161400d565b505050505050505b50565b60085461411e9073ffffffffffffffffffffffffffffffffffffffff166137f1565b600a81905560408051918252517f8a0df8ef054fae2c3d2d19a7b322e864870cc9fd3cb07fb9526309c596244bf49181900360200190a1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526004602052604090205461418d908263ffffffff61389316565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600460205260409020556003546141c6908263ffffffff61389316565b60035560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000178152925182516000946060949389169392918291908083835b602083106142f157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016142b4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614353576040519150601f19603f3d011682016040523d82523d6000602084013e614358565b606091505b5091509150818015614386575080511580614386575080806020019051602081101561438357600080fd5b50515b6143f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f21736166655472616e7366657200000000000000000000000000000000000000604482015290519081900360640190fd5b5050505050565b6000610a53828373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561447b57600080fd5b505afa15801561448f573d6000803e3d6000fd5b505050506040513d60208110156144a557600080fd5b5051615167565b600061102383838573ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156144fb57600080fd5b505af115801561450f573d6000803e3d6000fd5b505050506040513d602081101561452557600080fd5b50516151fc565b600061454a8261141485670de0b6b3a764000063ffffffff61352616565b90508061455957506000611023565b6008546145839073ffffffffffffffffffffffffffffffffffffffff16858563ffffffff61421b16565b604080517f6a627842000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff861691636a6278429160248083019260209291908290030181600087803b1580156145f157600080fd5b505af1158015614605573d6000803e3d6000fd5b505050506040513d602081101561461b57600080fd5b50516040805185815260208101839052815192935073ffffffffffffffffffffffffffffffffffffffff8716927f20541ba081e1e2ed9b41701070442c1fe618b0fec04825ba790aea8373f4e237929181900390910190a29392505050565b428510156146e957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496d7065726d61783a2045585049524544000000000000000000000000000000604482015290519081900360640190fd5b60065473ffffffffffffffffffffffffffffffffffffffff808a1660008181526007602090815260408083208054600180820190925582518085018a905280840196909652958e166060860152608085018d905260a085019590955260c08085018c90528151808603909101815260e0850182528051908301207f19010000000000000000000000000000000000000000000000000000000000006101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff8a166101828501526101a284018990526101c28401889052519193926101e2808201937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081019281900390910190855afa15801561482b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116158015906148a657508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b61491157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496d7065726d61783a20494e56414c49445f5349474e41545552450000000000604482015290519081900360640190fd5b50505050505050505050565b60008183614986576040517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482018181528351602484015283519092839260449091019190850190808383600083156132ed5781810151838201526020016132d5565b50600083858161499257fe5b0495945050505050565b6149a4615943565b8273ffffffffffffffffffffffffffffffffffffffff1663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156149ec57600080fd5b505af1158015614a00573d6000803e3d6000fd5b5050505060008373ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b158015614a4e57600080fd5b505af1158015614a62573d6000803e3d6000fd5b505050506040513d6020811015614a7857600080fd5b5051604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905191925060009173ffffffffffffffffffffffffffffffffffffffff8716916318160ddd916004808301926020929190829003018186803b158015614ae657600080fd5b505afa158015614afa573d6000803e3d6000fd5b505050506040513d6020811015614b1057600080fd5b5051604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301529151929350600092918816916370a0823191602480820192602092909190829003018186803b158015614b8857600080fd5b505afa158015614b9c573d6000803e3d6000fd5b505050506040513d6020811015614bb257600080fd5b505190506000614bc8838363ffffffff61389316565b90506040518061016001604052808873ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018873ffffffffffffffffffffffffffffffffffffffff166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015614c3e57600080fd5b505afa158015614c52573d6000803e3d6000fd5b505050506040513d6020811015614c6857600080fd5b50518152602001614c8b670de0b6b3a7640000611414858963ffffffff61352616565b8152602001614cac670de0b6b3a7640000611414868963ffffffff61352616565b8152602001614ccd670de0b6b3a7640000611414868963ffffffff61352616565b81526020018873ffffffffffffffffffffffffffffffffffffffff166391b427456040518163ffffffff1660e01b815260040160206040518083038186803b158015614d1857600080fd5b505afa158015614d2c573d6000803e3d6000fd5b505050506040513d6020811015614d4257600080fd5b50518152604080517f1aebf12f000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692631aebf12f9260048083019392829003018186803b158015614dae57600080fd5b505afa158015614dc2573d6000803e3d6000fd5b505050506040513d6020811015614dd857600080fd5b50518152604080517f4322b714000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692634322b7149260048083019392829003018186803b158015614e4457600080fd5b505afa158015614e58573d6000803e3d6000fd5b505050506040513d6020811015614e6e57600080fd5b50518152604080517f5b2b9d1a000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692635b2b9d1a9260048083019392829003018186803b158015614eda57600080fd5b505afa158015614eee573d6000803e3d6000fd5b505050506040513d6020811015614f0457600080fd5b5051815260006020909101529450614f1b856153e5565b6101408601525050505092915050565b614f33615943565b60008260400151614f438461512c565b1015614f5457508190506000614f8b565b6000614f67846040015161211c8661512c565b90506000614f798560a00151836154e5565b9050614f8585826154fb565b93509150505b915091565b610140908101519101511190565b600080821161500e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4552524f523a2072617465203d20300000000000000000000000000000000000604482015290519081900360640190fd5b82610140015182111561508257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552524f523a205441524745542052415445203e204341434845442052415445604482015290519081900360640190fd5b600061508e84846155bb565b905060006150b582611414670de0b6b3a7640000886040015161352690919063ffffffff16565b90506150c08561512c565b8110156150d257600092505050610a53565b6150eb6150de8661512c565b829063ffffffff61389316565b95945050505050565b6150fc615943565b60a0830151615111908363ffffffff6134b216565b60a084015261511f836153e5565b6101408401525090919050565b6000610a538260a0015183606001516134b290919063ffffffff16565b600061515f846151598585615723565b846151fc565b949350505050565b6000808373ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156151b257600080fd5b505af11580156151c6573d6000803e3d6000fd5b505050506040513d60208110156151dc57600080fd5b5051905061515f670de0b6b3a7640000611414858463ffffffff61352616565b600061521a670de0b6b3a7640000611414858563ffffffff61352616565b90508061522957506000611023565b60008473ffffffffffffffffffffffffffffffffffffffff1663ad7a672f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561527157600080fd5b505afa158015615285573d6000803e3d6000fd5b505050506040513d602081101561529b57600080fd5b50519050808211156152c6576152c38361141483670de0b6b3a764000063ffffffff61352616565b93505b6152ed73ffffffffffffffffffffffffffffffffffffffff8616868663ffffffff61421b16565b604080517f95a2251f000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8716916395a2251f9160248083019260209291908290030181600087803b15801561535b57600080fd5b505af115801561536f573d6000803e3d6000fd5b505050506040513d602081101561538557600080fd5b50516040805182815260208101879052815192945073ffffffffffffffffffffffffffffffffffffffff8816927f8d69ef09150dd510133bc8e54e6ca115e8cf3370ea49a4a5ae56a1cdefc835e9929181900390910190a2509392505050565b6000806153f183615731565b905060006154188460e00151611414670de0b6b3a76400008561352690919063ffffffff16565b905060008460e0015183101561542f5750806154b0565b60006154766154538760e00151670de0b6b3a764000061389390919063ffffffff16565b611414670de0b6b3a76400006136138a60e001518961389390919063ffffffff16565b90506154ac670de0b6b3a76400006154a0611db360018a610120015161389390919063ffffffff16565b9063ffffffff6134b216565b9150505b6150eb670de0b6b3a764000061141484613613670de0b6b3a76400006114146154d88c615771565b889063ffffffff61352616565b60008183106154f45781611023565b5090919050565b615503615943565b600061552f8460400151604051806060016040528060238152602001615a5a60239139613ffb8761512c565b90508083111561558a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180615b8e602e913960400191505060405180910390fd5b60a084015161559f908463ffffffff61389316565b60a08501526155ad846153e5565b610140850152509192915050565b60006155c683615771565b821161561f57615618670de0b6b3a76400006114148560e00151613613615613670de0b6b3a76400006136136155fb8b615771565b6114148b670de0b6b3a764000063ffffffff61352616565b6157c9565b9050610a53565b61012083015160009061563990600163ffffffff61389316565b90506000615665670de0b6b3a764000061211c8761012001518860e0015161352690919063ffffffff16565b905060006156ba61567587615771565b6114146156978960e00151670de0b6b3a764000061389390919063ffffffff16565b613613670de0b6b3a76400006114148c60e001518c61352690919063ffffffff16565b905060006156ff615613670de0b6b3a76400006136136156e36004828a8963ffffffff61352616565b6154a0670de0b6b3a76400006114148a8063ffffffff61352616565b905061571860026114148681858863ffffffff6134b216565b979650505050505050565b60006110238383600061581a565b60008061573d8361512c565b90508061574e5760009150506116f8565b61102381611414670de0b6b3a7640000866040015161352690919063ffffffff16565b6000610a53670de0b6b3a76400006114146157a2856101000151670de0b6b3a764000061389390919063ffffffff16565b613613670de0b6b3a76400006114148860c001518960e0015161352690919063ffffffff16565b6000600382111561580c575080600160028204015b81811015615806578091506002818285816157f557fe5b0401816157fe57fe5b0490506157de565b506116f8565b81156116f857506001919050565b6000806158398461141487670de0b6b3a764000063ffffffff61352616565b9050600061584e82600163ffffffff6134b216565b90508315615890576000615874670de0b6b3a7640000611414848963ffffffff61352616565b9050868111156158845782615886565b815b9350505050611023565b60006158ae670de0b6b3a7640000611414858963ffffffff61352616565b9050868110156158be5781615886565b829350505050611023565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061590a57805160ff1916838001178555615937565b82800160010185558215615937579182015b8281111561593757825182559160200191906001019061591c565b506134ae9291506159b3565b604051806101600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61143291905b808211156134ae57600081556001016159b956fe4c656e64696e675661756c7456323a20424f52524f5741424c455f4558495354534c656e64696e675661756c7456323a20424f52524f5741424c455f44495341424c45444c656e64696e675661756c7456323a204d41585f424f52524f5741424c45535f4c454e4754484c656e64696e675661756c7456323a20424f52524f5741424c455f454e41424c45444552524f523a204e4547415449564520415641494c41424c45204c4951554944495459454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774c656e64696e675661756c7456323a20494e434f4e56454e49454e545f5245414c4c4f434154494f4e4c656e64696e675661756c7456323a20424f52524f5741424c455f444f45534e545f4558495354534c656e64696e675661756c7456323a2052454445454d5f414d4f554e545f5a45524f4c656e64696e675661756c7456323a204e4547415449564520414d4f554e5420544f20414c4c4f434154454552524f523a204445414c4c4f4341544520414d4f554e54203e20415641494c41424c45204c49515549444954594c656e64696e675661756c7456323a20494e56414c49445f554e4445524c59494e474c656e64696e675661756c7456323a20424f52524f5741424c455f4e4f545f464f554e444c656e64696e675661756c7456323a20494e53554646494349454e545f4c4951554944495459a265627a7a72315820d4530361f465d6cbe6c6e00b8d094ff861a795afcbde017b35701a32b0e2f7e064736f6c63430005100032
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102ad5760003560e01c80637ecebe001161017b578063be340e32116100d8578063d505accf1161008c578063eb1ea9f411610071578063eb1ea9f41461093e578063fca7820b14610971578063fff6cae91461098e576102ad565b8063d505accf146108a5578063dd62ed3e14610903576102ad565b8063c5b7e148116100bd578063c5b7e148146107d8578063c72f3fbb1461080b578063ccc9564a14610813576102ad565b8063be340e32146107c8578063c45a0155146107d0576102ad565b8063a9059cbb1161012f578063ade37c1311610114578063ade37c1314610770578063ba9a7a561461078d578063bc25cf7714610795576102ad565b8063a9059cbb1461072f578063ad7a672f14610768576102ad565b806395a2251f1161016057806395a2251f146106ec57806395d89b411461071f57806398084db714610727576102ad565b80637ecebe00146106b1578063821beaf5146106e4576102ad565b80633ba0b9a91161022957806352ac4b02116101dd5780636a627842116101c25780636a6278421461061a5780636f307dc31461064d57806370a082311461067e576102ad565b806352ac4b0214610599578063579ce367146105cc576102ad565b80634643ec581161020e5780634643ec581461047f5780634a5d316c1461055e578063506fb08614610566576102ad565b80633ba0b9a91461046f5780634322b71414610477576102ad565b806323b872dd11610280578063313ce56711610265578063313ce5671461041657806332fe35fd146104345780633644e51514610467576102ad565b806323b872dd146103cb57806330adf81f1461040e576102ad565b806306fdde03146102b2578063095ea7b31461032f57806318160ddd1461037c578063218b5b8114610396575b600080fd5b6102ba610996565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102f45781810151838201526020016102dc565b50505050905090810190601f1680156103215780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103686004803603604081101561034557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610a42565b604080519115158252519081900360200190f35b610384610a59565b60408051918252519081900360200190f35b6103c9600480360360208110156103ac57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610a5f565b005b610368600480360360608110156103e157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610f15565b61038461102a565b61041e61104e565b6040805160ff9092168252519081900360200190f35b6103c96004803603602081101561044a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611057565b6103846113ab565b6103846113b1565b610384611435565b6103c96004803603606081101561049557600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156104cd57600080fd5b8201836020820111156104df57600080fd5b8035906020019184600183028401116401000000008311171561050157600080fd5b91939092909160208101903564010000000081111561051f57600080fd5b82018360208201111561053157600080fd5b8035906020019184600183028401116401000000008311171561055357600080fd5b50909250905061143b565b6103c961158c565b6103846004803603602081101561057c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661163d565b6103c9600480360360208110156105af57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166116fd565b6105ff600480360360208110156105e257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a4d565b60408051921515835290151560208301528051918290030190f35b6103846004803603602081101561063057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a6b565b610655611caa565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103846004803603602081101561069457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611cc6565b610384600480360360208110156106c757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611cd8565b610384611cea565b6103846004803603602081101561070257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611cf0565b6102ba611eb6565b6103c9611f2e565b6103686004803603604081101561074557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612006565b610384612013565b6106556004803603602081101561078657600080fd5b5035612019565b61038461204d565b6103c9600480360360208110156107ab57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612053565b61038461217c565b610655612182565b6103c9600480360360208110156107ee57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661219e565b610384612574565b6103c96004803603606081101561082957600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561086657600080fd5b82018360208201111561087857600080fd5b8035906020019184600183028401116401000000008311171561089a57600080fd5b509092509050612580565b6103c9600480360360e08110156108bb57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135612983565b6103846004803603604081101561091957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166129c7565b6103c96004803603602081101561095457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166129e4565b6103c96004803603602081101561098757600080fd5b5035612ee2565b6103c961316f565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f81018490048402820184019092528181529291830182828015610a3a5780601f10610a0f57610100808354040283529160200191610a3a565b820191906000526020600020905b815481529060010190602001808311610a1d57829003601f168201915b505050505081565b6000610a4f338484613210565b5060015b92915050565b60035481565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015610ac757600080fd5b505afa158015610adb573d6000803e3d6000fd5b505050506040513d6020811015610af157600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314610b7657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff16610be757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600854604080517f6f307dc3000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff92831692841691636f307dc3916004808301926020929190829003018186803b158015610c7c57600080fd5b505afa158015610c90573d6000803e3d6000fd5b505050506040513d6020811015610ca657600080fd5b505173ffffffffffffffffffffffffffffffffffffffff1614610d14576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615bbc6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff1615610d98576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806159ce6021913960400191505060405180910390fd5b600c54600a11610df3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180615a126026913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff90911661010017166001908117909155600c8054918201815583527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055517f3b94e6c56297c3ab2913d31d1c1adf8279146dbfb5624cc473e7af7a22d9c8469190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b73ffffffffffffffffffffffffffffffffffffffff831660009081526005602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461101457604080518082018252601e81527f496d7065726d61783a205452414e534645525f4e4f545f414c4c4f574544000060208083019190915273ffffffffffffffffffffffffffffffffffffffff87166000908152600582528381203382529091529190912054610fe291849063ffffffff61327f16565b73ffffffffffffffffffffffffffffffffffffffff851660009081526005602090815260408083203384529091529020555b61101f848484613330565b5060015b9392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025460ff1681565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b1580156110bf57600080fd5b505afa1580156110d3573d6000803e3d6000fd5b505050506040513d60208110156110e957600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16331461116e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff166111df57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff1661128a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615b196028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff1615611309576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615a386022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f54ba33e4b0861b4d81b3384c3b5130b25b55df191223d9e48b317dc289fac3a99190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60065481565b600354600090816113d26113c3613449565b600a549063ffffffff6134b216565b90508115806113df575080155b156113f657670de0b6b3a764000092505050611432565b60006114208361141484670de0b6b3a764000063ffffffff61352616565b9063ffffffff61359916565b905061142c81846135db565b93505050505b90565b600f5481565b60095473ffffffffffffffffffffffffffffffffffffffff1633146114c157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b61153484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152925086915085908190840183828082843760009201919091525061370d92505050565b5050600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94909416939093179092555050670de0b6b3a7640000600e55565b60095473ffffffffffffffffffffffffffffffffffffffff161561161157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496d7065726d61783a20464143544f52595f414c52454144595f534554000000604482015290519081900360640190fd5b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055565b6000805b600c548110156116a6578273ffffffffffffffffffffffffffffffffffffffff16600c828154811061166f57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141561169e5790506116f8565b600101611641565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180615bde6024913960400191505060405180910390fd5b919050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561176557600080fd5b505afa158015611779573d6000803e3d6000fd5b505050506040513d602081101561178f57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16331461181457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661188557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff16611930576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615b196028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff166119ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806159ef6023913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600d602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f6149acc591caf5f3d506cb615abb39ea3847de4e2aa83f4382531de216bdc6809190a250600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600d6020526000908152604090205460ff8082169161010090041682565b600b5460009060ff16611adf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600854600090611b2c9073ffffffffffffffffffffffffffffffffffffffff166137f1565b90506000611b45600a548361389390919063ffffffff16565b9050611b6a611b526113b1565b61141483670de0b6b3a764000063ffffffff61352616565b925060035460001415611b9857611b89836103e863ffffffff61389316565b9250611b9860006103e86138d5565b60008311611c0757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656e64696e675661756c7456323a204d494e545f414d4f554e545f5a45524f604482015290519081900360640190fd5b611c1184846138d5565b611c1b6000613986565b6040805182815260208101859052815173ffffffffffffffffffffffffffffffffffffffff87169233927f2f00e3cdd69a77be7ed215ec7b2a36784dd158f921fca79ac29deffa353fe6ee929081900390910190a35050611c7a6140fc565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055919050565b60085473ffffffffffffffffffffffffffffffffffffffff1681565b60046020526000908152604090205481565b60076020526000908152604090205481565b600c5490565b600b5460009060ff16611d6457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905530600090815260046020526040902054611dc0670de0b6b3a7640000611414611db36113b1565b849063ffffffff61352616565b915060008211611e1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615b416022913960400191505060405180910390fd5b611e253082614157565b611e2e82613986565b600854611e589073ffffffffffffffffffffffffffffffffffffffff16848463ffffffff61421b16565b6040805183815260208101839052815173ffffffffffffffffffffffffffffffffffffffff86169233927f3f693fff038bb8a046aa76d9516190ac7444f7d69cf952c4cbdc086fdef2d6fc929081900390910190a350611c7a6140fc565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f81018490048402820184019092528181529291830182828015610a3a5780601f10610a0f57610100808354040283529160200191610a3a565b600b5460ff16611f9f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611fd16000613986565b611fd96140fc565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000610a4f338484613330565b600a5481565b600c818154811061202657fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6103e881565b600b5460ff166120c457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600a5460085461214e918391612128919061211c9073ffffffffffffffffffffffffffffffffffffffff166137f1565b9063ffffffff61389316565b60085473ffffffffffffffffffffffffffffffffffffffff16919063ffffffff61421b16565b50600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600e5481565b60095473ffffffffffffffffffffffffffffffffffffffff1681565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b15801561220657600080fd5b505afa15801561221a573d6000803e3d6000fd5b505050506040513d602081101561223057600080fd5b505173ffffffffffffffffffffffffffffffffffffffff1633146122b557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661232657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff166123d1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615b196028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff1615612450576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615a386022913960400191505060405180910390fd5b60006124718273ffffffffffffffffffffffffffffffffffffffff166143f8565b9050600081116124e257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4c656e64696e675661756c7456323a205a45524f5f414d4f554e540000000000604482015290519081900360640190fd5b60006125038373ffffffffffffffffffffffffffffffffffffffff166137f1565b9050600061251184836144ac565b90508373ffffffffffffffffffffffffffffffffffffffff167f05750bc9042b6da04fdebec7b024caed5c2e2b35c707bd1fde571f31cdaeb5668483604051808381526020018281526020019250505060405180910390a250505061214e6140fc565b670c7d713b49da000081565b600b5460ff166125f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff84166000908152600d6020526040902054610100900460ff1661269c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615b196028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166000908152600d602052604090205460ff1661271a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806159ef6023913960400191505060405180910390fd5b61272383613986565b60008473ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561276d57600080fd5b505af1158015612781573d6000803e3d6000fd5b505050506040513d602081101561279757600080fd5b505190506127a685858361452c565b506040517f86e4709b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201908152602482018690526060604483019081526064830185905233926386e4709b9289928992899289929091608401848480828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561285557600080fd5b505af1158015612869573d6000803e3d6000fd5b505050506128776000613986565b66038d7ea4c6800081048573ffffffffffffffffffffffffffffffffffffffff1663ad7a672f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156128c757600080fd5b505afa1580156128db573d6000803e3d6000fd5b505050506040513d60208110156128f157600080fd5b505111612949576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180615af06029913960400191505060405180910390fd5b506129526140fc565b5050600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555050565b6129b3878787878787877f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c961467a565b6129be878787613210565b50505050505050565b600560209081526000928352604080842090915290825290205481565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015612a4c57600080fd5b505afa158015612a60573d6000803e3d6000fd5b505050506040513d6020811015612a7657600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314612afb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff16612b6c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905573ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040902054610100900460ff16612c17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615b196028913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604090205460ff1615612c96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615a386022913960400191505060405180910390fd5b612cb58173ffffffffffffffffffffffffffffffffffffffff166143f8565b15612d2157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4c656e64696e675661756c7456323a204e4f545f454d50545900000000000000604482015290519081900360640190fd5b600c547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016000612d518361163d565b9050600c8281548110612d6057fe5b600091825260209091200154600c805473ffffffffffffffffffffffffffffffffffffffff9092169183908110612d9357fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600c805480612de657fe5b6000828152602080822083017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925573ffffffffffffffffffffffffffffffffffffffff8516808352600d909152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690555190917f1f537c1571c0e7fa29083762436cadb3e57564c0f78e857e498cf428124c710e91a25050600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015612f4a57600080fd5b505afa158015612f5e573d6000803e3d6000fd5b505050506040513d6020811015612f7457600080fd5b505173ffffffffffffffffffffffffffffffffffffffff163314612ff957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c656e64696e675661756c7456323a20554e415554484f52495a454400000000604482015290519081900360640190fd5b600b5460ff1661306a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055670c7d713b49da000081111561310957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4c656e64696e675661756c7456323a20494e56414c49445f53455454494e4700604482015290519081900360640190fd5b600f8190556040805182815290517f9d9cd27245b4e6b06dcf523ac57b6e851b934e199eee376313f906e94bfbfd559181900360200190a150600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600b5460ff166131e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496d7065726d61783a205245454e544552454400000000000000000000000000604482015290519081900360640190fd5b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611fd96140fc565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260056020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b60008184841115613328576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156132ed5781810151838201526020016132d5565b50505050905090810190601f16801561331a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b604080518082018252601b81527f496d7065726d61783a205452414e534645525f544f4f5f48494748000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff861660009081526004909152919091205461339e91839063ffffffff61327f16565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526004602052604080822093909355908416815220546133e0908263ffffffff6134b216565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526004602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000805b600c548110156134ae576000600c828154811061346657fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1690506134a3613496826143f8565b849063ffffffff6134b216565b92505060010161344d565b5090565b60008282018381101561102357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008261353557506000610a53565b8282028284828161354257fe5b0414611023576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615acf6021913960400191505060405180910390fd5b600061102383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061491d565b600e546000908084111561370457600061362c61361f670de0b6b3a7640000611414600f54613613878b61389390919063ffffffff16565b9063ffffffff61352616565b869063ffffffff61389316565b905060006136488561211c84611414838b63ffffffff61352616565b905080156136f557600954604080517f345ef941000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163345ef941916004808301926020929190829003018186803b1580156136bb57600080fd5b505afa1580156136cf573d6000803e3d6000fd5b505050506040513d60208110156136e557600080fd5b505190506136f381836138d5565b505b50600e8190559150610a539050565b83915050610a53565b81516137209060009060208501906158c9565b5080516137349060019060208401906158c9565b506040514690806052615a7d82396040805191829003605201822086516020978801208383018352600184527f310000000000000000000000000000000000000000000000000000000000000093880193909352815180880191909152808201929092527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606083015260808201939093523060a0808301919091528351808303909101815260c090910190925250805192019190912060065550565b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905160009173ffffffffffffffffffffffffffffffffffffffff8416916370a0823191602480820192602092909190829003018186803b15801561386157600080fd5b505afa158015613875573d6000803e3d6000fd5b505050506040513d602081101561388b57600080fd5b505192915050565b600061102383836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f770081525061327f565b6003546138e8908263ffffffff6134b216565b60035573ffffffffffffffffffffffffffffffffffffffff8216600090815260046020526040902054613921908263ffffffff6134b216565b73ffffffffffffffffffffffffffffffffffffffff831660008181526004602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600c5460408051828152602080840282010190915260609180156139c457816020015b6139b1615943565b8152602001906001900390816139a95790505b50600c5490915060005b600c54811015613abf57600d6000600c83815481106139e957fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff16835282019290925260400190205460ff16613a4c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190613ab7565b600c54600090613a62908463ffffffff61389316565b9050613a9c600c8381548110613a7457fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff163061499c565b8482840381518110613aaa57fe5b6020026020010181905250505b6001016139ce565b50600854600090613ae59073ffffffffffffffffffffffffffffffffffffffff166137f1565b905060005b82811015613b49576000613b10858381518110613b0357fe5b6020026020010151614f2b565b8651879085908110613b1e57fe5b60209081029190910101919091529050613b3e838263ffffffff6134b216565b925050600101613aea565b50613b7584604051806060016040528060268152602001615c026026913983919063ffffffff61327f16565b905081613b84575050506140f9565b60005b60018303811015613c5c5760005b816001850303811015613c5357613bde858260010181518110613bb457fe5b6020026020010151868381518110613bc857fe5b6020026020010151614f9090919063ffffffff16565b613c4b57613bea615943565b858281518110613bf657fe5b60200260200101519050858260010181518110613c0f57fe5b6020026020010151868381518110613c2357fe5b602002602001018190525080868360010181518110613c3e57fe5b6020026020010181905250505b600101613b95565b50600101613b87565b508160015b83811015613e38576000858281518110613c7757fe5b6020026020010151610140015190506000809050606083604051908082528060200260200182016040528015613cb7578160200160208202803883390190505b50905082613cca57839450505050613e38565b60005b84811015613d675783898281518110613ce257fe5b6020026020010151610140015111613cf957613d67565b613d1f848a8381518110613d0957fe5b6020026020010151614f9e90919063ffffffff16565b828281518110613d2b57fe5b602002602001018181525050613d5d828281518110613d4657fe5b6020026020010151846134b290919063ffffffff16565b9250600101613ccd565b5085821115613d7b57839450505050613e38565b60005b84811015613e2857818181518110613d9257fe5b602002602001015160001415613da757613e20565b613de0828281518110613db657fe5b60200260200101518a8381518110613dca57fe5b60200260200101516150f490919063ffffffff16565b898281518110613dec57fe5b6020026020010181905250613e1d828281518110613e0657fe5b60200260200101518861389390919063ffffffff16565b96505b600101613d7e565b505060019092019150613c619050565b50600082815b83811015613e6f57613e65613496888381518110613e5857fe5b602002602001015161512c565b9250600101613e3e565b5060005b83811015613ef0576000808411613e8a5785613ea1565b613ea184611414856136138c8781518110613e5857fe5b905085811115613eae5750845b613ebe81898481518110613dca57fe5b888381518110613eca57fe5b6020908102919091010152613ee5868263ffffffff61389316565b955050600101613e73565b5060005b85811015613fbb57868181518110613f0857fe5b602002602001015160800151878281518110613f2057fe5b602002602001015160a001511015613fb3576000613f75888381518110613f4357fe5b602002602001015160a00151898481518110613f5b57fe5b60200260200101516080015161389390919063ffffffff16565b9050613fb0888381518110613f8657fe5b602002602001015160000151828a8581518110613f9f57fe5b602002602001015160200151615149565b50505b600101613ef4565b50614008876040518060600160405280602b8152602001615b63602b9139600854613ffb9073ffffffffffffffffffffffffffffffffffffffff166137f1565b919063ffffffff61327f16565b935060005b858110156140f15786818151811061402157fe5b60200260200101516080015187828151811061403957fe5b602002602001015160a0015111156140e957600061408e88838151811061405c57fe5b60200260200101516080015189848151811061407457fe5b602002602001015160a0015161389390919063ffffffff16565b90508581111561409b5750845b6140ab868263ffffffff61389316565b95506140e68883815181106140bc57fe5b602002602001015160000151828a85815181106140d557fe5b60200260200101516020015161452c565b50505b60010161400d565b505050505050505b50565b60085461411e9073ffffffffffffffffffffffffffffffffffffffff166137f1565b600a81905560408051918252517f8a0df8ef054fae2c3d2d19a7b322e864870cc9fd3cb07fb9526309c596244bf49181900360200190a1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526004602052604090205461418d908263ffffffff61389316565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600460205260409020556003546141c6908263ffffffff61389316565b60035560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000178152925182516000946060949389169392918291908083835b602083106142f157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016142b4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614353576040519150601f19603f3d011682016040523d82523d6000602084013e614358565b606091505b5091509150818015614386575080511580614386575080806020019051602081101561438357600080fd5b50515b6143f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f21736166655472616e7366657200000000000000000000000000000000000000604482015290519081900360640190fd5b5050505050565b6000610a53828373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561447b57600080fd5b505afa15801561448f573d6000803e3d6000fd5b505050506040513d60208110156144a557600080fd5b5051615167565b600061102383838573ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156144fb57600080fd5b505af115801561450f573d6000803e3d6000fd5b505050506040513d602081101561452557600080fd5b50516151fc565b600061454a8261141485670de0b6b3a764000063ffffffff61352616565b90508061455957506000611023565b6008546145839073ffffffffffffffffffffffffffffffffffffffff16858563ffffffff61421b16565b604080517f6a627842000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff861691636a6278429160248083019260209291908290030181600087803b1580156145f157600080fd5b505af1158015614605573d6000803e3d6000fd5b505050506040513d602081101561461b57600080fd5b50516040805185815260208101839052815192935073ffffffffffffffffffffffffffffffffffffffff8716927f20541ba081e1e2ed9b41701070442c1fe618b0fec04825ba790aea8373f4e237929181900390910190a29392505050565b428510156146e957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496d7065726d61783a2045585049524544000000000000000000000000000000604482015290519081900360640190fd5b60065473ffffffffffffffffffffffffffffffffffffffff808a1660008181526007602090815260408083208054600180820190925582518085018a905280840196909652958e166060860152608085018d905260a085019590955260c08085018c90528151808603909101815260e0850182528051908301207f19010000000000000000000000000000000000000000000000000000000000006101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff8a166101828501526101a284018990526101c28401889052519193926101e2808201937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081019281900390910190855afa15801561482b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116158015906148a657508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b61491157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496d7065726d61783a20494e56414c49445f5349474e41545552450000000000604482015290519081900360640190fd5b50505050505050505050565b60008183614986576040517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482018181528351602484015283519092839260449091019190850190808383600083156132ed5781810151838201526020016132d5565b50600083858161499257fe5b0495945050505050565b6149a4615943565b8273ffffffffffffffffffffffffffffffffffffffff1663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156149ec57600080fd5b505af1158015614a00573d6000803e3d6000fd5b5050505060008373ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b158015614a4e57600080fd5b505af1158015614a62573d6000803e3d6000fd5b505050506040513d6020811015614a7857600080fd5b5051604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905191925060009173ffffffffffffffffffffffffffffffffffffffff8716916318160ddd916004808301926020929190829003018186803b158015614ae657600080fd5b505afa158015614afa573d6000803e3d6000fd5b505050506040513d6020811015614b1057600080fd5b5051604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301529151929350600092918816916370a0823191602480820192602092909190829003018186803b158015614b8857600080fd5b505afa158015614b9c573d6000803e3d6000fd5b505050506040513d6020811015614bb257600080fd5b505190506000614bc8838363ffffffff61389316565b90506040518061016001604052808873ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018873ffffffffffffffffffffffffffffffffffffffff166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b158015614c3e57600080fd5b505afa158015614c52573d6000803e3d6000fd5b505050506040513d6020811015614c6857600080fd5b50518152602001614c8b670de0b6b3a7640000611414858963ffffffff61352616565b8152602001614cac670de0b6b3a7640000611414868963ffffffff61352616565b8152602001614ccd670de0b6b3a7640000611414868963ffffffff61352616565b81526020018873ffffffffffffffffffffffffffffffffffffffff166391b427456040518163ffffffff1660e01b815260040160206040518083038186803b158015614d1857600080fd5b505afa158015614d2c573d6000803e3d6000fd5b505050506040513d6020811015614d4257600080fd5b50518152604080517f1aebf12f000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692631aebf12f9260048083019392829003018186803b158015614dae57600080fd5b505afa158015614dc2573d6000803e3d6000fd5b505050506040513d6020811015614dd857600080fd5b50518152604080517f4322b714000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692634322b7149260048083019392829003018186803b158015614e4457600080fd5b505afa158015614e58573d6000803e3d6000fd5b505050506040513d6020811015614e6e57600080fd5b50518152604080517f5b2b9d1a000000000000000000000000000000000000000000000000000000008152905160209283019273ffffffffffffffffffffffffffffffffffffffff8c1692635b2b9d1a9260048083019392829003018186803b158015614eda57600080fd5b505afa158015614eee573d6000803e3d6000fd5b505050506040513d6020811015614f0457600080fd5b5051815260006020909101529450614f1b856153e5565b6101408601525050505092915050565b614f33615943565b60008260400151614f438461512c565b1015614f5457508190506000614f8b565b6000614f67846040015161211c8661512c565b90506000614f798560a00151836154e5565b9050614f8585826154fb565b93509150505b915091565b610140908101519101511190565b600080821161500e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f4552524f523a2072617465203d20300000000000000000000000000000000000604482015290519081900360640190fd5b82610140015182111561508257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552524f523a205441524745542052415445203e204341434845442052415445604482015290519081900360640190fd5b600061508e84846155bb565b905060006150b582611414670de0b6b3a7640000886040015161352690919063ffffffff16565b90506150c08561512c565b8110156150d257600092505050610a53565b6150eb6150de8661512c565b829063ffffffff61389316565b95945050505050565b6150fc615943565b60a0830151615111908363ffffffff6134b216565b60a084015261511f836153e5565b6101408401525090919050565b6000610a538260a0015183606001516134b290919063ffffffff16565b600061515f846151598585615723565b846151fc565b949350505050565b6000808373ffffffffffffffffffffffffffffffffffffffff16633ba0b9a96040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156151b257600080fd5b505af11580156151c6573d6000803e3d6000fd5b505050506040513d60208110156151dc57600080fd5b5051905061515f670de0b6b3a7640000611414858463ffffffff61352616565b600061521a670de0b6b3a7640000611414858563ffffffff61352616565b90508061522957506000611023565b60008473ffffffffffffffffffffffffffffffffffffffff1663ad7a672f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561527157600080fd5b505afa158015615285573d6000803e3d6000fd5b505050506040513d602081101561529b57600080fd5b50519050808211156152c6576152c38361141483670de0b6b3a764000063ffffffff61352616565b93505b6152ed73ffffffffffffffffffffffffffffffffffffffff8616868663ffffffff61421b16565b604080517f95a2251f000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8716916395a2251f9160248083019260209291908290030181600087803b15801561535b57600080fd5b505af115801561536f573d6000803e3d6000fd5b505050506040513d602081101561538557600080fd5b50516040805182815260208101879052815192945073ffffffffffffffffffffffffffffffffffffffff8816927f8d69ef09150dd510133bc8e54e6ca115e8cf3370ea49a4a5ae56a1cdefc835e9929181900390910190a2509392505050565b6000806153f183615731565b905060006154188460e00151611414670de0b6b3a76400008561352690919063ffffffff16565b905060008460e0015183101561542f5750806154b0565b60006154766154538760e00151670de0b6b3a764000061389390919063ffffffff16565b611414670de0b6b3a76400006136138a60e001518961389390919063ffffffff16565b90506154ac670de0b6b3a76400006154a0611db360018a610120015161389390919063ffffffff16565b9063ffffffff6134b216565b9150505b6150eb670de0b6b3a764000061141484613613670de0b6b3a76400006114146154d88c615771565b889063ffffffff61352616565b60008183106154f45781611023565b5090919050565b615503615943565b600061552f8460400151604051806060016040528060238152602001615a5a60239139613ffb8761512c565b90508083111561558a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180615b8e602e913960400191505060405180910390fd5b60a084015161559f908463ffffffff61389316565b60a08501526155ad846153e5565b610140850152509192915050565b60006155c683615771565b821161561f57615618670de0b6b3a76400006114148560e00151613613615613670de0b6b3a76400006136136155fb8b615771565b6114148b670de0b6b3a764000063ffffffff61352616565b6157c9565b9050610a53565b61012083015160009061563990600163ffffffff61389316565b90506000615665670de0b6b3a764000061211c8761012001518860e0015161352690919063ffffffff16565b905060006156ba61567587615771565b6114146156978960e00151670de0b6b3a764000061389390919063ffffffff16565b613613670de0b6b3a76400006114148c60e001518c61352690919063ffffffff16565b905060006156ff615613670de0b6b3a76400006136136156e36004828a8963ffffffff61352616565b6154a0670de0b6b3a76400006114148a8063ffffffff61352616565b905061571860026114148681858863ffffffff6134b216565b979650505050505050565b60006110238383600061581a565b60008061573d8361512c565b90508061574e5760009150506116f8565b61102381611414670de0b6b3a7640000866040015161352690919063ffffffff16565b6000610a53670de0b6b3a76400006114146157a2856101000151670de0b6b3a764000061389390919063ffffffff16565b613613670de0b6b3a76400006114148860c001518960e0015161352690919063ffffffff16565b6000600382111561580c575080600160028204015b81811015615806578091506002818285816157f557fe5b0401816157fe57fe5b0490506157de565b506116f8565b81156116f857506001919050565b6000806158398461141487670de0b6b3a764000063ffffffff61352616565b9050600061584e82600163ffffffff6134b216565b90508315615890576000615874670de0b6b3a7640000611414848963ffffffff61352616565b9050868111156158845782615886565b815b9350505050611023565b60006158ae670de0b6b3a7640000611414858963ffffffff61352616565b9050868110156158be5781615886565b829350505050611023565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061590a57805160ff1916838001178555615937565b82800160010185558215615937579182015b8281111561593757825182559160200191906001019061591c565b506134ae9291506159b3565b604051806101600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61143291905b808211156134ae57600081556001016159b956fe4c656e64696e675661756c7456323a20424f52524f5741424c455f4558495354534c656e64696e675661756c7456323a20424f52524f5741424c455f44495341424c45444c656e64696e675661756c7456323a204d41585f424f52524f5741424c45535f4c454e4754484c656e64696e675661756c7456323a20424f52524f5741424c455f454e41424c45444552524f523a204e4547415449564520415641494c41424c45204c4951554944495459454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774c656e64696e675661756c7456323a20494e434f4e56454e49454e545f5245414c4c4f434154494f4e4c656e64696e675661756c7456323a20424f52524f5741424c455f444f45534e545f4558495354534c656e64696e675661756c7456323a2052454445454d5f414d4f554e545f5a45524f4c656e64696e675661756c7456323a204e4547415449564520414d4f554e5420544f20414c4c4f434154454552524f523a204445414c4c4f4341544520414d4f554e54203e20415641494c41424c45204c49515549444954594c656e64696e675661756c7456323a20494e56414c49445f554e4445524c59494e474c656e64696e675661756c7456323a20424f52524f5741424c455f4e4f545f464f554e444c656e64696e675661756c7456323a20494e53554646494349454e545f4c4951554944495459a265627a7a72315820d4530361f465d6cbe6c6e00b8d094ff861a795afcbde017b35701a32b0e2f7e064736f6c63430005100032
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.