More Info
Private Name Tags
ContractCreator
TokenTracker
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
60767847 | 8 hrs ago | 1.36036196 AVAX | ||||
60767847 | 8 hrs ago | 1.36036196 AVAX | ||||
60767847 | 8 hrs ago | 1.36036128 AVAX | ||||
60767847 | 8 hrs ago | 1.36036128 AVAX | ||||
25623691 | 813 days ago | 0.05010598 AVAX | ||||
25623691 | 813 days ago | 0.05010598 AVAX | ||||
25519201 | 816 days ago | 6.01477573 AVAX | ||||
25519201 | 816 days ago | 6.01477573 AVAX | ||||
25102583 | 825 days ago | 1.9998871 AVAX | ||||
25102583 | 825 days ago | 1.9998871 AVAX | ||||
24756884 | 833 days ago | 1.96292975 AVAX | ||||
24756884 | 833 days ago | 1.96292975 AVAX | ||||
24750726 | 834 days ago | 1.69025293 AVAX | ||||
24750726 | 834 days ago | 1.69025293 AVAX | ||||
24750242 | 834 days ago | 1.69025251 AVAX | ||||
24750242 | 834 days ago | 1.69025251 AVAX | ||||
24747747 | 834 days ago | 1.82537185 AVAX | ||||
24747747 | 834 days ago | 1.82537185 AVAX | ||||
24747411 | 834 days ago | 1.8253711 AVAX | ||||
24747411 | 834 days ago | 1.8253711 AVAX | ||||
24732820 | 834 days ago | 1.88273153 AVAX | ||||
24732820 | 834 days ago | 1.88273153 AVAX | ||||
24732044 | 834 days ago | 1.88789729 AVAX | ||||
24732044 | 834 days ago | 1.88789729 AVAX | ||||
24730354 | 834 days ago | 1.97357247 AVAX |
Loading...
Loading
Contract Name:
BenqiNativeERC4626Reinvest
Compiler Version
v0.8.14+commit.80d49f37
Contract Source Code (Solidity)
/** *Submitted for verification at snowscan.xyz on 2022-12-16 */ // SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.14; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } } /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. /// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. library SafeTransferLib { /*////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool success; assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } require(success, "ETH_TRANSFER_FAILED"); } /*////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument. mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) ) } require(success, "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool success; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "APPROVE_FAILED"); } } /// @notice Arithmetic library with operations for fixed-point numbers. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol) /// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol) library FixedPointMathLib { /*////////////////////////////////////////////////////////////// SIMPLIFIED FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. } function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. } function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. } function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. } /*////////////////////////////////////////////////////////////// LOW LEVEL FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ function mulDivDown( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // Divide z by the denominator. z := div(z, denominator) } } function mulDivUp( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // First, divide z - 1 by the denominator and add 1. // We allow z - 1 to underflow if z is 0, because we multiply the // end result by 0 if z is zero, ensuring we return 0 if z is zero. z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1)) } } function rpow( uint256 x, uint256 n, uint256 scalar ) internal pure returns (uint256 z) { assembly { switch x case 0 { switch n case 0 { // 0 ** 0 = 1 z := scalar } default { // 0 ** n = 0 z := 0 } } default { switch mod(n, 2) case 0 { // If n is even, store scalar in z for now. z := scalar } default { // If n is odd, store x in z for now. z := x } // Shifting right by 1 is like dividing by 2. let half := shr(1, scalar) for { // Shift n right by 1 before looping to halve it. n := shr(1, n) } n { // Shift n right by 1 each iteration to halve it. n := shr(1, n) } { // Revert immediately if x ** 2 would overflow. // Equivalent to iszero(eq(div(xx, x), x)) here. if shr(128, x) { revert(0, 0) } // Store x squared. let xx := mul(x, x) // Round to the nearest number. let xxRound := add(xx, half) // Revert if xx + half overflowed. if lt(xxRound, xx) { revert(0, 0) } // Set x to scaled xxRound. x := div(xxRound, scalar) // If n is even: if mod(n, 2) { // Compute z * x. let zx := mul(z, x) // If z * x overflowed: if iszero(eq(div(zx, x), z)) { // Revert if x is non-zero. if iszero(iszero(x)) { revert(0, 0) } } // Round to the nearest number. let zxRound := add(zx, half) // Revert if zx + half overflowed. if lt(zxRound, zx) { revert(0, 0) } // Return properly scaled zxRound. z := div(zxRound, scalar) } } } } } /*////////////////////////////////////////////////////////////// GENERAL NUMBER UTILITIES //////////////////////////////////////////////////////////////*/ function sqrt(uint256 x) internal pure returns (uint256 z) { assembly { // Start off with z at 1. z := 1 // Used below to help find a nearby power of 2. let y := x // Find the lowest power of 2 that is at least sqrt(x). if iszero(lt(y, 0x100000000000000000000000000000000)) { y := shr(128, y) // Like dividing by 2 ** 128. z := shl(64, z) // Like multiplying by 2 ** 64. } if iszero(lt(y, 0x10000000000000000)) { y := shr(64, y) // Like dividing by 2 ** 64. z := shl(32, z) // Like multiplying by 2 ** 32. } if iszero(lt(y, 0x100000000)) { y := shr(32, y) // Like dividing by 2 ** 32. z := shl(16, z) // Like multiplying by 2 ** 16. } if iszero(lt(y, 0x10000)) { y := shr(16, y) // Like dividing by 2 ** 16. z := shl(8, z) // Like multiplying by 2 ** 8. } if iszero(lt(y, 0x100)) { y := shr(8, y) // Like dividing by 2 ** 8. z := shl(4, z) // Like multiplying by 2 ** 4. } if iszero(lt(y, 0x10)) { y := shr(4, y) // Like dividing by 2 ** 4. z := shl(2, z) // Like multiplying by 2 ** 2. } if iszero(lt(y, 0x8)) { // Equivalent to 2 ** z. z := shl(1, z) } // Shifting right by 1 is like dividing by 2. z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) // Compute a rounded down version of z. let zRoundDown := div(x, z) // If zRoundDown is smaller, use it. if lt(zRoundDown, z) { z := zRoundDown } } } } /// @notice Minimal ERC4626 tokenized Vault implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol) abstract contract ERC4626 is ERC20 { using SafeTransferLib for ERC20; using FixedPointMathLib for uint256; /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /*////////////////////////////////////////////////////////////// IMMUTABLES //////////////////////////////////////////////////////////////*/ ERC20 public immutable asset; constructor( ERC20 _asset, string memory _name, string memory _symbol ) ERC20(_name, _symbol, _asset.decimals()) { asset = _asset; } /*////////////////////////////////////////////////////////////// DEPOSIT/WITHDRAWAL LOGIC //////////////////////////////////////////////////////////////*/ function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) { // Check for rounding error since we round down in previewDeposit. require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES"); // Need to transfer before minting or ERC777s could reenter. asset.safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); afterDeposit(assets, shares); } function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) { assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up. // Need to transfer before minting or ERC777s could reenter. asset.safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); afterDeposit(assets, shares); } function withdraw( uint256 assets, address receiver, address owner ) public virtual returns (uint256 shares) { shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up. if (msg.sender != owner) { uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; } beforeWithdraw(assets, shares); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); asset.safeTransfer(receiver, assets); } function redeem( uint256 shares, address receiver, address owner ) public virtual returns (uint256 assets) { if (msg.sender != owner) { uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; } // Check for rounding error since we round down in previewRedeem. require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS"); beforeWithdraw(assets, shares); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); asset.safeTransfer(receiver, assets); } /*////////////////////////////////////////////////////////////// ACCOUNTING LOGIC //////////////////////////////////////////////////////////////*/ function totalAssets() public view virtual returns (uint256); function convertToShares(uint256 assets) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets()); } function convertToAssets(uint256 shares) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply); } function previewDeposit(uint256 assets) public view virtual returns (uint256) { return convertToShares(assets); } function previewMint(uint256 shares) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply); } function previewWithdraw(uint256 assets) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets()); } function previewRedeem(uint256 shares) public view virtual returns (uint256) { return convertToAssets(shares); } /*////////////////////////////////////////////////////////////// DEPOSIT/WITHDRAWAL LIMIT LOGIC //////////////////////////////////////////////////////////////*/ function maxDeposit(address) public view virtual returns (uint256) { return type(uint256).max; } function maxMint(address) public view virtual returns (uint256) { return type(uint256).max; } function maxWithdraw(address owner) public view virtual returns (uint256) { return convertToAssets(balanceOf[owner]); } function maxRedeem(address owner) public view virtual returns (uint256) { return balanceOf[owner]; } /*////////////////////////////////////////////////////////////// INTERNAL HOOKS LOGIC //////////////////////////////////////////////////////////////*/ function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {} function afterDeposit(uint256 assets, uint256 shares) internal virtual {} } abstract contract ICEther is ERC20 { function comptroller() external view virtual returns (address); function getCash() external view virtual returns (uint256); function getAccountSnapshot(address) external view virtual returns ( uint256, uint256, uint256, uint256 ); function redeemUnderlying(uint256) external virtual returns (uint256); function mint() external payable virtual; function exchangeRateStored() external virtual view returns (uint); } interface IInterestRateModel { function getBorrowRate( uint256, uint256, uint256 ) external view returns (uint256); function getSupplyRate( uint256, uint256, uint256, uint256 ) external view returns (uint256); } abstract contract ICERC20 is ERC20 { function mint(uint256 underlyingAmount) external virtual returns (uint256); function underlying() external view virtual returns (ERC20); function getCash() external view virtual returns (uint256); function totalBorrows() external view virtual returns (uint256); function totalReserves() external view virtual returns (uint256); function exchangeRateStored() external view virtual returns (uint256); function accrualBlockNumber() external view virtual returns (uint256); function redeemUnderlying(uint256 underlyingAmount) external virtual returns (uint256); function balanceOfUnderlying(address) external virtual returns (uint256); function reserveFactorMantissa() external view virtual returns (uint256); function interestRateModel() external view virtual returns (IInterestRateModel); function initialExchangeRateMantissa() external view virtual returns (uint256); } /// @notice Get up to date cToken data without mutating state. /// @author Transmissions11 (https://github.com/transmissions11/libcompound) library LibCompound { using FixedPointMathLib for uint256; function viewUnderlyingBalanceOf(ICERC20 cToken, address user) internal view returns (uint256) { return cToken.balanceOf(user).mulWadDown(viewExchangeRate(cToken)); } function viewExchangeRate(ICERC20 cToken) internal view returns (uint256) { uint256 accrualBlockNumberPrior = cToken.accrualBlockNumber(); if (accrualBlockNumberPrior == block.number) { return cToken.exchangeRateStored(); } uint256 totalCash = cToken.underlying().balanceOf(address(cToken)); uint256 borrowsPrior = cToken.totalBorrows(); uint256 reservesPrior = cToken.totalReserves(); uint256 borrowRateMantissa = cToken.interestRateModel().getBorrowRate(totalCash, borrowsPrior, reservesPrior); require(borrowRateMantissa <= 0.0005e16, "RATE_TOO_HIGH"); // Same as borrowRateMaxMantissa in CTokenInterfaces.sol uint256 interestAccumulated = (borrowRateMantissa * (block.number - accrualBlockNumberPrior)).mulWadDown(borrowsPrior); uint256 totalReserves = cToken.reserveFactorMantissa().mulWadDown(interestAccumulated) + reservesPrior; uint256 totalBorrows = interestAccumulated + borrowsPrior; uint256 totalSupply = cToken.totalSupply(); return totalSupply == 0 ? cToken.initialExchangeRateMantissa() : (totalCash + totalBorrows - totalReserves).divWadDown(totalSupply); } } interface IComptroller { function qiAddress() external view returns (address); function getAllMarkets() external view returns (address[] memory); function allMarkets(uint256 index) external view returns (address); function claimReward(uint8 rewardType, address holder) external; function mintGuardianPaused(address cToken) external view returns (bool); function rewardAccrued(uint8, address) external view returns (uint256); } interface IPair { function getReserves() external view returns ( uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast ); function swap( uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data ) external; } library DexSwap { using SafeTransferLib for ERC20; /** * @notice Swap directly through a Pair * @param amountIn input amount * @param fromToken address * @param toToken address * @param pairToken Pair used for swap * @return output amount */ function swap( uint256 amountIn, address fromToken, address toToken, address pairToken ) internal returns (uint256) { IPair pair = IPair(pairToken); (address token0, ) = sortTokens(fromToken, toToken); (uint112 reserve0, uint112 reserve1, ) = pair.getReserves(); if (token0 != fromToken) (reserve0, reserve1) = (reserve1, reserve0); uint256 amountOut1 = 0; uint256 amountOut2 = getAmountOut(amountIn, reserve0, reserve1); if (token0 != fromToken) (amountOut1, amountOut2) = (amountOut2, amountOut1); ERC20(fromToken).safeTransfer(address(pair), amountIn); pair.swap(amountOut1, amountOut2, address(this), new bytes(0)); return amountOut2 > amountOut1 ? amountOut2 : amountOut1; } /** * @notice Given an input amount of an asset and pair reserves, returns maximum output amount of the other asset * @dev Assumes swap fee is 0.30% * @param amountIn input asset * @param reserveIn size of input asset reserve * @param reserveOut size of output asset reserve * @return maximum output amount */ function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) internal pure returns (uint256) { uint256 amountInWithFee = amountIn * 997; uint256 numerator = amountInWithFee * (reserveOut); uint256 denominator = (reserveIn * 1000) + (amountInWithFee); return numerator / (denominator); } /** * @notice Given two tokens, it'll return the tokens in the right order for the tokens pair * @dev TokenA must be different from TokenB, and both shouldn't be address(0), no validations * @param tokenA address * @param tokenB address * @return sorted tokens */ function sortTokens(address tokenA, address tokenB) internal pure returns (address, address) { return tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); } } interface WrappedNative { function deposit() external payable; function withdraw(uint wad) external; } /// @title BenqiERC4626Reinvest - Custom implementation of yield-daddy wrappers with flexible reinvesting logic /// @notice Extended with payable function to accept native token transfer contract BenqiNativeERC4626Reinvest is ERC4626 { /// ----------------------------------------------------------------------- /// Libraries usage /// ----------------------------------------------------------------------- using LibCompound for ICEther; using SafeTransferLib for ERC20; using FixedPointMathLib for uint256; /// ----------------------------------------------------------------------- /// Constants /// ----------------------------------------------------------------------- uint256 internal constant NO_ERROR = 0; /// ----------------------------------------------------------------------- /// Immutable params /// ----------------------------------------------------------------------- /// @notice cEther token reference ICEther public immutable cEther; /// @notice The Compound comptroller contract IComptroller public immutable comptroller; /// @notice Access Control for harvest() route address public immutable manager; /// @notice The COMP-like token contract ERC20 public immutable reward; /// @notice Type of reward currently distributed by Benqi Vaults uint8 public rewardType; /// @notice Map rewardType to rewardToken mapping(uint8 => address) public rewardTokenMap; /// @notice Map rewardType to swap route mapping(uint8 => swapInfo) public swapInfoMap; /// @notice Pointer to swapInfo swapInfo public SwapInfo; /// Compact struct to make two swaps (PancakeSwap on BSC) /// A => B (using pair1) then B => asset (of Wrapper) (using pair2) struct swapInfo { address token; address pair1; address pair2; } /// ----------------------------------------------------------------------- /// Errors /// ----------------------------------------------------------------------- /// @notice Thrown when a call to Compound returned an error. /// @param errorCode The error code returned by Compound error CompoundERC4626__CompoundError(uint256 errorCode); /// @notice Thrown when the deposited assets doesnot return any shares. error CompoundERC4626_ZEROSHARES_Error(); /// @notice Thrown when the redeems shares doesnot return any assets. error CompoundERC4626_ZEROASSETS_Error(); /// ----------------------------------------------------------------------- /// Constructor /// ----------------------------------------------------------------------- constructor( ERC20 asset_, // underlying ERC20 reward_, // comp token or other ICEther cEther_, // compound concept of a share address manager_ ) ERC4626(asset_, _vaultName(asset_), _vaultSymbol(asset_)) { reward = reward_; cEther = cEther_; comptroller = IComptroller(cEther.comptroller()); manager = manager_; } /// ----------------------------------------------------------------------- /// Compound liquidity mining /// ----------------------------------------------------------------------- /// @notice Set swap routes for selling rewards /// @notice Set type of reward we are harvesting and selling /// @dev 0 = BenqiToken, 1 = AVAX /// @dev Setting wrong addresses here will revert harvest() calls function setRoute( uint8 rewardType_, address rewardToken, address token, address pair1, address pair2 ) external { require(msg.sender == manager, "onlyOwner"); swapInfoMap[rewardType_] = swapInfo(token, pair1, pair2); rewardTokenMap[rewardType_] = rewardToken; } /// @notice Claims liquidity mining rewards from Benqi and sends it to this Vault function harvest(uint8 rewardType_) external { swapInfo memory swapMap = swapInfoMap[rewardType_]; address rewardToken = rewardTokenMap[rewardType_]; ERC20 rewardToken_ = ERC20(rewardToken); comptroller.claimReward(rewardType_, address(this)); uint256 earned = ERC20(rewardToken).balanceOf(address(this)); /// If only one swap needed (high liquidity pair) - set swapInfo.token0/token/pair2 to 0x if (swapMap.token == address(asset)) { rewardToken_.approve(swapMap.pair1, earned); DexSwap.swap( earned, /// REWARDS amount to swap rewardToken, // from REWARD (because of liquidity) address(asset), /// to target underlying of this Vault ie USDC swapMap.pair1 /// pairToken (pool) ); /// If two swaps needed } else { rewardToken_.approve(swapMap.pair1, earned); uint256 swapTokenAmount = DexSwap.swap( earned, /// REWARDS amount to swap rewardToken, /// fromToken REWARD swapMap.token, /// to intermediary token with high liquidity (no direct pools) swapMap.pair1 /// pairToken (pool) ); ERC20(swapMap.token).approve(swapMap.pair2, swapTokenAmount); DexSwap.swap( swapTokenAmount, swapMap.token, // from received BUSD (because of liquidity) address(asset), /// to target underlying of this Vault ie USDC swapMap.pair2 /// pairToken (pool) ); } afterDeposit(asset.balanceOf(address(this)), 0); } /// @notice Check how much rewards are available to claim, useful before harvest() function getRewardsAccrued(uint8 rewardType_) external view returns (uint256 amount) { amount = comptroller.rewardAccrued(rewardType_, address(this)); } /// ----------------------------------------------------------------------- /// ERC4626 overrides /// ----------------------------------------------------------------------- function beforeWithdraw(uint256 assets, uint256) internal override { // Withdraw the underlying tokens from the cEther. uint256 errorCode = cEther.redeemUnderlying(assets); if (errorCode != NO_ERROR) { revert CompoundERC4626__CompoundError(errorCode); } } function viewUnderlyingBalanceOf() internal view returns (uint256) { return cEther.balanceOf(address(this)).mulWadDown( cEther.exchangeRateStored() ); } function afterDeposit(uint256 assets, uint256) internal override { WrappedNative(address(asset)).withdraw(assets); // mint tokens cEther.mint{value: assets}(); } function deposit(address receiver) public payable returns (uint256 shares) { // Check for rounding error since we round down in previewDeposit. if ((shares = previewDeposit(msg.value)) == 0) revert CompoundERC4626_ZEROSHARES_Error(); require((shares = previewDeposit(msg.value)) != 0, "ZERO_SHARES"); WrappedNative(address(asset)).deposit{value: msg.value}(); _mint(receiver, shares); emit Deposit(msg.sender, receiver, msg.value, shares); afterDeposit(msg.value, shares); } /// Standard ERC4626 deposit can only accept ERC20 function deposit(uint256 assets, address receiver) public override returns (uint256 shares) { require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES"); asset.safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); afterDeposit(assets, shares); } /// @notice Total amount of the underlying asset that /// is "managed" by Vault. function totalAssets() public view override returns (uint256) { return viewUnderlyingBalanceOf(); } /// @notice maximum amount of assets that can be deposited. /// This is capped by the amount of assets the cEther can be /// supplied with. /// This is 0 if minting is paused on the cEther. function maxDeposit(address) public view override returns (uint256) { if (comptroller.mintGuardianPaused(address(cEther))) return 0; return type(uint256).max; } /// @notice maximum amount of shares that can be minted. /// This is capped by the amount of assets the cEther can be /// supplied with. /// This is 0 if minting is paused on the cEther. function maxMint(address) public view override returns (uint256) { if (comptroller.mintGuardianPaused(address(cEther))) return 0; return type(uint256).max; } /// @notice Maximum amount of assets that can be withdrawn. /// This is capped by the amount of cash available on the cEther, /// if all assets are borrowed, a user can't withdraw from the vault. function maxWithdraw(address owner) public view override returns (uint256) { uint256 cash = cEther.getCash(); uint256 assetsBalance = convertToAssets(balanceOf[owner]); return cash < assetsBalance ? cash : assetsBalance; } /// @notice Maximum amount of shares that can be redeemed. /// This is capped by the amount of cash available on the cEther, /// if all assets are borrowed, a user can't redeem from the vault. function maxRedeem(address owner) public view override returns (uint256) { uint256 cash = cEther.getCash(); uint256 cashInShares = convertToShares(cash); uint256 shareBalance = balanceOf[owner]; return cashInShares < shareBalance ? cashInShares : shareBalance; } /// @notice withdraw assets of the owner. function withdraw( uint256 assets, address receiver, address owner ) public override returns (uint256 shares) { shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up. if (msg.sender != owner) { uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; } beforeWithdraw(assets, shares); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); WrappedNative(address(asset)).deposit{value: assets}(); asset.safeTransfer(receiver, assets); } function redeem( uint256 shares, address receiver, address owner ) public override returns (uint256 assets) { if (msg.sender != owner) { uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; } // Check for rounding error since we round down in previewRedeem. if ((assets = previewRedeem(shares)) == 0) revert CompoundERC4626_ZEROASSETS_Error(); beforeWithdraw(assets, shares); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); WrappedNative(address(asset)).deposit{value: assets}(); asset.safeTransfer(receiver, assets); } receive() external payable {} /// ----------------------------------------------------------------------- /// ERC20 metadata generation /// ----------------------------------------------------------------------- function _vaultName(ERC20 asset_) internal view virtual returns (string memory vaultName) { vaultName = string.concat("ERC4626-Wrapped Benqi - ", asset_.symbol()); } function _vaultSymbol(ERC20 asset_) internal view virtual returns (string memory vaultSymbol) { vaultSymbol = string.concat("bq46-", asset_.symbol()); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract ERC20","name":"asset_","type":"address"},{"internalType":"contract ERC20","name":"reward_","type":"address"},{"internalType":"contract ICEther","name":"cEther_","type":"address"},{"internalType":"address","name":"manager_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CompoundERC4626_ZEROASSETS_Error","type":"error"},{"inputs":[],"name":"CompoundERC4626_ZEROSHARES_Error","type":"error"},{"inputs":[{"internalType":"uint256","name":"errorCode","type":"uint256"}],"name":"CompoundERC4626__CompoundError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Deposit","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":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SwapInfo","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"pair1","type":"address"},{"internalType":"address","name":"pair2","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cEther","outputs":[{"internalType":"contract ICEther","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"comptroller","outputs":[{"internalType":"contract IComptroller","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"rewardType_","type":"uint8"}],"name":"getRewardsAccrued","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"rewardType_","type":"uint8"}],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"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":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reward","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"rewardTokenMap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardType","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"rewardType_","type":"uint8"},{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"pair1","type":"address"},{"internalType":"address","name":"pair2","type":"address"}],"name":"setRoute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"swapInfoMap","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"pair1","type":"address"},{"internalType":"address","name":"pair2","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101806040523480156200001257600080fd5b506040516200307438038062003074833981016040819052620000359162000404565b83620000418162000199565b6200004c866200022c565b8181846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200008d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b391906200046c565b8251620000c890600090602086019062000345565b508151620000de90600190602085019062000345565b5060ff81166080524660a052620000f4620002a9565b60c0525050506001600160a01b0392831660e052505083811661016052821661010081905260408051635fe3b56760e01b81529051635fe3b567916004808201926020929091908290030181865afa15801562000155573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200017b919062000498565b6001600160a01b03908116610120521661014052506200070e915050565b6060816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620001da573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000204919081019062000501565b604051602001620002169190620005b9565b6040516020818303038152906040529050919050565b6060816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200026d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000297919081019062000501565b60405160200162000216919062000600565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051620002dd91906200066b565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b82805462000353906200062f565b90600052602060002090601f016020900481019282620003775760008555620003c2565b82601f106200039257805160ff1916838001178555620003c2565b82800160010185558215620003c2579182015b82811115620003c2578251825591602001919060010190620003a5565b50620003d0929150620003d4565b5090565b5b80821115620003d05760008155600101620003d5565b6001600160a01b03811681146200040157600080fd5b50565b600080600080608085870312156200041b57600080fd5b84516200042881620003eb565b60208601519094506200043b81620003eb565b60408601519093506200044e81620003eb565b60608601519092506200046181620003eb565b939692955090935050565b6000602082840312156200047f57600080fd5b815160ff811681146200049157600080fd5b9392505050565b600060208284031215620004ab57600080fd5b81516200049181620003eb565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004eb578181015183820152602001620004d1565b83811115620004fb576000848401525b50505050565b6000602082840312156200051457600080fd5b81516001600160401b03808211156200052c57600080fd5b818401915084601f8301126200054157600080fd5b815181811115620005565762000556620004b8565b604051601f8201601f19908116603f01168101908382118183101715620005815762000581620004b8565b816040528281528760208487010111156200059b57600080fd5b620005ae836020830160208801620004ce565b979650505050505050565b7f455243343632362d577261707065642042656e7169202d200000000000000000815260008251620005f3816018850160208701620004ce565b9190910160180192915050565b64627134362d60d81b81526000825162000622816005850160208701620004ce565b9190910160050192915050565b600181811c908216806200064457607f821691505b6020821081036200066557634e487b7160e01b600052602260045260246000fd5b50919050565b600080835481600182811c9150808316806200068857607f831692505b60208084108203620006a857634e487b7160e01b86526022600452602486fd5b818015620006bf5760018114620006d15762000700565b60ff1986168952848901965062000700565b60008a81526020902060005b86811015620006f85781548b820152908501908301620006dd565b505084890196505b509498975050505050505050565b60805160a05160c05160e0516101005161012051610140516101605161285f62000815600039600061039b01526000818161049e01526111ec01526000818161054901528181610a2901528181610f3701526110c501526000818161034f01528181610f0c015281816116ac015281816119b401528181611bd101528181611c6601528181611f1e015261212401526000818161044a01528181610af601528181610bb201528181610cf901528181610d3e015281816110220152818161115201528181611438015281816114b6015281816115de0152818161165c01528181611af90152611eb801526000610ed301526000610ea3015260006103ef015261285f6000f3fe60806040526004361061023f5760003560e01c8063743c854a1161012e578063c63d75b6116100ab578063d505accf1161006f578063d505accf146107b3578063d905777e146107d3578063dd62ed3e146107f3578063ef8b30f71461082b578063f340fa011461084b57600080fd5b8063c63d75b61461046c578063c6e6f59214610710578063ce96cb7714610730578063d2802f5d14610750578063d38d0a921461079957600080fd5b80639f3bb0ef116100f25780639f3bb0ef14610670578063a9059cbb14610690578063b3d7f6b9146106b0578063b460af94146106d0578063ba087652146106f057600080fd5b8063743c854a146105b85780637ecebe00146105d857806394bf804d1461060557806395d89b4114610625578063966134fb1461063a57600080fd5b8063313ce567116101bc5780634cdad506116101805780634cdad506146104c057806353104b8e146104e05780635fe3b567146105375780636e553f651461056b57806370a082311461058b57600080fd5b8063313ce567146103dd5780633644e5151461042357806338d52e0f14610438578063402d267d1461046c578063481c6a751461048c57600080fd5b806315146d131161020357806315146d131461030557806318160ddd1461032757806319b68c001461033d578063228cb7331461038957806323b872dd146103bd57600080fd5b806301e1d1141461024b57806306fdde031461027357806307a2d13a14610295578063095ea7b3146102b55780630a28a477146102e557600080fd5b3661024657005b600080fd5b34801561025757600080fd5b5061026061085e565b6040519081526020015b60405180910390f35b34801561027f57600080fd5b5061028861086d565b60405161026a9190612384565b3480156102a157600080fd5b506102606102b0366004612397565b6108fb565b3480156102c157600080fd5b506102d56102d03660046123c7565b610928565b604051901515815260200161026a565b3480156102f157600080fd5b50610260610300366004612397565b610995565b34801561031157600080fd5b50610325610320366004612402565b6109b5565b005b34801561033357600080fd5b5061026060025481565b34801561034957600080fd5b506103717f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161026a565b34801561039557600080fd5b506103717f000000000000000000000000000000000000000000000000000000000000000081565b3480156103c957600080fd5b506102d56103d836600461241d565b610dbf565b3480156103e957600080fd5b506104117f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161026a565b34801561042f57600080fd5b50610260610e9f565b34801561044457600080fd5b506103717f000000000000000000000000000000000000000000000000000000000000000081565b34801561047857600080fd5b50610260610487366004612459565b610ef5565b34801561049857600080fd5b506103717f000000000000000000000000000000000000000000000000000000000000000081565b3480156104cc57600080fd5b506102606104db366004612397565b610fba565b3480156104ec57600080fd5b50600954600a54600b5461050d926001600160a01b03908116928116911683565b604080516001600160a01b039485168152928416602084015292169181019190915260600161026a565b34801561054357600080fd5b506103717f000000000000000000000000000000000000000000000000000000000000000081565b34801561057757600080fd5b50610260610586366004612474565b610fc5565b34801561059757600080fd5b506102606105a6366004612459565b60036020526000908152604090205481565b3480156105c457600080fd5b506102606105d3366004612402565b6110a4565b3480156105e457600080fd5b506102606105f3366004612459565b60056020526000908152604090205481565b34801561061157600080fd5b50610260610620366004612474565b611138565b34801561063157600080fd5b506102886111d4565b34801561064657600080fd5b50610371610655366004612402565b6007602052600090815260409020546001600160a01b031681565b34801561067c57600080fd5b5061032561068b3660046124a0565b6111e1565b34801561069c57600080fd5b506102d56106ab3660046123c7565b6112d7565b3480156106bc57600080fd5b506102606106cb366004612397565b61133d565b3480156106dc57600080fd5b506102606106eb366004612505565b61135c565b3480156106fc57600080fd5b5061026061070b366004612505565b6114e1565b34801561071c57600080fd5b5061026061072b366004612397565b611687565b34801561073c57600080fd5b5061026061074b366004612459565b6116a7565b34801561075c57600080fd5b5061050d61076b366004612402565b6008602052600090815260409020805460018201546002909201546001600160a01b03918216928216911683565b3480156107a557600080fd5b506006546104119060ff1681565b3480156107bf57600080fd5b506103256107ce366004612541565b61176b565b3480156107df57600080fd5b506102606107ee366004612459565b6119af565b3480156107ff57600080fd5b5061026061080e3660046125ab565b600460209081526000928352604080842090915290825290205481565b34801561083757600080fd5b50610260610846366004612397565b611a75565b610260610859366004612459565b611a80565b6000610868611bca565b905090565b6000805461087a906125d5565b80601f01602080910402602001604051908101604052809291908181526020018280546108a6906125d5565b80156108f35780601f106108c8576101008083540402835291602001916108f3565b820191906000526020600020905b8154815290600101906020018083116108d657829003601f168201915b505050505081565b600254600090801561091f5761091a61091261085e565b849083611cdf565b610921565b825b9392505050565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906109839086815260200190565b60405180910390a35060015b92915050565b600254600090801561091f5761091a816109ad61085e565b859190611cfe565b60ff81166000818152600860209081526040808320815160608101835281546001600160a01b0390811682526001830154811682860152600290920154821681840152858552600790935292819020549051630952c56360e01b8152600481019490945230602485015290929082169182917f000000000000000000000000000000000000000000000000000000000000000090911690630952c56390604401600060405180830381600087803b158015610a6f57600080fd5b505af1158015610a83573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03851691506370a0823190602401602060405180830381865afa158015610ace573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af2919061260f565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031684600001516001600160a01b031603610be157602084015160405163095ea7b360e01b81526001600160a01b039182166004820152602481018390529083169063095ea7b3906044016020604051808303816000875af1158015610b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610baa9190612628565b50610bdb81847f00000000000000000000000000000000000000000000000000000000000000008760200151611d2c565b50610d25565b602084015160405163095ea7b360e01b81526001600160a01b039182166004820152602481018390529083169063095ea7b3906044016020604051808303816000875af1158015610c36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5a9190612628565b506000610c71828587600001518860200151611d2c565b8551604080880151905163095ea7b360e01b81526001600160a01b03918216600482015260248101849052929350169063095ea7b3906044016020604051808303816000875af1158015610cc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ced9190612628565b50610d228186600001517f00000000000000000000000000000000000000000000000000000000000000008860400151611d2c565b50505b6040516370a0823160e01b8152306004820152610db8907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610d8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db1919061260f565b6000611ea2565b5050505050565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610e1b57610df68382612660565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610e43908490612660565b90915550506001600160a01b038085166000818152600360205260409081902080548701905551909187169060008051602061280a83398151915290610e8c9087815260200190565b60405180910390a3506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610ed057610868611f94565b507f000000000000000000000000000000000000000000000000000000000000000090565b60405163731f0c2b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063731f0c2b90602401602060405180830381865afa158015610f80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa49190612628565b15610fb157506000919050565b50600019919050565b600061098f826108fb565b6000610fd083611a75565b9050806000036110155760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b60448201526064015b60405180910390fd5b61104a6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308661202e565b61105482826120b1565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a361098f8382611ea2565b6040516305b9783d60e01b815260ff821660048201523060248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906305b9783d90604401602060405180830381865afa158015611114573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098f919061260f565b60006111438361133d565b905061117a6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308461202e565b61118482846120b1565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a361098f8184611ea2565b6001805461087a906125d5565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146112455760405162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015260640161100c565b604080516060810182526001600160a01b039485168152928416602080850191825292851684830190815260ff97909716600090815260088452828120945185546001600160a01b031990811691881691909117865591516001860180548416918816919091179055965160029094018054821694861694909417909355600790915290932080549093169116179055565b336000908152600360205260408120805483919083906112f8908490612660565b90915550506001600160a01b0383166000818152600360205260409081902080548501905551339060008051602061280a833981519152906109839086815260200190565b600254600090801561091f5761091a61135461085e565b849083611cfe565b600061136784610995565b9050336001600160a01b038316146113d7576001600160a01b038216600090815260046020908152604080832033845290915290205460001981146113d5576113b08282612660565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b6113e1848261210b565b6113eb82826121c2565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a47f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b15801561149157600080fd5b505af11580156114a5573d6000803e3d6000fd5b506109219350506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016915085905086612224565b6000336001600160a01b03831614611551576001600160a01b0382166000908152600460209081526040808320338452909152902054600019811461154f5761152a8582612660565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b61155a84610fba565b90508060000361157d57604051631c3b296560e11b815260040160405180910390fd5b611587818561210b565b61159182856121c2565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a47f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561163757600080fd5b505af115801561164b573d6000803e3d6000fd5b506109219350506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016915085905083612224565b600254600090801561091f5761091a8161169f61085e565b859190611cdf565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633b1d21a26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611708573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172c919061260f565b6001600160a01b03841660009081526003602052604081205491925090611752906108fb565b90508082106117615780611763565b815b949350505050565b428410156117bb5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f45585049524544000000000000000000604482015260640161100c565b600060016117c7610e9f565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa1580156118d3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906119095750876001600160a01b0316816001600160a01b0316145b6119465760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b604482015260640161100c565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633b1d21a26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a34919061260f565b90506000611a4182611687565b6001600160a01b038516600090815260036020526040902054909150808210611a6a5780611a6c565b815b95945050505050565b600061098f82611687565b6000611a8b34611a75565b905080600003611aae57604051632090dad160e01b815260040160405180910390fd5b611ab734611a75565b905080600003611af75760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b604482015260640161100c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b5257600080fd5b505af1158015611b66573d6000803e3d6000fd5b5050505050611b7582826120b1565b60408051348152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3611bc53482611ea2565b919050565b60006108687f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c51919061260f565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd9919061260f565b906122a2565b828202811515841585830485141716611cf757600080fd5b0492915050565b828202811515841585830485141716611d1657600080fd5b6001826001830304018115150290509392505050565b60008181611d3a86866122b7565b509050600080836001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611d7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da2919061268e565b5091509150876001600160a01b0316836001600160a01b031614611dc257905b600080611de28b856001600160701b0316856001600160701b03166122e8565b9050896001600160a01b0316856001600160a01b031614611dff57905b611e136001600160a01b038b16878d612224565b6040805160008152602081019182905263022c0d9f60e01b9091526001600160a01b0387169063022c0d9f90611e5290859085903090602481016126de565b600060405180830381600087803b158015611e6c57600080fd5b505af1158015611e80573d6000803e3d6000fd5b50505050818111611e915781611e93565b805b9b9a5050505050505050505050565b604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b158015611f0457600080fd5b505af1158015611f18573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631249c58b836040518263ffffffff1660e01b81526004016000604051808303818588803b158015611f7757600080fd5b505af1158015611f8b573d6000803e3d6000fd5b50505050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611fc69190612715565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60006040516323b872dd60e01b81528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080610db85760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b604482015260640161100c565b80600260008282546120c391906127b0565b90915550506001600160a01b03821660008181526003602090815260408083208054860190555184815260008051602061280a83398151915291015b60405180910390a35050565b60405163852a12e360e01b8152600481018390526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063852a12e3906024016020604051808303816000875af1158015612175573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612199919061260f565b905080156121bd5760405163c309609960e01b81526004810182905260240161100c565b505050565b6001600160a01b038216600090815260036020526040812080548392906121ea908490612660565b90915550506002805482900390556040518181526000906001600160a01b0384169060008051602061280a833981519152906020016120ff565b600060405163a9059cbb60e01b8152836004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061229c5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015260640161100c565b50505050565b60006109218383670de0b6b3a7640000611cdf565b600080826001600160a01b0316846001600160a01b0316106122da5782846122dd565b83835b915091509250929050565b6000806122f7856103e56127c8565b9050600061230584836127c8565b9050600082612316876103e86127c8565b61232091906127b0565b905061232c81836127e7565b979650505050505050565b6000815180845260005b8181101561235d57602081850181015186830182015201612341565b8181111561236f576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006109216020830184612337565b6000602082840312156123a957600080fd5b5035919050565b80356001600160a01b0381168114611bc557600080fd5b600080604083850312156123da57600080fd5b6123e3836123b0565b946020939093013593505050565b803560ff81168114611bc557600080fd5b60006020828403121561241457600080fd5b610921826123f1565b60008060006060848603121561243257600080fd5b61243b846123b0565b9250612449602085016123b0565b9150604084013590509250925092565b60006020828403121561246b57600080fd5b610921826123b0565b6000806040838503121561248757600080fd5b82359150612497602084016123b0565b90509250929050565b600080600080600060a086880312156124b857600080fd5b6124c1866123f1565b94506124cf602087016123b0565b93506124dd604087016123b0565b92506124eb606087016123b0565b91506124f9608087016123b0565b90509295509295909350565b60008060006060848603121561251a57600080fd5b8335925061252a602085016123b0565b9150612538604085016123b0565b90509250925092565b600080600080600080600060e0888a03121561255c57600080fd5b612565886123b0565b9650612573602089016123b0565b9550604088013594506060880135935061258f608089016123f1565b925060a0880135915060c0880135905092959891949750929550565b600080604083850312156125be57600080fd5b6125c7836123b0565b9150612497602084016123b0565b600181811c908216806125e957607f821691505b60208210810361260957634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561262157600080fd5b5051919050565b60006020828403121561263a57600080fd5b8151801515811461092157600080fd5b634e487b7160e01b600052601160045260246000fd5b6000828210156126725761267261264a565b500390565b80516001600160701b0381168114611bc557600080fd5b6000806000606084860312156126a357600080fd5b6126ac84612677565b92506126ba60208501612677565b9150604084015163ffffffff811681146126d357600080fd5b809150509250925092565b84815283602082015260018060a01b038316604082015260806060820152600061270b6080830184612337565b9695505050505050565b600080835481600182811c91508083168061273157607f831692505b6020808410820361275057634e487b7160e01b86526022600452602486fd5b8180156127645760018114612775576127a2565b60ff198616895284890196506127a2565b60008a81526020902060005b8681101561279a5781548b820152908501908301612781565b505084890196505b509498975050505050505050565b600082198211156127c3576127c361264a565b500190565b60008160001904831182151516156127e2576127e261264a565b500290565b60008261280457634e487b7160e01b600052601260045260246000fd5b50049056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212207dd8e7ba39547c929ee358b5a0f863e9d6bccd97935ee5d299d99a3062b4e2b664736f6c634300080e0033000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c70000000000000000000000008729438eb15e2c8b576fcc6aecda6a148776c0f50000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b4
Deployed Bytecode
0x60806040526004361061023f5760003560e01c8063743c854a1161012e578063c63d75b6116100ab578063d505accf1161006f578063d505accf146107b3578063d905777e146107d3578063dd62ed3e146107f3578063ef8b30f71461082b578063f340fa011461084b57600080fd5b8063c63d75b61461046c578063c6e6f59214610710578063ce96cb7714610730578063d2802f5d14610750578063d38d0a921461079957600080fd5b80639f3bb0ef116100f25780639f3bb0ef14610670578063a9059cbb14610690578063b3d7f6b9146106b0578063b460af94146106d0578063ba087652146106f057600080fd5b8063743c854a146105b85780637ecebe00146105d857806394bf804d1461060557806395d89b4114610625578063966134fb1461063a57600080fd5b8063313ce567116101bc5780634cdad506116101805780634cdad506146104c057806353104b8e146104e05780635fe3b567146105375780636e553f651461056b57806370a082311461058b57600080fd5b8063313ce567146103dd5780633644e5151461042357806338d52e0f14610438578063402d267d1461046c578063481c6a751461048c57600080fd5b806315146d131161020357806315146d131461030557806318160ddd1461032757806319b68c001461033d578063228cb7331461038957806323b872dd146103bd57600080fd5b806301e1d1141461024b57806306fdde031461027357806307a2d13a14610295578063095ea7b3146102b55780630a28a477146102e557600080fd5b3661024657005b600080fd5b34801561025757600080fd5b5061026061085e565b6040519081526020015b60405180910390f35b34801561027f57600080fd5b5061028861086d565b60405161026a9190612384565b3480156102a157600080fd5b506102606102b0366004612397565b6108fb565b3480156102c157600080fd5b506102d56102d03660046123c7565b610928565b604051901515815260200161026a565b3480156102f157600080fd5b50610260610300366004612397565b610995565b34801561031157600080fd5b50610325610320366004612402565b6109b5565b005b34801561033357600080fd5b5061026060025481565b34801561034957600080fd5b506103717f0000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c81565b6040516001600160a01b03909116815260200161026a565b34801561039557600080fd5b506103717f0000000000000000000000008729438eb15e2c8b576fcc6aecda6a148776c0f581565b3480156103c957600080fd5b506102d56103d836600461241d565b610dbf565b3480156103e957600080fd5b506104117f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff909116815260200161026a565b34801561042f57600080fd5b50610260610e9f565b34801561044457600080fd5b506103717f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c781565b34801561047857600080fd5b50610260610487366004612459565b610ef5565b34801561049857600080fd5b506103717f000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b481565b3480156104cc57600080fd5b506102606104db366004612397565b610fba565b3480156104ec57600080fd5b50600954600a54600b5461050d926001600160a01b03908116928116911683565b604080516001600160a01b039485168152928416602084015292169181019190915260600161026a565b34801561054357600080fd5b506103717f000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b481565b34801561057757600080fd5b50610260610586366004612474565b610fc5565b34801561059757600080fd5b506102606105a6366004612459565b60036020526000908152604090205481565b3480156105c457600080fd5b506102606105d3366004612402565b6110a4565b3480156105e457600080fd5b506102606105f3366004612459565b60056020526000908152604090205481565b34801561061157600080fd5b50610260610620366004612474565b611138565b34801561063157600080fd5b506102886111d4565b34801561064657600080fd5b50610371610655366004612402565b6007602052600090815260409020546001600160a01b031681565b34801561067c57600080fd5b5061032561068b3660046124a0565b6111e1565b34801561069c57600080fd5b506102d56106ab3660046123c7565b6112d7565b3480156106bc57600080fd5b506102606106cb366004612397565b61133d565b3480156106dc57600080fd5b506102606106eb366004612505565b61135c565b3480156106fc57600080fd5b5061026061070b366004612505565b6114e1565b34801561071c57600080fd5b5061026061072b366004612397565b611687565b34801561073c57600080fd5b5061026061074b366004612459565b6116a7565b34801561075c57600080fd5b5061050d61076b366004612402565b6008602052600090815260409020805460018201546002909201546001600160a01b03918216928216911683565b3480156107a557600080fd5b506006546104119060ff1681565b3480156107bf57600080fd5b506103256107ce366004612541565b61176b565b3480156107df57600080fd5b506102606107ee366004612459565b6119af565b3480156107ff57600080fd5b5061026061080e3660046125ab565b600460209081526000928352604080842090915290825290205481565b34801561083757600080fd5b50610260610846366004612397565b611a75565b610260610859366004612459565b611a80565b6000610868611bca565b905090565b6000805461087a906125d5565b80601f01602080910402602001604051908101604052809291908181526020018280546108a6906125d5565b80156108f35780601f106108c8576101008083540402835291602001916108f3565b820191906000526020600020905b8154815290600101906020018083116108d657829003601f168201915b505050505081565b600254600090801561091f5761091a61091261085e565b849083611cdf565b610921565b825b9392505050565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906109839086815260200190565b60405180910390a35060015b92915050565b600254600090801561091f5761091a816109ad61085e565b859190611cfe565b60ff81166000818152600860209081526040808320815160608101835281546001600160a01b0390811682526001830154811682860152600290920154821681840152858552600790935292819020549051630952c56360e01b8152600481019490945230602485015290929082169182917f000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b490911690630952c56390604401600060405180830381600087803b158015610a6f57600080fd5b505af1158015610a83573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03851691506370a0823190602401602060405180830381865afa158015610ace573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af2919061260f565b90507f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76001600160a01b031684600001516001600160a01b031603610be157602084015160405163095ea7b360e01b81526001600160a01b039182166004820152602481018390529083169063095ea7b3906044016020604051808303816000875af1158015610b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610baa9190612628565b50610bdb81847f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c78760200151611d2c565b50610d25565b602084015160405163095ea7b360e01b81526001600160a01b039182166004820152602481018390529083169063095ea7b3906044016020604051808303816000875af1158015610c36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5a9190612628565b506000610c71828587600001518860200151611d2c565b8551604080880151905163095ea7b360e01b81526001600160a01b03918216600482015260248101849052929350169063095ea7b3906044016020604051808303816000875af1158015610cc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ced9190612628565b50610d228186600001517f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c78860400151611d2c565b50505b6040516370a0823160e01b8152306004820152610db8907f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76001600160a01b0316906370a0823190602401602060405180830381865afa158015610d8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db1919061260f565b6000611ea2565b5050505050565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610e1b57610df68382612660565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610e43908490612660565b90915550506001600160a01b038085166000818152600360205260409081902080548701905551909187169060008051602061280a83398151915290610e8c9087815260200190565b60405180910390a3506001949350505050565b60007f000000000000000000000000000000000000000000000000000000000000a86a4614610ed057610868611f94565b507ff2e58a6f7db03ce99cf3777d5c4235b7435e87572051e44076ddc6b42f93a7e690565b60405163731f0c2b60e01b81526001600160a01b037f0000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c811660048301526000917f000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b49091169063731f0c2b90602401602060405180830381865afa158015610f80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa49190612628565b15610fb157506000919050565b50600019919050565b600061098f826108fb565b6000610fd083611a75565b9050806000036110155760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b60448201526064015b60405180910390fd5b61104a6001600160a01b037f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c71633308661202e565b61105482826120b1565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a361098f8382611ea2565b6040516305b9783d60e01b815260ff821660048201523060248201526000907f000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b46001600160a01b0316906305b9783d90604401602060405180830381865afa158015611114573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098f919061260f565b60006111438361133d565b905061117a6001600160a01b037f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c71633308461202e565b61118482846120b1565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a361098f8184611ea2565b6001805461087a906125d5565b336001600160a01b037f000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b416146112455760405162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015260640161100c565b604080516060810182526001600160a01b039485168152928416602080850191825292851684830190815260ff97909716600090815260088452828120945185546001600160a01b031990811691881691909117865591516001860180548416918816919091179055965160029094018054821694861694909417909355600790915290932080549093169116179055565b336000908152600360205260408120805483919083906112f8908490612660565b90915550506001600160a01b0383166000818152600360205260409081902080548501905551339060008051602061280a833981519152906109839086815260200190565b600254600090801561091f5761091a61135461085e565b849083611cfe565b600061136784610995565b9050336001600160a01b038316146113d7576001600160a01b038216600090815260046020908152604080832033845290915290205460001981146113d5576113b08282612660565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b6113e1848261210b565b6113eb82826121c2565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a47f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b15801561149157600080fd5b505af11580156114a5573d6000803e3d6000fd5b506109219350506001600160a01b037f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c716915085905086612224565b6000336001600160a01b03831614611551576001600160a01b0382166000908152600460209081526040808320338452909152902054600019811461154f5761152a8582612660565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b61155a84610fba565b90508060000361157d57604051631c3b296560e11b815260040160405180910390fd5b611587818561210b565b61159182856121c2565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a47f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561163757600080fd5b505af115801561164b573d6000803e3d6000fd5b506109219350506001600160a01b037f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c716915085905083612224565b600254600090801561091f5761091a8161169f61085e565b859190611cdf565b6000807f0000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c6001600160a01b0316633b1d21a26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611708573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172c919061260f565b6001600160a01b03841660009081526003602052604081205491925090611752906108fb565b90508082106117615780611763565b815b949350505050565b428410156117bb5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f45585049524544000000000000000000604482015260640161100c565b600060016117c7610e9f565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa1580156118d3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906119095750876001600160a01b0316816001600160a01b0316145b6119465760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b604482015260640161100c565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000807f0000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c6001600160a01b0316633b1d21a26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a34919061260f565b90506000611a4182611687565b6001600160a01b038516600090815260036020526040902054909150808210611a6a5780611a6c565b815b95945050505050565b600061098f82611687565b6000611a8b34611a75565b905080600003611aae57604051632090dad160e01b815260040160405180910390fd5b611ab734611a75565b905080600003611af75760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b604482015260640161100c565b7f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b5257600080fd5b505af1158015611b66573d6000803e3d6000fd5b5050505050611b7582826120b1565b60408051348152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3611bc53482611ea2565b919050565b60006108687f0000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c6001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c51919061260f565b6040516370a0823160e01b81523060048201527f0000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c6001600160a01b0316906370a0823190602401602060405180830381865afa158015611cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd9919061260f565b906122a2565b828202811515841585830485141716611cf757600080fd5b0492915050565b828202811515841585830485141716611d1657600080fd5b6001826001830304018115150290509392505050565b60008181611d3a86866122b7565b509050600080836001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611d7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da2919061268e565b5091509150876001600160a01b0316836001600160a01b031614611dc257905b600080611de28b856001600160701b0316856001600160701b03166122e8565b9050896001600160a01b0316856001600160a01b031614611dff57905b611e136001600160a01b038b16878d612224565b6040805160008152602081019182905263022c0d9f60e01b9091526001600160a01b0387169063022c0d9f90611e5290859085903090602481016126de565b600060405180830381600087803b158015611e6c57600080fd5b505af1158015611e80573d6000803e3d6000fd5b50505050818111611e915781611e93565b805b9b9a5050505050505050505050565b604051632e1a7d4d60e01b8152600481018390527f000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c76001600160a01b031690632e1a7d4d90602401600060405180830381600087803b158015611f0457600080fd5b505af1158015611f18573d6000803e3d6000fd5b505050507f0000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c6001600160a01b0316631249c58b836040518263ffffffff1660e01b81526004016000604051808303818588803b158015611f7757600080fd5b505af1158015611f8b573d6000803e3d6000fd5b50505050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611fc69190612715565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60006040516323b872dd60e01b81528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080610db85760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b604482015260640161100c565b80600260008282546120c391906127b0565b90915550506001600160a01b03821660008181526003602090815260408083208054860190555184815260008051602061280a83398151915291015b60405180910390a35050565b60405163852a12e360e01b8152600481018390526000907f0000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c6001600160a01b03169063852a12e3906024016020604051808303816000875af1158015612175573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612199919061260f565b905080156121bd5760405163c309609960e01b81526004810182905260240161100c565b505050565b6001600160a01b038216600090815260036020526040812080548392906121ea908490612660565b90915550506002805482900390556040518181526000906001600160a01b0384169060008051602061280a833981519152906020016120ff565b600060405163a9059cbb60e01b8152836004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061229c5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015260640161100c565b50505050565b60006109218383670de0b6b3a7640000611cdf565b600080826001600160a01b0316846001600160a01b0316106122da5782846122dd565b83835b915091509250929050565b6000806122f7856103e56127c8565b9050600061230584836127c8565b9050600082612316876103e86127c8565b61232091906127b0565b905061232c81836127e7565b979650505050505050565b6000815180845260005b8181101561235d57602081850181015186830182015201612341565b8181111561236f576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006109216020830184612337565b6000602082840312156123a957600080fd5b5035919050565b80356001600160a01b0381168114611bc557600080fd5b600080604083850312156123da57600080fd5b6123e3836123b0565b946020939093013593505050565b803560ff81168114611bc557600080fd5b60006020828403121561241457600080fd5b610921826123f1565b60008060006060848603121561243257600080fd5b61243b846123b0565b9250612449602085016123b0565b9150604084013590509250925092565b60006020828403121561246b57600080fd5b610921826123b0565b6000806040838503121561248757600080fd5b82359150612497602084016123b0565b90509250929050565b600080600080600060a086880312156124b857600080fd5b6124c1866123f1565b94506124cf602087016123b0565b93506124dd604087016123b0565b92506124eb606087016123b0565b91506124f9608087016123b0565b90509295509295909350565b60008060006060848603121561251a57600080fd5b8335925061252a602085016123b0565b9150612538604085016123b0565b90509250925092565b600080600080600080600060e0888a03121561255c57600080fd5b612565886123b0565b9650612573602089016123b0565b9550604088013594506060880135935061258f608089016123f1565b925060a0880135915060c0880135905092959891949750929550565b600080604083850312156125be57600080fd5b6125c7836123b0565b9150612497602084016123b0565b600181811c908216806125e957607f821691505b60208210810361260957634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561262157600080fd5b5051919050565b60006020828403121561263a57600080fd5b8151801515811461092157600080fd5b634e487b7160e01b600052601160045260246000fd5b6000828210156126725761267261264a565b500390565b80516001600160701b0381168114611bc557600080fd5b6000806000606084860312156126a357600080fd5b6126ac84612677565b92506126ba60208501612677565b9150604084015163ffffffff811681146126d357600080fd5b809150509250925092565b84815283602082015260018060a01b038316604082015260806060820152600061270b6080830184612337565b9695505050505050565b600080835481600182811c91508083168061273157607f831692505b6020808410820361275057634e487b7160e01b86526022600452602486fd5b8180156127645760018114612775576127a2565b60ff198616895284890196506127a2565b60008a81526020902060005b8681101561279a5781548b820152908501908301612781565b505084890196505b509498975050505050505050565b600082198211156127c3576127c361264a565b500190565b60008160001904831182151516156127e2576127e261264a565b500290565b60008261280457634e487b7160e01b600052601260045260246000fd5b50049056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212207dd8e7ba39547c929ee358b5a0f863e9d6bccd97935ee5d299d99a3062b4e2b664736f6c634300080e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c70000000000000000000000008729438eb15e2c8b576fcc6aecda6a148776c0f50000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b4
-----Decoded View---------------
Arg [0] : asset_ (address): 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7
Arg [1] : reward_ (address): 0x8729438EB15e2C8B576fCc6AeCdA6A148776C0F5
Arg [2] : cEther_ (address): 0x5C0401e81Bc07Ca70fAD469b451682c0d747Ef1c
Arg [3] : manager_ (address): 0x486Af39519B4Dc9a7fCcd318217352830E8AD9b4
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7
Arg [1] : 0000000000000000000000008729438eb15e2c8b576fcc6aecda6a148776c0f5
Arg [2] : 0000000000000000000000005c0401e81bc07ca70fad469b451682c0d747ef1c
Arg [3] : 000000000000000000000000486af39519b4dc9a7fccd318217352830e8ad9b4
Deployed Bytecode Sourcemap
34452:12227:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42402:113;;;;;;;;;;;;;:::i;:::-;;;160:25:1;;;148:2;133:18;42402:113:0;;;;;;;;1043:18;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;25147:261::-;;;;;;;;;;-1:-1:-1;25147:261:0;;;;;:::i;:::-;;:::i;2520:217::-;;;;;;;;;;-1:-1:-1;2520:217:0;;;;;:::i;:::-;;:::i;:::-;;;1685:14:1;;1678:22;1660:41;;1648:2;1633:18;2520:217:0;1520:187:1;25814:259:0;;;;;;;;;;-1:-1:-1;25814:259:0;;;;;:::i;:::-;;:::i;38283:1750::-;;;;;;;;;;-1:-1:-1;38283:1750:0;;;;;:::i;:::-;;:::i;:::-;;1326:26;;;;;;;;;;;;;;;;35273:31;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2240:32:1;;;2222:51;;2210:2;2195:18;35273:31:0;2060:219:1;35553:29:0;;;;;;;;;;;;;;;3138:612;;;;;;;;;;-1:-1:-1;3138:612:0;;;;;:::i;:::-;;:::i;1099:31::-;;;;;;;;;;;;;;;;;;3010:4:1;2998:17;;;2980:36;;2968:2;2953:18;1099:31:0;2838:184:1;5480:179:0;;;;;;;;;;;;;:::i;21735:28::-;;;;;;;;;;;;;;;42733:183;;;;;;;;;;-1:-1:-1;42733:183:0;;;;;:::i;:::-;;:::i;35466:32::-;;;;;;;;;;;;;;;26081:126;;;;;;;;;;-1:-1:-1;26081:126:0;;;;;:::i;:::-;;:::i;35933:24::-;;;;;;;;;;-1:-1:-1;35933:24:0;;;;;;;;-1:-1:-1;;;;;35933:24:0;;;;;;;;;;;;;;-1:-1:-1;;;;;3866:15:1;;;3848:34;;3918:15;;;3913:2;3898:18;;3891:43;3970:15;;3950:18;;;3943:43;;;;3798:2;3783:18;35933:24:0;3608:384:1;35364:41:0;;;;;;;;;;;;;;;41888:415;;;;;;;;;;-1:-1:-1;41888:415:0;;;;;:::i;:::-;;:::i;1361:44::-;;;;;;;;;;-1:-1:-1;1361:44:0;;;;;:::i;:::-;;;;;;;;;;;;;;40129:166;;;;;;;;;;-1:-1:-1;40129:166:0;;;;;:::i;:::-;;:::i;1787:41::-;;;;;;;;;;-1:-1:-1;1787:41:0;;;;;:::i;:::-;;;;;;;;;;;;;;22686:478;;;;;;;;;;-1:-1:-1;22686:478:0;;;;;:::i;:::-;;:::i;1070:20::-;;;;;;;;;;;;;:::i;35740:47::-;;;;;;;;;;-1:-1:-1;35740:47:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;35740:47:0;;;37843:345;;;;;;;;;;-1:-1:-1;37843:345:0;;;;;:::i;:::-;;:::i;2745:385::-;;;;;;;;;;-1:-1:-1;2745:385:0;;;;;:::i;:::-;;:::i;25551:255::-;;;;;;;;;;-1:-1:-1;25551:255:0;;;;;:::i;:::-;;:::i;44358:780::-;;;;;;;;;;-1:-1:-1;44358:780:0;;;;;:::i;:::-;;:::i;45146:851::-;;;;;;;;;;-1:-1:-1;45146:851:0;;;;;:::i;:::-;;:::i;24878:261::-;;;;;;;;;;-1:-1:-1;24878:261:0;;;;;:::i;:::-;;:::i;43530:254::-;;;;;;;;;;-1:-1:-1;43530:254:0;;;;;:::i;:::-;;:::i;35842:45::-;;;;;;;;;;-1:-1:-1;35842:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35842:45:0;;;;;;;;;;35661:23;;;;;;;;;;-1:-1:-1;35661:23:0;;;;;;;;3945:1527;;;;;;;;;;-1:-1:-1;3945:1527:0;;;;;:::i;:::-;;:::i;44000:303::-;;;;;;;;;;-1:-1:-1;44000:303:0;;;;;:::i;:::-;;:::i;1414:64::-;;;;;;;;;;-1:-1:-1;1414:64:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;25416:127;;;;;;;;;;-1:-1:-1;25416:127:0;;;;;:::i;:::-;;:::i;41229:595::-;;;;;;:::i;:::-;;:::i;42402:113::-;42455:7;42482:25;:23;:25::i;:::-;42475:32;;42402:113;:::o;1043:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;25147:261::-;25254:11;;25217:7;;25337:11;;:63;;25360:40;25378:13;:11;:13::i;:::-;25360:6;;25393;25360:17;:40::i;:::-;25337:63;;;25351:6;25337:63;25330:70;25147:261;-1:-1:-1;;;25147:261:0:o;2520:217::-;2621:10;2594:4;2611:21;;;:9;:21;;;;;;;;-1:-1:-1;;;;;2611:30:0;;;;;;;;;;:39;;;2668:37;2594:4;;2611:30;;2668:37;;;;2644:6;160:25:1;;148:2;133:18;;14:177;2668:37:0;;;;;;;;-1:-1:-1;2725:4:0;2520:217;;;;;:::o;25814:259::-;25921:11;;25884:7;;26004:11;;:61;;26027:38;26043:6;26051:13;:11;:13::i;:::-;26027:6;;:38;:15;:38::i;38283:1750::-;38375:24;;;38349:23;38375:24;;;:11;:24;;;;;;;;38349:50;;;;;;;;;-1:-1:-1;;;;;38349:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;38432:27;;;:14;:27;;;;;;;;38522:51;;-1:-1:-1;;;38522:51:0;;;;;6734:36:1;;;;38567:4:0;6786:18:1;;;6779:60;38349:50:0;;38432:27;;;;;;38522:11;:23;;;;;;6707:18:1;;38522:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;38601:43:0;;-1:-1:-1;;;38601:43:0;;38638:4;38601:43;;;2222:51:1;38584:14:0;;-1:-1:-1;;;;;;38601:28:0;;;-1:-1:-1;38601:28:0;;2195:18:1;;38601:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38584:60;;38785:5;-1:-1:-1;;;;;38760:31:0;:7;:13;;;-1:-1:-1;;;;;38760:31:0;;38756:1210;;38831:13;;;;38810:43;;-1:-1:-1;;;38810:43:0;;-1:-1:-1;;;;;7231:32:1;;;38810:43:0;;;7213:51:1;7280:18;;;7273:34;;;38810:20:0;;;;;;7186:18:1;;38810:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;38871:280;38902:6;38954:11;39030:5;39102:7;:13;;;38871:12;:280::i;:::-;;38756:1210;;;39244:13;;;;39223:43;;-1:-1:-1;;;39223:43:0;;-1:-1:-1;;;;;7231:32:1;;;39223:43:0;;;7213:51:1;7280:18;;;7273:34;;;39223:20:0;;;;;;7186:18:1;;39223:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;39283:23;39309:279;39340:6;39392:11;39443:7;:13;;;39539:7;:13;;;39309:12;:279::i;:::-;39611:13;;39634;;;;;39605:60;;-1:-1:-1;;;39605:60:0;;-1:-1:-1;;;;;7231:32:1;;;39605:60:0;;;7213:51:1;7280:18;;;7273:34;;;39283:305:0;;-1:-1:-1;39605:28:0;;;;7186:18:1;;39605:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;39683:271;39714:15;39748:7;:13;;;39833:5;39905:7;:13;;;39683:12;:271::i;:::-;;39206:760;38756:1210;39991:30;;-1:-1:-1;;;39991:30:0;;40015:4;39991:30;;;2222:51:1;39978:47:0;;39991:5;-1:-1:-1;;;;;39991:15:0;;;;2195:18:1;;39991:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40023:1;39978:12;:47::i;:::-;38328:1705;;;;38283:1750;:::o;3138:612::-;-1:-1:-1;;;;;3295:15:0;;3260:4;3295:15;;;:9;:15;;;;;;;;3311:10;3295:27;;;;;;;;-1:-1:-1;;3375:28:0;;3371:80;;3435:16;3445:6;3435:7;:16;:::i;:::-;-1:-1:-1;;;;;3405:15:0;;;;;;:9;:15;;;;;;;;3421:10;3405:27;;;;;;;:46;3371:80;-1:-1:-1;;;;;3464:15:0;;;;;;:9;:15;;;;;:25;;3483:6;;3464:15;:25;;3483:6;;3464:25;:::i;:::-;;;;-1:-1:-1;;;;;;;3640:13:0;;;;;;;:9;:13;;;;;;;:23;;;;;;3692:26;3640:13;;3692:26;;;-1:-1:-1;;;;;;;;;;;3692:26:0;;;3657:6;160:25:1;;148:2;133:18;;14:177;3692:26:0;;;;;;;;-1:-1:-1;3738:4:0;;3138:612;-1:-1:-1;;;;3138:612:0:o;5480:179::-;5537:7;5581:16;5564:13;:33;:87;;5627:24;:22;:24::i;5564:87::-;-1:-1:-1;5600:24:0;;5480:179::o;42733:183::-;42816:47;;-1:-1:-1;;;42816:47:0;;-1:-1:-1;;;;;42855:6:0;2240:32:1;;42816:47:0;;;2222:51:1;-1:-1:-1;;42816:11:0;:30;;;;;;2195:18:1;;42816:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42812:61;;;-1:-1:-1;42872:1:0;;42733:183;-1:-1:-1;42733:183:0:o;42812:61::-;-1:-1:-1;;;42891:17:0;42733:183;-1:-1:-1;42733:183:0:o;26081:126::-;26149:7;26176:23;26192:6;26176:15;:23::i;41888:415::-;41991:14;42041:22;42056:6;42041:14;:22::i;:::-;42032:31;;;42068:1;42031:38;42023:62;;;;-1:-1:-1;;;42023:62:0;;8064:2:1;42023:62:0;;;8046:21:1;8103:2;8083:18;;;8076:30;-1:-1:-1;;;8122:18:1;;;8115:41;8173:18;;42023:62:0;;;;;;;;;42098:57;-1:-1:-1;;;;;42098:5:0;:22;42121:10;42141:4;42148:6;42098:22;:57::i;:::-;42168:23;42174:8;42184:6;42168:5;:23::i;:::-;42209:45;;;8376:25:1;;;8432:2;8417:18;;8410:34;;;-1:-1:-1;;;;;42209:45:0;;;42217:10;;42209:45;;8349:18:1;42209:45:0;;;;;;;42267:28;42280:6;42288;42267:12;:28::i;40129:166::-;40234:53;;-1:-1:-1;;;40234:53:0;;6764:4:1;6752:17;;40234:53:0;;;6734:36:1;40281:4:0;6786:18:1;;;6779:60;40198:14:0;;40234:11;-1:-1:-1;;;;;40234:25:0;;;;6707:18:1;;40234:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;22686:478::-;22758:14;22794:19;22806:6;22794:11;:19::i;:::-;22785:28;-1:-1:-1;22959:57:0;-1:-1:-1;;;;;22959:5:0;:22;22982:10;23002:4;22785:28;22959:22;:57::i;:::-;23029:23;23035:8;23045:6;23029:5;:23::i;:::-;23070:45;;;8376:25:1;;;8432:2;8417:18;;8410:34;;;-1:-1:-1;;;;;23070:45:0;;;23078:10;;23070:45;;8349:18:1;23070:45:0;;;;;;;23128:28;23141:6;23149;23128:12;:28::i;1070:20::-;;;;;;;:::i;37843:345::-;38026:10;-1:-1:-1;;;;;38040:7:0;38026:21;;38018:43;;;;-1:-1:-1;;;38018:43:0;;8657:2:1;38018:43:0;;;8639:21:1;8696:1;8676:18;;;8669:29;-1:-1:-1;;;8714:18:1;;;8707:39;8763:18;;38018:43:0;8455:332:1;38018:43:0;38099:29;;;;;;;;-1:-1:-1;;;;;38099:29:0;;;;;;;;;;;;;;;;;;;;;;;;38072:24;;;;;-1:-1:-1;38072:24:0;;;:11;:24;;;;;:56;;;;-1:-1:-1;;;;;;38072:56:0;;;;;;;;;;;;;;-1:-1:-1;38072:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38139:14;:27;;;;;;:41;;;;;;;;;;37843:345::o;2745:385::-;2842:10;2815:4;2832:21;;;:9;:21;;;;;:31;;2857:6;;2832:21;2815:4;;2832:31;;2857:6;;2832:31;:::i;:::-;;;;-1:-1:-1;;;;;;;3014:13:0;;;;;;:9;:13;;;;;;;:23;;;;;;3066:32;3075:10;;-1:-1:-1;;;;;;;;;;;3066:32:0;;;3031:6;160:25:1;;148:2;133:18;;14:177;25551:255:0;25654:11;;25617:7;;25737:11;;:61;;25760:38;25776:13;:11;:13::i;:::-;25760:6;;25791;25760:15;:38::i;44358:780::-;44484:14;44520:23;44536:6;44520:15;:23::i;:::-;44511:32;-1:-1:-1;44627:10:0;-1:-1:-1;;;;;44627:19:0;;;44623:249;;-1:-1:-1;;;;;44681:16:0;;44663:15;44681:16;;;:9;:16;;;;;;;;44698:10;44681:28;;;;;;;;-1:-1:-1;;44766:28:0;;44762:98;;44844:16;44854:6;44844:7;:16;:::i;:::-;-1:-1:-1;;;;;44813:16:0;;;;;;:9;:16;;;;;;;;44830:10;44813:28;;;;;;;:47;44762:98;44648:224;44623:249;44884:30;44899:6;44907;44884:14;:30::i;:::-;44927:20;44933:5;44940:6;44927:5;:20::i;:::-;44965:53;;;8376:25:1;;;8432:2;8417:18;;8410:34;;;-1:-1:-1;;;;;44965:53:0;;;;;;;;44974:10;;44965:53;;8349:18:1;44965:53:0;;;;;;;45051:5;-1:-1:-1;;;;;45029:37:0;;45074:6;45029:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45094:36:0;;-1:-1:-1;;;;;;;45094:5:0;:18;;-1:-1:-1;45113:8:0;;-1:-1:-1;45123:6:0;45094:18;:36::i;45146:851::-;45270:14;45301:10;-1:-1:-1;;;;;45301:19:0;;;45297:249;;-1:-1:-1;;;;;45355:16:0;;45337:15;45355:16;;;:9;:16;;;;;;;;45372:10;45355:28;;;;;;;;-1:-1:-1;;45440:28:0;;45436:98;;45518:16;45528:6;45518:7;:16;:::i;:::-;-1:-1:-1;;;;;45487:16:0;;;;;;:9;:16;;;;;;;;45504:10;45487:28;;;;;;;:47;45436:98;45322:224;45297:249;45647:21;45661:6;45647:13;:21::i;:::-;45638:30;;;45673:1;45637:37;45633:97;;45696:34;;-1:-1:-1;;;45696:34:0;;;;;;;;;;;45633:97;45743:30;45758:6;45766;45743:14;:30::i;:::-;45786:20;45792:5;45799:6;45786:5;:20::i;:::-;45824:53;;;8376:25:1;;;8432:2;8417:18;;8410:34;;;-1:-1:-1;;;;;45824:53:0;;;;;;;;45833:10;;45824:53;;8349:18:1;45824:53:0;;;;;;;45910:5;-1:-1:-1;;;;;45888:37:0;;45933:6;45888:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45953:36:0;;-1:-1:-1;;;;;;;45953:5:0;:18;;-1:-1:-1;45972:8:0;;-1:-1:-1;45982:6:0;45953:18;:36::i;24878:261::-;24985:11;;24948:7;;25068:11;;:63;;25091:40;25109:6;25117:13;:11;:13::i;:::-;25091:6;;:40;:17;:40::i;43530:254::-;43596:7;43616:12;43631:6;-1:-1:-1;;;;;43631:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;43698:16:0;;43658:21;43698:16;;;:9;:16;;;;;;43616:31;;-1:-1:-1;43658:21:0;43682:33;;:15;:33::i;:::-;43658:57;;43740:13;43733:4;:20;:43;;43763:13;43733:43;;;43756:4;43733:43;43726:50;43530:254;-1:-1:-1;;;;43530:254:0:o;3945:1527::-;4173:15;4161:8;:27;;4153:63;;;;-1:-1:-1;;;4153:63:0;;8994:2:1;4153:63:0;;;8976:21:1;9033:2;9013:18;;;9006:30;9072:25;9052:18;;;9045:53;9115:18;;4153:63:0;8792:347:1;4153:63:0;4386:24;4413:827;4553:18;:16;:18::i;:::-;-1:-1:-1;;;;;5007:13:0;;;;;;;:6;:13;;;;;;;;;:15;;;;;;;;4638:458;;4683:167;4638:458;;;9431:25:1;9510:18;;;9503:43;;;;9582:15;;;9562:18;;;9555:43;9614:18;;;9607:34;;;9657:19;;;9650:35;;;;9701:19;;;;9694:35;;;4638:458:0;;;;;;;;;;9403:19:1;;;4638:458:0;;;4598:525;;;;;;;;-1:-1:-1;;;4473:673:0;;;9998:27:1;10041:11;;;10034:27;;;;10077:12;;;10070:28;;;;10114:12;;4473:673:0;;;-1:-1:-1;;4473:673:0;;;;;;;;;4441:724;;4473:673;4441:724;;;;4413:827;;;;;;;;;10364:25:1;10437:4;10425:17;;10405:18;;;10398:45;10459:18;;;10452:34;;;10502:18;;;10495:34;;;10336:19;;4413:827:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4413:827:0;;-1:-1:-1;;4413:827:0;;;-1:-1:-1;;;;;;;5265:30:0;;;;;;:59;;;5319:5;-1:-1:-1;;;;;5299:25:0;:16;-1:-1:-1;;;;;5299:25:0;;5265:59;5257:86;;;;-1:-1:-1;;;5257:86:0;;10742:2:1;5257:86:0;;;10724:21:1;10781:2;10761:18;;;10754:30;-1:-1:-1;;;10800:18:1;;;10793:44;10854:18;;5257:86:0;10540:338:1;5257:86:0;-1:-1:-1;;;;;5360:27:0;;;;;;;:9;:27;;;;;;;;:36;;;;;;;;;;;;;:44;;;5433:31;160:25:1;;;5360:36:0;;5433:31;;;;;133:18:1;5433:31:0;;;;;;;3945:1527;;;;;;;:::o;44000:303::-;44064:7;44084:12;44099:6;-1:-1:-1;;;;;44099:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44084:31;;44126:20;44149:21;44165:4;44149:15;:21::i;:::-;-1:-1:-1;;;;;44204:16:0;;44181:20;44204:16;;;:9;:16;;;;;;44126:44;;-1:-1:-1;44238:27:0;;;:57;;44283:12;44238:57;;;44268:12;44238:57;44231:64;44000:303;-1:-1:-1;;;;;44000:303:0:o;25416:127::-;25485:7;25512:23;25528:6;25512:15;:23::i;41229:595::-;41315:14;41437:25;41452:9;41437:14;:25::i;:::-;41428:34;;;41467:1;41427:41;41423:101;;41490:34;;-1:-1:-1;;;41490:34:0;;;;;;;;;;;41423:101;41553:25;41568:9;41553:14;:25::i;:::-;41544:34;;;41583:1;41543:41;41535:65;;;;-1:-1:-1;;;41535:65:0;;8064:2:1;41535:65:0;;;8046:21:1;8103:2;8083:18;;;8076:30;-1:-1:-1;;;8122:18:1;;;8115:41;8173:18;;41535:65:0;7862:335:1;41535:65:0;41635:5;-1:-1:-1;;;;;41613:37:0;;41658:9;41613:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41683:23;41689:8;41699:6;41683:5;:23::i;:::-;41724:48;;;41754:9;8376:25:1;;8432:2;8417:18;;8410:34;;;-1:-1:-1;;;;;41724:48:0;;;41732:10;;41724:48;;8349:18:1;41724:48:0;;;;;;;41785:31;41798:9;41809:6;41785:12;:31::i;:::-;41229:595;;;:::o;40811:209::-;40869:7;40909:103;40970:6;-1:-1:-1;;;;;40970:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40909:31;;-1:-1:-1;;;40909:31:0;;40934:4;40909:31;;;2222:51:1;40909:6:0;-1:-1:-1;;;;;40909:16:0;;;;2195:18:1;;40909:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:42;;:103::i;14267:552::-;14480:9;;;14614:19;;14607:27;14639:9;;14653;;;14650:16;;14636:31;14603:65;14593:123;;14699:1;14696;14689:12;14593:123;14782:19;;14267:552;-1:-1:-1;;14267:552:0:o;14827:771::-;15038:9;;;15172:19;;15165:27;15197:9;;15211;;;15208:16;;15194:31;15161:65;15151:123;;15257:1;15254;15247:12;15151:123;15577:1;15563:11;15559:1;15556;15552:9;15548:27;15544:35;15539:1;15532:9;15525:17;15521:59;15516:64;;14827:771;;;;;:::o;32050:828::-;32198:7;32237:9;32198:7;32279:30;32290:9;32301:7;32279:10;:30::i;:::-;32258:51;;;32321:16;32339;32361:4;-1:-1:-1;;;;;32361:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32320:59;;;;;32404:9;-1:-1:-1;;;;;32394:19:0;:6;-1:-1:-1;;;;;32394:19:0;;32390:68;;32439:8;32390:68;32469:18;32502;32523:42;32536:8;32546;-1:-1:-1;;;;;32523:42:0;32556:8;-1:-1:-1;;;;;32523:42:0;:12;:42::i;:::-;32502:63;;32590:9;-1:-1:-1;;;;;32580:19:0;:6;-1:-1:-1;;;;;32580:19:0;;32576:89;;32642:10;32576:89;32676:54;-1:-1:-1;;;;;32676:29:0;;32714:4;32721:8;32676:29;:54::i;:::-;32790:12;;;32800:1;32790:12;;;;;;;;;-1:-1:-1;;;32741:62:0;;;-1:-1:-1;;;;;32741:9:0;;;;;:62;;32751:10;;32763;;32783:4;;32741:62;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32834:10;32821;:23;:49;;32860:10;32821:49;;;32847:10;32821:49;32814:56;32050:828;-1:-1:-1;;;;;;;;;;;32050:828:0:o;41028:193::-;41104:46;;-1:-1:-1;;;41104:46:0;;;;;160:25:1;;;41126:5:0;-1:-1:-1;;;;;41104:38:0;;;;133:18:1;;41104:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41185:6;-1:-1:-1;;;;;41185:11:0;;41204:6;41185:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41028:193;;:::o;5667:457::-;5732:7;5833:95;5967:4;5951:22;;;;;;:::i;:::-;;;;;;;;;;5800:301;;;13624:25:1;;;;13665:18;;13658:34;;;;5996:14:0;13708:18:1;;;13701:34;6033:13:0;13751:18:1;;;13744:34;6077:4:0;13794:19:1;;;13787:61;13596:19;;5800:301:0;;;;;;;;;;;;5772:344;;;;;;5752:364;;5667:457;:::o;8206:1604::-;8350:12;8481:4;8475:11;-1:-1:-1;;;8607:17:0;8600:93;8741:4;8737:1;8718:17;8714:25;8707:39;8826:2;8821;8802:17;8798:26;8791:38;8907:6;8902:2;8883:17;8879:26;8872:42;9721:2;9718:1;9713:3;9694:17;9691:1;9684:5;9677;9672:52;9235:16;9228:24;9222:2;9204:16;9201:24;9197:1;9193;9187:8;9184:15;9180:46;9177:76;8974:765;8963:776;;;9770:7;9762:40;;;;-1:-1:-1;;;9762:40:0;;14061:2:1;9762:40:0;;;14043:21:1;14100:2;14080:18;;;14073:30;-1:-1:-1;;;14119:18:1;;;14112:50;14179:18;;9762:40:0;13859:344:1;6324:335:0;6410:6;6395:11;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;6567:13:0;;;;;;:9;:13;;;;;;;;:23;;;;;;6619:32;160:25:1;;;-1:-1:-1;;;;;;;;;;;6619:32:0;133:18:1;6619:32:0;;;;;;;;6324:335;;:::o;40494:309::-;40652:31;;-1:-1:-1;;;40652:31:0;;;;;160:25:1;;;40632:17:0;;40652:6;-1:-1:-1;;;;;40652:23:0;;;;133:18:1;;40652:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40632:51;-1:-1:-1;40698:21:0;;40694:102;;40743:41;;-1:-1:-1;;;40743:41:0;;;;;160:25:1;;;133:18;;40743:41:0;14:177:1;40694:102:0;40561:242;40494:309;;:::o;6667:338::-;-1:-1:-1;;;;;6740:15:0;;;;;;:9;:15;;;;;:25;;6759:6;;6740:15;:25;;6759:6;;6740:25;:::i;:::-;;;;-1:-1:-1;;6913:11:0;:21;;;;;;;6963:34;;160:25:1;;;-1:-1:-1;;;;;;;6963:34:0;;;-1:-1:-1;;;;;;;;;;;6963:34:0;148:2:1;133:18;6963:34:0;14:177:1;9818:1485:0;9935:12;10066:4;10060:11;-1:-1:-1;;;10192:17:0;10185:93;10326:2;10322:1;10303:17;10299:25;10292:37;10407:6;10402:2;10383:17;10379:26;10372:42;11219:2;11216:1;11212:2;11193:17;11190:1;11183:5;11176;11171:51;10735:16;10728:24;10722:2;10704:16;10701:24;10697:1;10693;10687:8;10684:15;10680:46;10677:76;10474:763;10463:774;;;11268:7;11260:35;;;;-1:-1:-1;;;11260:35:0;;14543:2:1;11260:35:0;;;14525:21:1;14582:2;14562:18;;;14555:30;-1:-1:-1;;;14601:18:1;;;14594:45;14656:18;;11260:35:0;14341:339:1;11260:35:0;9924:1379;9818:1485;;;:::o;13387:166::-;13452:7;13479:21;13490:1;13493;13336:4;13479:10;:21::i;33935:204::-;34037:7;34046;34087:6;-1:-1:-1;;;;;34078:15:0;:6;-1:-1:-1;;;;;34078:15:0;;:53;;34116:6;34124;34078:53;;;34097:6;34105;34078:53;34071:60;;;;33935:204;;;;;:::o;33243:379::-;33379:7;;33425:14;:8;33436:3;33425:14;:::i;:::-;33399:40;-1:-1:-1;33450:17:0;33470:30;33489:10;33399:40;33470:30;:::i;:::-;33450:50;-1:-1:-1;33511:19:0;33555:15;33534:16;:9;33546:4;33534:16;:::i;:::-;33533:38;;;;:::i;:::-;33511:60;-1:-1:-1;33589:25:0;33511:60;33589:9;:25;:::i;:::-;33582:32;33243:379;-1:-1:-1;;;;;;;33243:379:0:o;196:472:1:-;238:3;276:5;270:12;303:6;298:3;291:19;328:1;338:162;352:6;349:1;346:13;338:162;;;414:4;470:13;;;466:22;;460:29;442:11;;;438:20;;431:59;367:12;338:162;;;518:6;515:1;512:13;509:87;;;584:1;577:4;568:6;563:3;559:16;555:27;548:38;509:87;-1:-1:-1;650:2:1;629:15;-1:-1:-1;;625:29:1;616:39;;;;657:4;612:50;;196:472;-1:-1:-1;;196:472:1:o;673:220::-;822:2;811:9;804:21;785:4;842:45;883:2;872:9;868:18;860:6;842:45;:::i;898:180::-;957:6;1010:2;998:9;989:7;985:23;981:32;978:52;;;1026:1;1023;1016:12;978:52;-1:-1:-1;1049:23:1;;898:180;-1:-1:-1;898:180:1:o;1083:173::-;1151:20;;-1:-1:-1;;;;;1200:31:1;;1190:42;;1180:70;;1246:1;1243;1236:12;1261:254;1329:6;1337;1390:2;1378:9;1369:7;1365:23;1361:32;1358:52;;;1406:1;1403;1396:12;1358:52;1429:29;1448:9;1429:29;:::i;:::-;1419:39;1505:2;1490:18;;;;1477:32;;-1:-1:-1;;;1261:254:1:o;1712:156::-;1778:20;;1838:4;1827:16;;1817:27;;1807:55;;1858:1;1855;1848:12;1873:182;1930:6;1983:2;1971:9;1962:7;1958:23;1954:32;1951:52;;;1999:1;1996;1989:12;1951:52;2022:27;2039:9;2022:27;:::i;2505:328::-;2582:6;2590;2598;2651:2;2639:9;2630:7;2626:23;2622:32;2619:52;;;2667:1;2664;2657:12;2619:52;2690:29;2709:9;2690:29;:::i;:::-;2680:39;;2738:38;2772:2;2761:9;2757:18;2738:38;:::i;:::-;2728:48;;2823:2;2812:9;2808:18;2795:32;2785:42;;2505:328;;;;;:::o;3209:186::-;3268:6;3321:2;3309:9;3300:7;3296:23;3292:32;3289:52;;;3337:1;3334;3327:12;3289:52;3360:29;3379:9;3360:29;:::i;4226:254::-;4294:6;4302;4355:2;4343:9;4334:7;4330:23;4326:32;4323:52;;;4371:1;4368;4361:12;4323:52;4407:9;4394:23;4384:33;;4436:38;4470:2;4459:9;4455:18;4436:38;:::i;:::-;4426:48;;4226:254;;;;;:::o;4485:480::-;4578:6;4586;4594;4602;4610;4663:3;4651:9;4642:7;4638:23;4634:33;4631:53;;;4680:1;4677;4670:12;4631:53;4703:27;4720:9;4703:27;:::i;:::-;4693:37;;4749:38;4783:2;4772:9;4768:18;4749:38;:::i;:::-;4739:48;;4806:38;4840:2;4829:9;4825:18;4806:38;:::i;:::-;4796:48;;4863:38;4897:2;4886:9;4882:18;4863:38;:::i;:::-;4853:48;;4920:39;4954:3;4943:9;4939:19;4920:39;:::i;:::-;4910:49;;4485:480;;;;;;;;:::o;4970:328::-;5047:6;5055;5063;5116:2;5104:9;5095:7;5091:23;5087:32;5084:52;;;5132:1;5129;5122:12;5084:52;5168:9;5155:23;5145:33;;5197:38;5231:2;5220:9;5216:18;5197:38;:::i;:::-;5187:48;;5254:38;5288:2;5277:9;5273:18;5254:38;:::i;:::-;5244:48;;4970:328;;;;;:::o;5303:606::-;5414:6;5422;5430;5438;5446;5454;5462;5515:3;5503:9;5494:7;5490:23;5486:33;5483:53;;;5532:1;5529;5522:12;5483:53;5555:29;5574:9;5555:29;:::i;:::-;5545:39;;5603:38;5637:2;5626:9;5622:18;5603:38;:::i;:::-;5593:48;;5688:2;5677:9;5673:18;5660:32;5650:42;;5739:2;5728:9;5724:18;5711:32;5701:42;;5762:37;5794:3;5783:9;5779:19;5762:37;:::i;:::-;5752:47;;5846:3;5835:9;5831:19;5818:33;5808:43;;5898:3;5887:9;5883:19;5870:33;5860:43;;5303:606;;;;;;;;;;:::o;5914:260::-;5982:6;5990;6043:2;6031:9;6022:7;6018:23;6014:32;6011:52;;;6059:1;6056;6049:12;6011:52;6082:29;6101:9;6082:29;:::i;:::-;6072:39;;6130:38;6164:2;6153:9;6149:18;6130:38;:::i;6179:380::-;6258:1;6254:12;;;;6301;;;6322:61;;6376:4;6368:6;6364:17;6354:27;;6322:61;6429:2;6421:6;6418:14;6398:18;6395:38;6392:161;;6475:10;6470:3;6466:20;6463:1;6456:31;6510:4;6507:1;6500:15;6538:4;6535:1;6528:15;6392:161;;6179:380;;;:::o;6850:184::-;6920:6;6973:2;6961:9;6952:7;6948:23;6944:32;6941:52;;;6989:1;6986;6979:12;6941:52;-1:-1:-1;7012:16:1;;6850:184;-1:-1:-1;6850:184:1:o;7318:277::-;7385:6;7438:2;7426:9;7417:7;7413:23;7409:32;7406:52;;;7454:1;7451;7444:12;7406:52;7486:9;7480:16;7539:5;7532:13;7525:21;7518:5;7515:32;7505:60;;7561:1;7558;7551:12;7600:127;7661:10;7656:3;7652:20;7649:1;7642:31;7692:4;7689:1;7682:15;7716:4;7713:1;7706:15;7732:125;7772:4;7800:1;7797;7794:8;7791:34;;;7805:18;;:::i;:::-;-1:-1:-1;7842:9:1;;7732:125::o;10883:188::-;10962:13;;-1:-1:-1;;;;;11004:42:1;;10994:53;;10984:81;;11061:1;11058;11051:12;11076:450;11163:6;11171;11179;11232:2;11220:9;11211:7;11207:23;11203:32;11200:52;;;11248:1;11245;11238:12;11200:52;11271:40;11301:9;11271:40;:::i;:::-;11261:50;;11330:49;11375:2;11364:9;11360:18;11330:49;:::i;:::-;11320:59;;11422:2;11411:9;11407:18;11401:25;11466:10;11459:5;11455:22;11448:5;11445:33;11435:61;;11492:1;11489;11482:12;11435:61;11515:5;11505:15;;;11076:450;;;;;:::o;11663:459::-;11894:6;11883:9;11876:25;11937:6;11932:2;11921:9;11917:18;11910:34;12009:1;12005;12000:3;11996:11;11992:19;11984:6;11980:32;11975:2;11964:9;11960:18;11953:60;12049:3;12044:2;12033:9;12029:18;12022:31;11857:4;12070:46;12111:3;12100:9;12096:19;12088:6;12070:46;:::i;:::-;12062:54;11663:459;-1:-1:-1;;;;;;11663:459:1:o;12256:1104::-;12386:3;12415:1;12448:6;12442:13;12478:3;12500:1;12528:9;12524:2;12520:18;12510:28;;12588:2;12577:9;12573:18;12610;12600:61;;12654:4;12646:6;12642:17;12632:27;;12600:61;12680:2;12728;12720:6;12717:14;12697:18;12694:38;12691:165;;-1:-1:-1;;;12755:33:1;;12811:4;12808:1;12801:15;12841:4;12762:3;12829:17;12691:165;12872:18;12899:104;;;;13017:1;13012:323;;;;12865:470;;12899:104;-1:-1:-1;;12932:24:1;;12920:37;;12977:16;;;;-1:-1:-1;12899:104:1;;13012:323;12203:1;12196:14;;;12240:4;12227:18;;13110:1;13124:165;13138:6;13135:1;13132:13;13124:165;;;13216:14;;13203:11;;;13196:35;13259:16;;;;13153:10;;13124:165;;;13128:3;;13318:6;13313:3;13309:16;13302:23;;12865:470;-1:-1:-1;13351:3:1;;12256:1104;-1:-1:-1;;;;;;;;12256:1104:1:o;14208:128::-;14248:3;14279:1;14275:6;14272:1;14269:13;14266:39;;;14285:18;;:::i;:::-;-1:-1:-1;14321:9:1;;14208:128::o;14685:168::-;14725:7;14791:1;14787;14783:6;14779:14;14776:1;14773:21;14768:1;14761:9;14754:17;14750:45;14747:71;;;14798:18;;:::i;:::-;-1:-1:-1;14838:9:1;;14685:168::o;14858:217::-;14898:1;14924;14914:132;;14968:10;14963:3;14959:20;14956:1;14949:31;15003:4;15000:1;14993:15;15031:4;15028:1;15021:15;14914:132;-1:-1:-1;15060:9:1;;14858:217::o
Swarm Source
ipfs://7dd8e7ba39547c929ee358b5a0f863e9d6bccd97935ee5d299d99a3062b4e2b6
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
BSC | 100.00% | $0.02558 | 112.8787 | $2.89 |
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.