Contract Overview
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0xd7e70773ed7d778f26c43961a431c462da57c5f788efc9cbcc6f4e79ab0e4a9d | 0x6101c060 | 52588271 | 160 days 6 hrs ago | 0xdc6ca6116d69171b4aea7acbd1a739cf7c565f53 | IN | Contract Creation | 0 FTM | 0.109873706332 |
[ Download CSV Export ]
Latest 1 internal transaction
Parent Txn Hash | Block | From | To | Value | |||
---|---|---|---|---|---|---|---|
0xd7e70773ed7d778f26c43961a431c462da57c5f788efc9cbcc6f4e79ab0e4a9d | 52588271 | 160 days 6 hrs ago | 0xdc6ca6116d69171b4aea7acbd1a739cf7c565f53 | Contract Creation | 0 FTM |
[ Download CSV Export ]
Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0xd0b072360aDB8318467CD9686a71e361096273Ed
Contract Name:
GeistERC4626Reinvest
Compiler Version
v0.8.14+commit.80d49f37
Contract Source Code (Solidity)
/** *Submitted for verification at FtmScan.com on 2022-12-20 */ // 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 {} } interface IMultiFeeDistribution { function getReward() external; function exit() external; } // Aave lending pool interface // Documentation: https://docs.aave.com/developers/the-core-protocol/lendingpool/ilendingpool // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. interface ILendingPool { struct ReserveConfigurationMap { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus //bit 48-55: Decimals //bit 56: Reserve is active //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled //bit 60-63: reserved //bit 64-79: reserve factor uint256 data; } struct ReserveData { ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; //the current stable borrow rate. Expressed in ray uint128 currentStableBorrowRate; uint40 lastUpdateTimestamp; //tokens addresses address aTokenAddress; address stableDebtTokenAddress; address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the id of the reserve. Represents the position in the list of the active reserves uint8 id; } /** * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User deposits 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to deposit * @param amount The amount to be deposited * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * */ function deposit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to Address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet * @return The final amount withdrawn * */ function withdraw( address asset, uint256 amount, address to ) external returns (uint256); /** * @dev Returns the state and configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The state of the reserve * */ function getReserveData(address asset) external view returns (ReserveData memory); function paused() external view returns (bool); } 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); } } /// @title GeistERC4626Reinvest contract GeistERC4626Reinvest is ERC4626 { address public immutable manager; /// ----------------------------------------------------------------------- /// Libraries usage /// ----------------------------------------------------------------------- using SafeTransferLib for ERC20; /// ----------------------------------------------------------------------- /// Constants /// ----------------------------------------------------------------------- uint256 internal constant ACTIVE_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFF; uint256 internal constant FROZEN_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFF; address public immutable spookySwap = 0xF491e7B69E4244ad4002BC14e878a34207E38c29; /// ----------------------------------------------------------------------- /// Immutable params /// ----------------------------------------------------------------------- /// @notice The Aave aToken contract ERC20 public immutable aToken; /// @notice The Aave liquidity mining contract IMultiFeeDistribution public immutable rewards; /// @notice GEIST token (reward) ERC20 public immutable rewardToken; /// @notice The Aave LendingPool contract ILendingPool public immutable lendingPool; /// @notice Pointer to swapInfo swapInfo public SwapInfo; /// Compact struct to make two swaps (SpookySwap on FTM) /// A => B (using pair1) then B => asset (of BaseWrapper) (using pair2) struct swapInfo { address token; address pair1; address pair2; } /// ----------------------------------------------------------------------- /// Constructor /// ----------------------------------------------------------------------- constructor( ERC20 asset_, ERC20 aToken_, IMultiFeeDistribution rewards_, ILendingPool lendingPool_, ERC20 rewardToken_, address manager_ ) ERC4626(asset_, _vaultName(asset_), _vaultSymbol(asset_)) { aToken = aToken_; rewards = rewards_; lendingPool = lendingPool_; rewardToken = rewardToken_; manager = manager_; } /// ----------------------------------------------------------------------- /// Geist Rewards Module /// ----------------------------------------------------------------------- function setRoute( address token, address pair1, address pair2 ) external { require(msg.sender == manager, "onlyOwner"); SwapInfo = swapInfo(token, pair1, pair2); } /// @notice Claims liquidity providing rewards from Geist for this contract /// MultiFeeDistribution on Geist accrues GEIST token as reward for supplying liq function harvest() external { rewards.getReward(); rewards.exit(); uint256 earned = rewardToken.balanceOf(address(this)); if (SwapInfo.token == address(asset)) { rewardToken.approve(SwapInfo.pair1, earned); DexSwap.swap( earned, address(rewardToken), // from GEIST SwapInfo.token, /// to intermediary token FTM (no direct pools) SwapInfo.pair1 /// pairToken (pool) ); } else { rewardToken.approve(SwapInfo.pair1, earned); /// Swap on Spooky uint256 swapTokenAmount = DexSwap.swap( earned, address(rewardToken), // from GEIST SwapInfo.token, /// to intermediary token FTM (no direct pools) SwapInfo.pair1 /// pairToken (pool) ); ERC20(SwapInfo.token).approve(SwapInfo.pair2, swapTokenAmount); swapTokenAmount = DexSwap.swap( swapTokenAmount, SwapInfo.token, // from received FTM address(asset), /// to target underlying of BaseWrapper Vault SwapInfo.pair2 /// pairToken (pool) ); } afterDeposit(asset.balanceOf(address(this)), 0); } /// ----------------------------------------------------------------------- /// ERC4626 overrides /// ----------------------------------------------------------------------- function withdraw( uint256 assets, address receiver, address owner ) public virtual 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); // withdraw assets directly from Aave lendingPool.withdraw(address(asset), assets, receiver); } function redeem( uint256 shares, address receiver, address owner ) public virtual 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. require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS"); beforeWithdraw(assets, shares); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); // withdraw assets directly from Aave lendingPool.withdraw(address(asset), assets, receiver); } function totalAssets() public view virtual override returns (uint256) { return aToken.balanceOf(address(this)); } function afterDeposit( uint256 assets, uint256 /*shares*/ ) internal virtual override { /// ----------------------------------------------------------------------- /// Deposit assets into Aave /// ----------------------------------------------------------------------- // approve to lendingPool asset.safeApprove(address(lendingPool), assets); // deposit into lendingPool lendingPool.deposit(address(asset), assets, address(this), 0); } function maxDeposit(address) public view virtual override returns (uint256) { // check if pool is paused if (lendingPool.paused()) { return 0; } // check if asset is paused uint256 configData = lendingPool .getReserveData(address(asset)) .configuration .data; if (!(_getActive(configData) && !_getFrozen(configData))) { return 0; } return type(uint256).max; } function maxMint(address) public view virtual override returns (uint256) { // check if pool is paused if (lendingPool.paused()) { return 0; } // check if asset is paused uint256 configData = lendingPool .getReserveData(address(asset)) .configuration .data; if (!(_getActive(configData) && !_getFrozen(configData))) { return 0; } return type(uint256).max; } function maxWithdraw(address owner) public view virtual override returns (uint256) { // check if pool is paused if (lendingPool.paused()) { return 0; } // check if asset is paused uint256 configData = lendingPool .getReserveData(address(asset)) .configuration .data; if (!_getActive(configData)) { return 0; } uint256 cash = asset.balanceOf(address(aToken)); uint256 assetsBalance = convertToAssets(balanceOf[owner]); return cash < assetsBalance ? cash : assetsBalance; } function maxRedeem(address owner) public view virtual override returns (uint256) { // check if pool is paused if (lendingPool.paused()) { return 0; } // check if asset is paused uint256 configData = lendingPool .getReserveData(address(asset)) .configuration .data; if (!_getActive(configData)) { return 0; } uint256 cash = asset.balanceOf(address(aToken)); uint256 cashInShares = convertToShares(cash); uint256 shareBalance = balanceOf[owner]; return cashInShares < shareBalance ? cashInShares : shareBalance; } /// ----------------------------------------------------------------------- /// ERC20 metadata generation /// ----------------------------------------------------------------------- function _vaultName(ERC20 asset_) internal view virtual returns (string memory vaultName) { vaultName = string.concat("ERC4626-Wrapped Geist-", asset_.symbol()); } function _vaultSymbol(ERC20 asset_) internal view virtual returns (string memory vaultSymbol) { vaultSymbol = string.concat("gs4626-", asset_.symbol()); } /// ----------------------------------------------------------------------- /// Internal functions /// ----------------------------------------------------------------------- function _getActive(uint256 configData) internal pure returns (bool) { return configData & ~ACTIVE_MASK != 0; } function _getFrozen(uint256 configData) internal pure returns (bool) { return configData & ~FROZEN_MASK != 0; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ERC20","name":"asset_","type":"address"},{"internalType":"contract ERC20","name":"aToken_","type":"address"},{"internalType":"contract IMultiFeeDistribution","name":"rewards_","type":"address"},{"internalType":"contract ILendingPool","name":"lendingPool_","type":"address"},{"internalType":"contract ERC20","name":"rewardToken_","type":"address"},{"internalType":"address","name":"manager_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"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":[],"name":"aToken","outputs":[{"internalType":"contract ERC20","name":"","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":[{"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":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lendingPool","outputs":[{"internalType":"contract ILendingPool","name":"","type":"address"}],"stateMutability":"view","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":"rewardToken","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewards","outputs":[{"internalType":"contract IMultiFeeDistribution","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":[],"name":"spookySwap","outputs":[{"internalType":"address","name":"","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"}]
Contract Creation Code
6101c060405273f491e7b69e4244ad4002bc14e878a34207e38c29610120523480156200002b57600080fd5b5060405162003130380380620031308339810160408190526200004e91620003b5565b856200005a816200014a565b6200006588620001dd565b8181846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000a6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000cc919062000449565b8251620000e1906000906020860190620002f6565b508151620000f7906001906020850190620002f6565b5060ff81166080524660a0526200010d6200025a565b60c0525050506001600160a01b0392831660e052505094851661014052928416610160529083166101a052821661018052166101005250620006cd565b6060816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200018b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001b59190810190620004be565b604051602001620001c7919062000576565b6040516020818303038152906040529050919050565b6060816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200021e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620002489190810190620004be565b604051602001620001c79190620005bd565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516200028e91906200062a565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b8280546200030490620005ee565b90600052602060002090601f01602090048101928262000328576000855562000373565b82601f106200034357805160ff191683800117855562000373565b8280016001018555821562000373579182015b828111156200037357825182559160200191906001019062000356565b506200038192915062000385565b5090565b5b8082111562000381576000815560010162000386565b6001600160a01b0381168114620003b257600080fd5b50565b60008060008060008060c08789031215620003cf57600080fd5b8651620003dc816200039c565b6020880151909650620003ef816200039c565b604088015190955062000402816200039c565b606088015190945062000415816200039c565b608088015190935062000428816200039c565b60a08801519092506200043b816200039c565b809150509295509295509295565b6000602082840312156200045c57600080fd5b815160ff811681146200046e57600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004a85781810151838201526020016200048e565b83811115620004b8576000848401525b50505050565b600060208284031215620004d157600080fd5b81516001600160401b0380821115620004e957600080fd5b818401915084601f830112620004fe57600080fd5b81518181111562000513576200051362000475565b604051601f8201601f19908116603f011681019083821181831017156200053e576200053e62000475565b816040528281528760208487010111156200055857600080fd5b6200056b8360208301602088016200048b565b979650505050505050565b7f455243343632362d577261707065642047656973742d00000000000000000000815260008251620005b08160168501602087016200048b565b9190910160160192915050565b666773343632362d60c81b815260008251620005e18160078501602087016200048b565b9190910160070192915050565b600181811c908216806200060357607f821691505b6020821081036200062457634e487b7160e01b600052602260045260246000fd5b50919050565b600080835481600182811c9150808316806200064757607f831692505b602080841082036200066757634e487b7160e01b86526022600452602486fd5b8180156200067e57600181146200069057620006bf565b60ff19861689528489019650620006bf565b60008a81526020902060005b86811015620006b75781548b8201529085019083016200069c565b505084890196505b509498975050505050505050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516128f26200083e600039600081816104ca0152818161090e015281816109dd0152818161127201528181611444015281816114970152818161156601528181611923015281816119f201528181611ebd0152611f350152600081816105da01528181610b8001528181610c5501528181610cd301528181610d340152610db501526000818161047c01528181610a850152610af80152600081816104a301528181610614015281816116030152611a8f0152600061041a0152600081816103630152611b74015260008181610307015281816109b201528181610c0401528181610e7d01528181610ebf01528181610fa4015281816110400152818161123b0152818161140d0152818161153b0152818161162e015281816119c701528181611aba01528181611e9b0152611ef9015260006108e8015260006108b8015260006102c601526128f26000f3fe608060405234801561001057600080fd5b50600436106102275760003560e01c80637ecebe0011610130578063ba087652116100b8578063d905777e1161007c578063d905777e14610571578063dd62ed3e14610584578063ec42be77146105af578063ef8b30f7146105c2578063f7c618c1146105d557600080fd5b8063ba08765214610525578063c63d75b614610341578063c6e6f59214610538578063ce96cb771461054b578063d505accf1461055e57600080fd5b8063a0c1f15e116100ff578063a0c1f15e1461049e578063a59a9973146104c5578063a9059cbb146104ec578063b3d7f6b9146104ff578063b460af941461051257600080fd5b80637ecebe001461043c57806394bf804d1461045c57806395d89b411461046f5780639ec5a8941461047757600080fd5b806338d52e0f116101b35780634cdad506116101825780634cdad5061461038557806353104b8e146103985780636e553f65146103e257806370a08231146103f55780637c71e1191461041557600080fd5b806338d52e0f14610302578063402d267d146103415780634641257d14610354578063481c6a751461035e57600080fd5b80630a28a477116101fa5780630a28a4771461029257806318160ddd146102a557806323b872dd146102ae578063313ce567146102c15780633644e515146102fa57600080fd5b806301e1d1141461022c57806306fdde031461024757806307a2d13a1461025c578063095ea7b31461026f575b600080fd5b6102346105fc565b6040519081526020015b60405180910390f35b61024f61068c565b60405161023e919061229d565b61023461026a3660046122b0565b61071a565b61028261027d3660046122de565b610747565b604051901515815260200161023e565b6102346102a03660046122b0565b6107b4565b61023460025481565b6102826102bc36600461230a565b6107d4565b6102e87f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161023e565b6102346108b4565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161023e565b61023461034f36600461234b565b61090a565b61035c610a83565b005b6103297f000000000000000000000000000000000000000000000000000000000000000081565b6102346103933660046122b0565b610f3c565b6006546007546008546103b8926001600160a01b03908116928116911683565b604080516001600160a01b039485168152928416602084015292169181019190915260600161023e565b6102346103f0366004612368565b610f47565b61023461040336600461234b565b60036020526000908152604090205481565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b61023461044a36600461234b565b60056020526000908152604090205481565b61023461046a366004612368565b611026565b61024f6110c2565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b6102826104fa3660046122de565b6110cf565b61023461050d3660046122b0565b611135565b610234610520366004612398565b611154565b610234610533366004612398565b6112e8565b6102346105463660046122b0565b611473565b61023461055936600461234b565b611493565b61035c61056c3660046123e9565b6116db565b61023461057f36600461234b565b61191f565b61023461059236600461245a565b600460209081526000928352604080842090915290825290205481565b61035c6105bd366004612488565b611b69565b6102346105d03660046122b0565b611c26565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610663573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068791906124b8565b905090565b60008054610699906124d1565b80601f01602080910402602001604051908101604052809291908181526020018280546106c5906124d1565b80156107125780601f106106e757610100808354040283529160200191610712565b820191906000526020600020905b8154815290600101906020018083116106f557829003601f168201915b505050505081565b600254600090801561073e576107396107316105fc565b849083611c31565b610740565b825b9392505050565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906107a29086815260200190565b60405180910390a35060015b92915050565b600254600090801561073e57610739816107cc6105fc565b859190611c50565b6001600160a01b038316600090815260046020908152604080832033845290915281205460001981146108305761080b8382612521565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610858908490612521565b90915550506001600160a01b038085166000818152600360205260409081902080548701905551909187169060008051602061289d833981519152906108a19087815260200190565b60405180910390a3506001949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146108e557610687611c7e565b507f000000000000000000000000000000000000000000000000000000000000000090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561096a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098e9190612538565b1561099b57506000919050565b6040516335ea6a7560e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906335ea6a759060240161018060405180830381865afa158015610a27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4b9190612632565b51519050600160381b811615158015610a6c57506702000000000000008116155b610a795750600092915050565b5060001992915050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633d18b9126040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ade57600080fd5b505af1158015610af2573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e9fad8ee6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b5157600080fd5b505af1158015610b65573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691506370a0823190602401602060405180830381865afa158015610bd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf491906124b8565b6006549091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911603610d0b5760075460405163095ea7b360e01b81526001600160a01b039182166004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000009091169063095ea7b3906044016020604051808303816000875af1158015610ca0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc49190612538565b50600654600754610d059183917f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b039081169116611d18565b50610ea6565b60075460405163095ea7b360e01b81526001600160a01b039182166004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000009091169063095ea7b3906044016020604051808303816000875af1158015610d7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da39190612538565b50600654600754600091610de79184917f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b039182169116611d18565b60065460085460405163095ea7b360e01b81526001600160a01b03918216600482015260248101849052929350169063095ea7b3906044016020604051808303816000875af1158015610e3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e629190612538565b50600654600854610ea39183916001600160a01b03918216917f00000000000000000000000000000000000000000000000000000000000000009116611d18565b50505b6040516370a0823160e01b8152306004820152610f39907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610f0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3291906124b8565b6000611e8e565b50565b60006107ae8261071a565b6000610f5283611c26565b905080600003610f975760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b60448201526064015b60405180910390fd5b610fcc6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333086611f95565b610fd6828261201f565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a36107ae8382611e8e565b600061103183611135565b90506110686001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084611f95565b611072828461201f565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a36107ae8184611e8e565b60018054610699906124d1565b336000908152600360205260408120805483919083906110f0908490612521565b90915550506001600160a01b0383166000818152600360205260409081902080548501905551339060008051602061289d833981519152906107a29086815260200190565b600254600090801561073e5761073961114c6105fc565b849083611c50565b600061115f846107b4565b9050336001600160a01b038316146111cf576001600160a01b038216600090815260046020908152604080832033845290915290205460001981146111cd576111a88282612521565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b6111d98282612079565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4604051631a4ca37b60e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820186905284811660448301527f000000000000000000000000000000000000000000000000000000000000000016906369328dec906064015b6020604051808303816000875af11580156112bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e091906124b8565b509392505050565b6000336001600160a01b03831614611358576001600160a01b03821660009081526004602090815260408083203384529091529020546000198114611356576113318582612521565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b61136184610f3c565b9050806000036113a15760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f41535345545360a81b6044820152606401610f8e565b6113ab8285612079565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4604051631a4ca37b60e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820183905284811660448301527f000000000000000000000000000000000000000000000000000000000000000016906369328dec9060640161129d565b600254600090801561073e576107398161148b6105fc565b859190611c31565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115179190612538565b1561152457506000919050565b6040516335ea6a7560e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906335ea6a759060240161018060405180830381865afa1580156115b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d49190612632565b51519050600160381b81166115ec5750600092915050565b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015611677573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169b91906124b8565b6001600160a01b038516600090815260036020526040812054919250906116c19061071a565b90508082106116d057806116d2565b815b95945050505050565b4284101561172b5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610f8e565b600060016117376108b4565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611843573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906118795750876001600160a01b0316816001600160a01b0316145b6118b65760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610f8e565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561197f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a39190612538565b156119b057506000919050565b6040516335ea6a7560e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906335ea6a759060240161018060405180830381865afa158015611a3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a609190612632565b51519050600160381b8116611a785750600092915050565b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015611b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2791906124b8565b90506000611b3482611473565b6001600160a01b038616600090815260036020526040902054909150808210611b5d5780611b5f565b815b9695505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611bcd5760405162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b6044820152606401610f8e565b604080516060810182526001600160a01b0394851680825293851660208201819052929094169301839052600680546001600160a01b031990811690931790556007805483169091179055600880549091169091179055565b60006107ae82611473565b828202811515841585830485141716611c4957600080fd5b0492915050565b828202811515841585830485141716611c6857600080fd5b6001826001830304018115150290509392505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611cb0919061271f565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60008181611d2686866120db565b509050600080836001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611d6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d8e91906127d1565b5091509150876001600160a01b0316836001600160a01b031614611dae57905b600080611dce8b856001600160701b0316856001600160701b031661210c565b9050896001600160a01b0316856001600160a01b031614611deb57905b611dff6001600160a01b038b16878d61215b565b6040805160008152602081019182905263022c0d9f60e01b9091526001600160a01b0387169063022c0d9f90611e3e9085908590309060248101612816565b600060405180830381600087803b158015611e5857600080fd5b505af1158015611e6c573d6000803e3d6000fd5b50505050818111611e7d5781611e7f565b805b9b9a5050505050505050505050565b611ee26001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000846121d9565b60405163e8eda9df60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260248201849052306044830152600060648301527f0000000000000000000000000000000000000000000000000000000000000000169063e8eda9df90608401600060405180830381600087803b158015611f7957600080fd5b505af1158015611f8d573d6000803e3d6000fd5b505050505050565b60006040516323b872dd60e01b81528460048201528360248201528260448201526020600060648360008a5af13d15601f3d11600160005114161716915050806120185760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610f8e565b5050505050565b80600260008282546120319190612843565b90915550506001600160a01b03821660008181526003602090815260408083208054860190555184815260008051602061289d83398151915291015b60405180910390a35050565b6001600160a01b038216600090815260036020526040812080548392906120a1908490612521565b90915550506002805482900390556040518181526000906001600160a01b0384169060008051602061289d8339815191529060200161206d565b600080826001600160a01b0316846001600160a01b0316106120fe578284612101565b83835b915091509250929050565b60008061211b856103e561285b565b90506000612129848361285b565b905060008261213a876103e861285b565b6121449190612843565b9050612150818361287a565b979650505050505050565b600060405163a9059cbb60e01b8152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806121d35760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610f8e565b50505050565b600060405163095ea7b360e01b8152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806121d35760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b6044820152606401610f8e565b6000815180845260005b818110156122765760208185018101518683018201520161225a565b81811115612288576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006107406020830184612250565b6000602082840312156122c257600080fd5b5035919050565b6001600160a01b0381168114610f3957600080fd5b600080604083850312156122f157600080fd5b82356122fc816122c9565b946020939093013593505050565b60008060006060848603121561231f57600080fd5b833561232a816122c9565b9250602084013561233a816122c9565b929592945050506040919091013590565b60006020828403121561235d57600080fd5b8135610740816122c9565b6000806040838503121561237b57600080fd5b82359150602083013561238d816122c9565b809150509250929050565b6000806000606084860312156123ad57600080fd5b8335925060208401356123bf816122c9565b915060408401356123cf816122c9565b809150509250925092565b60ff81168114610f3957600080fd5b600080600080600080600060e0888a03121561240457600080fd5b873561240f816122c9565b9650602088013561241f816122c9565b95506040880135945060608801359350608088013561243d816123da565b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561246d57600080fd5b8235612478816122c9565b9150602083013561238d816122c9565b60008060006060848603121561249d57600080fd5b83356124a8816122c9565b925060208401356123bf816122c9565b6000602082840312156124ca57600080fd5b5051919050565b600181811c908216806124e557607f821691505b60208210810361250557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156125335761253361250b565b500390565b60006020828403121561254a57600080fd5b8151801515811461074057600080fd5b604051610180810167ffffffffffffffff8111828210171561258c57634e487b7160e01b600052604160045260246000fd5b60405290565b6000602082840312156125a457600080fd5b6040516020810181811067ffffffffffffffff821117156125d557634e487b7160e01b600052604160045260246000fd5b6040529151825250919050565b80516fffffffffffffffffffffffffffffffff8116811461260257600080fd5b919050565b805164ffffffffff8116811461260257600080fd5b8051612602816122c9565b8051612602816123da565b6000610180828403121561264557600080fd5b61264d61255a565b6126578484612592565b8152612665602084016125e2565b6020820152612676604084016125e2565b6040820152612687606084016125e2565b6060820152612698608084016125e2565b60808201526126a960a084016125e2565b60a08201526126ba60c08401612607565b60c08201526126cb60e0840161261c565b60e08201526101006126de81850161261c565b908201526101206126f084820161261c565b9082015261014061270284820161261c565b90820152610160612714848201612627565b908201529392505050565b600080835481600182811c91508083168061273b57607f831692505b6020808410820361275a57634e487b7160e01b86526022600452602486fd5b81801561276e576001811461277f576127ac565b60ff198616895284890196506127ac565b60008a81526020902060005b868110156127a45781548b82015290850190830161278b565b505084890196505b509498975050505050505050565b80516001600160701b038116811461260257600080fd5b6000806000606084860312156127e657600080fd5b6127ef846127ba565b92506127fd602085016127ba565b9150604084015163ffffffff811681146123cf57600080fd5b84815283602082015260018060a01b0383166040820152608060608201526000611b5f6080830184612250565b600082198211156128565761285661250b565b500190565b60008160001904831182151516156128755761287561250b565b500290565b60008261289757634e487b7160e01b600052601260045260246000fd5b50049056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220fb99e7be51c986887c79a7884ed7c7c5a10894b19f21e0dd0c90b99f50150a6864736f6c634300080e00330000000000000000000000008d11ec38a3eb5e956b052f67da8bdc9bef8abf3e00000000000000000000000007e6332dd090d287d3489245038daf987955dcfb00000000000000000000000049c93a95dbcc9a6a4d8f77e59c038ce5020e82f80000000000000000000000009fad24f572045c7869117160a571b2e50b10d068000000000000000000000000d8321aa83fb0a4ecd6348d4577431310a6e0814d000000000000000000000000dc6ca6116d69171b4aea7acbd1a739cf7c565f53
Deployed ByteCode Sourcemap
33913:10375:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40011:127;;;:::i;:::-;;;160:25:1;;;148:2;133:18;40011:127:0;;;;;;;;1043:18;;;:::i;:::-;;;;;;;:::i;25147:261::-;;;;;;:::i;:::-;;:::i;2520:217::-;;;;;;:::i;:::-;;:::i;:::-;;;1704:14:1;;1697:22;1679:41;;1667:2;1652:18;2520:217:0;1539:187:1;25814:259:0;;;;;;:::i;:::-;;:::i;1326:26::-;;;;;;3138:612;;;;;;:::i;:::-;;:::i;1099:31::-;;;;;;;;2364:4:1;2352:17;;;2334:36;;2322:2;2307:18;1099:31:0;2192:184:1;5480:179:0;;;:::i;21735:28::-;;;;;;;;-1:-1:-1;;;;;2740:32:1;;;2722:51;;2710:2;2695:18;21735:28:0;2563:216:1;40685:555:0;;;;;;:::i;:::-;;:::i;36832:1349::-;;;:::i;:::-;;33961:32;;;;;26081:126;;;;;;:::i;:::-;;:::i;35350:24::-;;;;;;;;;-1:-1:-1;;;;;35350:24:0;;;;;;;;;;;;;;-1:-1:-1;;;;;3502:15:1;;;3484:34;;3554:15;;;3549:2;3534:18;;3527:43;3606:15;;3586:18;;;3579:43;;;;3434:2;3419:18;35350:24:0;3244:384:1;22150:528:0;;;;;;:::i;:::-;;:::i;1361:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;34660:89;;;;;1787:41;;;;;;:::i;:::-;;;;;;;;;;;;;;22686:478;;;;;;:::i;:::-;;:::i;1070:20::-;;;:::i;35080:46::-;;;;;34990:29;;;;;35263:41;;;;;2745:385;;;;;;:::i;:::-;;:::i;25551:255::-;;;;;;:::i;:::-;;:::i;38380:790::-;;;;;;:::i;:::-;;:::i;39178:825::-;;;;;;:::i;:::-;;:::i;24878:261::-;;;;;;:::i;:::-;;:::i;41758:685::-;;;;;;:::i;:::-;;:::i;3945:1527::-;;;;;;:::i;:::-;;:::i;42451:734::-;;;;;;:::i;:::-;;:::i;1414:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;36437:219;;;;;;:::i;:::-;;:::i;25416:127::-;;;;;;:::i;:::-;;:::i;35173:34::-;;;;;40011:127;40099:31;;-1:-1:-1;;;40099:31:0;;40124:4;40099:31;;;2722:51:1;40072:7:0;;40099:6;-1:-1:-1;;;;;40099:16:0;;;;2695:18:1;;40099:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40092:38;;40011:127;:::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;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;40685:555::-;40797:7;40862:11;-1:-1:-1;;;;;40862:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40858:61;;;-1:-1:-1;40906:1:0;;40685:555;-1:-1:-1;40685:555:0:o;40858:61::-;40989:56;;-1:-1:-1;;;40989:56:0;;-1:-1:-1;;;;;41038:5:0;2740:32:1;;40989:56:0;;;2722:51:1;-1:-1:-1;;40989:11:0;:40;;;;;;2695:18:1;;40989:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:84;:103;;-1:-1:-1;;;;44114:25:0;;:30;;41109:49;;;;-1:-1:-1;44260:12:0;44247:25;;:30;41109:49;41103:93;;-1:-1:-1;41183:1:0;;40685:555;-1:-1:-1;;40685:555:0:o;41103:93::-;-1:-1:-1;;;41215:17:0;40685:555;-1:-1:-1;;40685:555:0:o;36832:1349::-;36871:7;-1:-1:-1;;;;;36871:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36901:7;-1:-1:-1;;;;;36901:12:0;;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;36945:36:0;;-1:-1:-1;;;36945:36:0;;36975:4;36945:36;;;2722:51:1;36928:14:0;;-1:-1:-1;36945:11:0;-1:-1:-1;;;;;36945:21:0;;-1:-1:-1;36945:21:0;;2695:18:1;;36945:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;36998:8;:14;36928:53;;-1:-1:-1;;;;;;37024:5:0;36998:32;;:14;;:32;36994:1120;;37067:14;;37047:43;;-1:-1:-1;;;37047:43:0;;-1:-1:-1;;;;;37067:14:0;;;37047:43;;;11025:51:1;11092:18;;;11085:34;;;37047:11:0;:19;;;;;;10998:18:1;;37047:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;37216:8:0;:14;37297;;37107:240;;37138:6;;37171:11;;-1:-1:-1;;;;;37216:14:0;;;;37297;37107:12;:240::i;:::-;;36994:1120;;;37402:14;;37382:43;;-1:-1:-1;;;37382:43:0;;-1:-1:-1;;;;;37402:14:0;;;37382:43;;;11025:51:1;11092:18;;;11085:34;;;37382:11:0;:19;;;;;;10998:18:1;;37382:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;37609:8:0;:14;37690;;37474:23;;37500:240;;37531:6;;37564:11;;-1:-1:-1;;;;;37609:14:0;;;;37690;37500:12;:240::i;:::-;37763:8;:14;37787;;37757:62;;-1:-1:-1;;;37757:62:0;;-1:-1:-1;;;;;37787:14:0;;;37757:62;;;11025:51:1;11092:18;;;11085:34;;;37474:266:0;;-1:-1:-1;37763:14:0;;37757:29;;10998:18:1;;37757:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;37919:8:0;:14;38052;;37854:248;;37885:15;;-1:-1:-1;;;;;37919:14:0;;;;37981:5;;38052:14;37854:12;:248::i;:::-;-1:-1:-1;;36994:1120:0;38139:30;;-1:-1:-1;;;38139:30:0;;38163:4;38139:30;;;2722:51:1;38126:47:0;;38139:5;-1:-1:-1;;;;;38139:15:0;;;;2695:18:1;;38139:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38171:1;38126:12;:47::i;:::-;36860:1321;36832:1349::o;26081:126::-;26149:7;26176:23;26192:6;26176:15;:23::i;22150:528::-;22225:14;22346:22;22361:6;22346:14;:22::i;:::-;22337:31;;;22373:1;22336:38;22328:62;;;;-1:-1:-1;;;22328:62:0;;11332:2:1;22328:62:0;;;11314:21:1;11371:2;11351:18;;;11344:30;-1:-1:-1;;;11390:18:1;;;11383:41;11441:18;;22328:62:0;;;;;;;;;22473:57;-1:-1:-1;;;;;22473:5:0;:22;22496:10;22516:4;22523:6;22473:22;:57::i;:::-;22543:23;22549:8;22559:6;22543:5;:23::i;:::-;22584:45;;;11644:25:1;;;11700:2;11685:18;;11678:34;;;-1:-1:-1;;;;;22584:45:0;;;22592:10;;22584:45;;11617:18:1;22584:45:0;;;;;;;22642:28;22655:6;22663;22642:12;:28::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;;;11644:25:1;;;11700:2;11685:18;;11678:34;;;-1:-1:-1;;;;;23070:45:0;;;23078:10;;23070:45;;11617:18:1;23070:45:0;;;;;;;23128:28;23141:6;23149;23128:12;:28::i;1070:20::-;;;;;;;:::i;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;38380:790::-;38514:14;38550:23;38566:6;38550:15;:23::i;:::-;38541:32;-1:-1:-1;38657:10:0;-1:-1:-1;;;;;38657:19:0;;;38653:249;;-1:-1:-1;;;;;38711:16:0;;38693:15;38711:16;;;:9;:16;;;;;;;;38728:10;38711:28;;;;;;;;-1:-1:-1;;38796:28:0;;38792:98;;38874:16;38884:6;38874:7;:16;:::i;:::-;-1:-1:-1;;;;;38843:16:0;;;;;;:9;:16;;;;;;;;38860:10;38843:28;;;;;;;:47;38792:98;38678:224;38653:249;38957:20;38963:5;38970:6;38957:5;:20::i;:::-;38995:53;;;11644:25:1;;;11700:2;11685:18;;11678:34;;;-1:-1:-1;;;;;38995:53:0;;;;;;;;39004:10;;38995:53;;11617:18:1;38995:53:0;;;;;;;39108:54;;-1:-1:-1;;;39108:54:0;;-1:-1:-1;;;;;39137:5:0;11981:15:1;;39108:54:0;;;11963:34:1;12013:18;;;12006:34;;;12076:15;;;12056:18;;;12049:43;39108:11:0;:20;;;;11898:18:1;;39108:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;38380:790;;;;;:::o;39178:825::-;39310:14;39341:10;-1:-1:-1;;;;;39341:19:0;;;39337:249;;-1:-1:-1;;;;;39395:16:0;;39377:15;39395:16;;;:9;:16;;;;;;;;39412:10;39395:28;;;;;;;;-1:-1:-1;;39480:28:0;;39476:98;;39558:16;39568:6;39558:7;:16;:::i;:::-;-1:-1:-1;;;;;39527:16:0;;;;;;:9;:16;;;;;;;;39544:10;39527:28;;;;;;;:47;39476:98;39362:224;39337:249;39691:21;39705:6;39691:13;:21::i;:::-;39682:30;;;39717:1;39681:37;39673:61;;;;-1:-1:-1;;;39673:61:0;;12305:2:1;39673:61:0;;;12287:21:1;12344:2;12324:18;;;12317:30;-1:-1:-1;;;12363:18:1;;;12356:41;12414:18;;39673:61:0;12103:335:1;39673:61:0;39790:20;39796:5;39803:6;39790:5;:20::i;:::-;39828:53;;;11644:25:1;;;11700:2;11685:18;;11678:34;;;-1:-1:-1;;;;;39828:53:0;;;;;;;;39837:10;;39828:53;;11617:18:1;39828:53:0;;;;;;;39941:54;;-1:-1:-1;;;39941:54:0;;-1:-1:-1;;;;;39970:5:0;11981:15:1;;39941:54:0;;;11963:34:1;12013:18;;;12006:34;;;12076:15;;;12056:18;;;12049:43;39941:11:0;:20;;;;11898:18:1;;39941:54:0;11723:375:1;24878:261:0;24985:11;;24948:7;;25068:11;;:63;;25091:40;25109:6;25117:13;:11;:13::i;:::-;25091:6;;:40;:17;:40::i;41758:685::-;41877:7;41942:11;-1:-1:-1;;;;;41942:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41938:61;;;-1:-1:-1;41986:1:0;;41758:685;-1:-1:-1;41758:685:0:o;41938:61::-;42069:56;;-1:-1:-1;;;42069:56:0;;-1:-1:-1;;;;;42118:5:0;2740:32:1;;42069:56:0;;;2722:51:1;-1:-1:-1;;42069:11:0;:40;;;;;;2695:18:1;;42069:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:84;:103;;-1:-1:-1;;;;44114:25:0;;42183:64;;-1:-1:-1;42234:1:0;;41758:685;-1:-1:-1;;41758:685:0:o;42183:64::-;42274:32;;-1:-1:-1;;;42274:32:0;;-1:-1:-1;;;;;42298:6:0;2740:32:1;;42274::0;;;2722:51:1;-1:-1:-1;;42274:5:0;:15;;;;;;2695:18:1;;42274:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;42357:16:0;;42317:21;42357:16;;;:9;:16;;;;;;42259:47;;-1:-1:-1;42317:21:0;42341:33;;:15;:33::i;:::-;42317:57;;42399:13;42392:4;:20;:43;;42422:13;42392:43;;;42415:4;42392:43;42385:50;41758:685;-1:-1:-1;;;;;41758:685:0:o;3945:1527::-;4173:15;4161:8;:27;;4153:63;;;;-1:-1:-1;;;4153:63:0;;12645:2:1;4153:63:0;;;12627:21:1;12684:2;12664:18;;;12657:30;12723:25;12703:18;;;12696:53;12766:18;;4153:63:0;12443: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;;;13082:25:1;13161:18;;;13154:43;;;;13233:15;;;13213:18;;;13206:43;13265:18;;;13258:34;;;13308:19;;;13301:35;;;;13352:19;;;;13345:35;;;4638:458:0;;;;;;;;;;13054:19:1;;;4638:458:0;;;4598:525;;;;;;;;-1:-1:-1;;;4473:673:0;;;13649:27:1;13692:11;;;13685:27;;;;13728:12;;;13721:28;;;;13765:12;;4473:673:0;;;-1:-1:-1;;4473:673:0;;;;;;;;;4441:724;;4473:673;4441:724;;;;4413:827;;;;;;;;;14015:25:1;14088:4;14076:17;;14056:18;;;14049:45;14110:18;;;14103:34;;;14153:18;;;14146:34;;;13987: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;;14393:2:1;5257:86:0;;;14375:21:1;14432:2;14412:18;;;14405:30;-1:-1:-1;;;14451:18:1;;;14444:44;14505:18;;5257:86:0;14191: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;42451:734::-;42568:7;42633:11;-1:-1:-1;;;;;42633:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42629:61;;;-1:-1:-1;42677:1:0;;42451:734;-1:-1:-1;42451:734:0:o;42629:61::-;42760:56;;-1:-1:-1;;;42760:56:0;;-1:-1:-1;;;;;42809:5:0;2740:32:1;;42760:56:0;;;2722:51:1;-1:-1:-1;;42760:11:0;:40;;;;;;2695:18:1;;42760:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:84;:103;;-1:-1:-1;;;;44114:25:0;;42874:64;;-1:-1:-1;42925:1:0;;42451:734;-1:-1:-1;;42451:734:0:o;42874:64::-;42965:32;;-1:-1:-1;;;42965:32:0;;-1:-1:-1;;;;;42989:6:0;2740:32:1;;42965::0;;;2722:51:1;-1:-1:-1;;42965:5:0;:15;;;;;;2695:18:1;;42965:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42950:47;;43008:20;43031:21;43047:4;43031:15;:21::i;:::-;-1:-1:-1;;;;;43086:16:0;;43063:20;43086:16;;;:9;:16;;;;;;43008:44;;-1:-1:-1;43120:27:0;;;:57;;43165:12;43120:57;;;43150:12;43120:57;43113:64;42451:734;-1:-1:-1;;;;;;42451:734:0:o;36437:219::-;36562:10;-1:-1:-1;;;;;36576:7:0;36562:21;;36554:43;;;;-1:-1:-1;;;36554:43:0;;14736:2:1;36554:43:0;;;14718:21:1;14775:1;14755:18;;;14748:29;-1:-1:-1;;;14793:18:1;;;14786:39;14842:18;;36554:43:0;14534:332:1;36554:43:0;36619:29;;;;;;;;-1:-1:-1;;;;;36619:29:0;;;;;;;;;;;;;;;;;;;;;;;;36608:8;:40;;-1:-1:-1;;;;;;36608:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36437:219::o;25416:127::-;25485:7;25512:23;25528:6;25512:15;:23::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;5667:457::-;5732:7;5833:95;5967:4;5951:22;;;;;;:::i;:::-;;;;;;;;;;5800:301;;;16368:25:1;;;;16409:18;;16402:34;;;;5996:14:0;16452:18:1;;;16445:34;6033:13:0;16495:18:1;;;16488:34;6077:4:0;16538:19:1;;;16531:61;16340:19;;5800:301:0;;;;;;;;;;;;5772:344;;;;;;5752:364;;5667:457;:::o;31784:828::-;31932:7;31971:9;31932:7;32013:30;32024:9;32035:7;32013:10;:30::i;:::-;31992:51;;;32055:16;32073;32095:4;-1:-1:-1;;;;;32095:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32054:59;;;;;32138:9;-1:-1:-1;;;;;32128:19:0;:6;-1:-1:-1;;;;;32128:19:0;;32124:68;;32173:8;32124:68;32203:18;32236;32257:42;32270:8;32280;-1:-1:-1;;;;;32257:42:0;32290:8;-1:-1:-1;;;;;32257:42:0;:12;:42::i;:::-;32236:63;;32324:9;-1:-1:-1;;;;;32314:19:0;:6;-1:-1:-1;;;;;32314:19:0;;32310:89;;32376:10;32310:89;32410:54;-1:-1:-1;;;;;32410:29:0;;32448:4;32455:8;32410:29;:54::i;:::-;32524:12;;;32534:1;32524:12;;;;;;;;;-1:-1:-1;;;32475:62:0;;;-1:-1:-1;;;;;32475:9:0;;;;;:62;;32485:10;;32497;;32517:4;;32475:62;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32568:10;32555;:23;:49;;32594:10;32555:49;;;32581:10;32555:49;32548:56;31784:828;-1:-1:-1;;;;;;;;;;;31784:828:0:o;40146:531::-;40511:47;-1:-1:-1;;;;;40511:5:0;:17;40537:11;40551:6;40511:17;:47::i;:::-;40608:61;;-1:-1:-1;;;40608:61:0;;-1:-1:-1;;;;;40636:5:0;18009:15:1;;40608:61:0;;;17991:34:1;18041:18;;;18034:34;;;40660:4:0;18084:18:1;;;18077:43;-1:-1:-1;18136:18:1;;;18129:47;40608:11:0;:19;;;;17925::1;;40608:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40146:531;;:::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;;18389:2:1;9762:40:0;;;18371:21:1;18428:2;18408:18;;;18401:30;-1:-1:-1;;;18447:18:1;;;18440:50;18507:18;;9762:40:0;18187:344:1;9762:40:0;8339:1471;8206:1604;;;;:::o;6324:335::-;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;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;33669:204:0;33771:7;33780;33821:6;-1:-1:-1;;;;;33812:15:0;:6;-1:-1:-1;;;;;33812:15:0;;:53;;33850:6;33858;33812:53;;;33831:6;33839;33812:53;33805:60;;;;33669:204;;;;;:::o;32977:379::-;33113:7;;33159:14;:8;33170:3;33159:14;:::i;:::-;33133:40;-1:-1:-1;33184:17:0;33204:30;33223:10;33133:40;33204:30;:::i;:::-;33184:50;-1:-1:-1;33245:19:0;33289:15;33268:16;:9;33280:4;33268:16;:::i;:::-;33267:38;;;;:::i;:::-;33245:60;-1:-1:-1;33323:25:0;33245:60;33323:9;:25;:::i;:::-;33316:32;32977:379;-1:-1:-1;;;;;;;32977:379:0:o;9818:1485::-;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;;19266:2:1;11260:35:0;;;19248:21:1;19305:2;19285:18;;;19278:30;-1:-1:-1;;;19324:18:1;;;19317:45;19379:18;;11260:35:0;19064:339:1;11260:35:0;9924:1379;9818:1485;;;:::o;11311:1483::-;11427:12;11558:4;11552:11;-1:-1:-1;;;11684:17:0;11677:93;11818:2;11814:1;11795:17;11791:25;11784:37;11899:6;11894:2;11875:17;11871:26;11864:42;12711:2;12708:1;12704:2;12685:17;12682:1;12675:5;12668;12663:51;12227:16;12220:24;12214:2;12196:16;12193:24;12189:1;12185;12179:8;12176:15;12172:46;12169:76;11966:763;11955:774;;;12760:7;12752:34;;;;-1:-1:-1;;;12752:34:0;;19610:2:1;12752:34:0;;;19592:21:1;19649:2;19629:18;;;19622:30;-1:-1:-1;;;19668:18:1;;;19661:44;19722:18;;12752:34:0;19408:338:1;196:472;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:131::-;-1:-1:-1;;;;;1158:31:1;;1148:42;;1138:70;;1204:1;1201;1194:12;1219:315;1287:6;1295;1348:2;1336:9;1327:7;1323:23;1319:32;1316:52;;;1364:1;1361;1354:12;1316:52;1403:9;1390:23;1422:31;1447:5;1422:31;:::i;:::-;1472:5;1524:2;1509:18;;;;1496:32;;-1:-1:-1;;;1219:315:1:o;1731:456::-;1808:6;1816;1824;1877:2;1865:9;1856:7;1852:23;1848:32;1845:52;;;1893:1;1890;1883:12;1845:52;1932:9;1919:23;1951:31;1976:5;1951:31;:::i;:::-;2001:5;-1:-1:-1;2058:2:1;2043:18;;2030:32;2071:33;2030:32;2071:33;:::i;:::-;1731:456;;2123:7;;-1:-1:-1;;;2177:2:1;2162:18;;;;2149:32;;1731:456::o;2784:247::-;2843:6;2896:2;2884:9;2875:7;2871:23;2867:32;2864:52;;;2912:1;2909;2902:12;2864:52;2951:9;2938:23;2970:31;2995:5;2970:31;:::i;3633:315::-;3701:6;3709;3762:2;3750:9;3741:7;3737:23;3733:32;3730:52;;;3778:1;3775;3768:12;3730:52;3814:9;3801:23;3791:33;;3874:2;3863:9;3859:18;3846:32;3887:31;3912:5;3887:31;:::i;:::-;3937:5;3927:15;;;3633:315;;;;;:::o;4420:456::-;4497:6;4505;4513;4566:2;4554:9;4545:7;4541:23;4537:32;4534:52;;;4582:1;4579;4572:12;4534:52;4618:9;4605:23;4595:33;;4678:2;4667:9;4663:18;4650:32;4691:31;4716:5;4691:31;:::i;:::-;4741:5;-1:-1:-1;4798:2:1;4783:18;;4770:32;4811:33;4770:32;4811:33;:::i;:::-;4863:7;4853:17;;;4420:456;;;;;:::o;4881:114::-;4965:4;4958:5;4954:16;4947:5;4944:27;4934:55;;4985:1;4982;4975:12;5000:801;5111:6;5119;5127;5135;5143;5151;5159;5212:3;5200:9;5191:7;5187:23;5183:33;5180:53;;;5229:1;5226;5219:12;5180:53;5268:9;5255:23;5287:31;5312:5;5287:31;:::i;:::-;5337:5;-1:-1:-1;5394:2:1;5379:18;;5366:32;5407:33;5366:32;5407:33;:::i;:::-;5459:7;-1:-1:-1;5513:2:1;5498:18;;5485:32;;-1:-1:-1;5564:2:1;5549:18;;5536:32;;-1:-1:-1;5620:3:1;5605:19;;5592:33;5634:31;5592:33;5634:31;:::i;:::-;5000:801;;;;-1:-1:-1;5000:801:1;;;;5684:7;5738:3;5723:19;;5710:33;;-1:-1:-1;5790:3:1;5775:19;;;5762:33;;5000:801;-1:-1:-1;;5000:801:1:o;5806:388::-;5874:6;5882;5935:2;5923:9;5914:7;5910:23;5906:32;5903:52;;;5951:1;5948;5941:12;5903:52;5990:9;5977:23;6009:31;6034:5;6009:31;:::i;:::-;6059:5;-1:-1:-1;6116:2:1;6101:18;;6088:32;6129:33;6088:32;6129:33;:::i;6199:529::-;6276:6;6284;6292;6345:2;6333:9;6324:7;6320:23;6316:32;6313:52;;;6361:1;6358;6351:12;6313:52;6400:9;6387:23;6419:31;6444:5;6419:31;:::i;:::-;6469:5;-1:-1:-1;6526:2:1;6511:18;;6498:32;6539:33;6498:32;6539:33;:::i;6733:184::-;6803:6;6856:2;6844:9;6835:7;6831:23;6827:32;6824:52;;;6872:1;6869;6862:12;6824:52;-1:-1:-1;6895:16:1;;6733:184;-1:-1:-1;6733:184:1:o;6922:380::-;7001:1;6997:12;;;;7044;;;7065:61;;7119:4;7111:6;7107:17;7097:27;;7065:61;7172:2;7164:6;7161:14;7141:18;7138:38;7135:161;;7218:10;7213:3;7209:20;7206:1;7199:31;7253:4;7250:1;7243:15;7281:4;7278:1;7271:15;7135:161;;6922:380;;;:::o;7307:127::-;7368:10;7363:3;7359:20;7356:1;7349:31;7399:4;7396:1;7389:15;7423:4;7420:1;7413:15;7439:125;7479:4;7507:1;7504;7501:8;7498:34;;;7512:18;;:::i;:::-;-1:-1:-1;7549:9:1;;7439:125::o;7569:277::-;7636:6;7689:2;7677:9;7668:7;7664:23;7660:32;7657:52;;;7705:1;7702;7695:12;7657:52;7737:9;7731:16;7790:5;7783:13;7776:21;7769:5;7766:32;7756:60;;7812:1;7809;7802:12;7983:344;8050:2;8044:9;8092:3;8080:16;;8126:18;8111:34;;8147:22;;;8108:62;8105:185;;;8212:10;8207:3;8203:20;8200:1;8193:31;8247:4;8244:1;8237:15;8275:4;8272:1;8265:15;8105:185;8306:2;8299:22;7983:344;:::o;8332:523::-;8413:5;8461:4;8449:9;8444:3;8440:19;8436:30;8433:50;;;8479:1;8476;8469:12;8433:50;8512:2;8506:9;8554:4;8546:6;8542:17;8625:6;8613:10;8610:22;8589:18;8577:10;8574:34;8571:62;8568:185;;;8675:10;8670:3;8666:20;8663:1;8656:31;8710:4;8707:1;8700:15;8738:4;8735:1;8728:15;8568:185;8769:2;8762:22;8832:16;;8817:32;;-1:-1:-1;8802:6:1;8332:523;-1:-1:-1;8332:523:1:o;8860:192::-;8939:13;;8992:34;8981:46;;8971:57;;8961:85;;9042:1;9039;9032:12;8961:85;8860:192;;;:::o;9057:169::-;9135:13;;9188:12;9177:24;;9167:35;;9157:63;;9216:1;9213;9206:12;9231:138;9310:13;;9332:31;9310:13;9332:31;:::i;9374:134::-;9451:13;;9473:29;9451:13;9473:29;:::i;9513:1333::-;9612:6;9665:3;9653:9;9644:7;9640:23;9636:33;9633:53;;;9682:1;9679;9672:12;9633:53;9708:17;;:::i;:::-;9748:72;9812:7;9801:9;9748:72;:::i;:::-;9741:5;9734:87;9853:49;9898:2;9887:9;9883:18;9853:49;:::i;:::-;9848:2;9841:5;9837:14;9830:73;9935:49;9980:2;9969:9;9965:18;9935:49;:::i;:::-;9930:2;9923:5;9919:14;9912:73;10017:49;10062:2;10051:9;10047:18;10017:49;:::i;:::-;10012:2;10005:5;10001:14;9994:73;10100:50;10145:3;10134:9;10130:19;10100:50;:::i;:::-;10094:3;10087:5;10083:15;10076:75;10184:50;10229:3;10218:9;10214:19;10184:50;:::i;:::-;10178:3;10171:5;10167:15;10160:75;10268:49;10312:3;10301:9;10297:19;10268:49;:::i;:::-;10262:3;10255:5;10251:15;10244:74;10351:50;10396:3;10385:9;10381:19;10351:50;:::i;:::-;10345:3;10338:5;10334:15;10327:75;10421:3;10456:49;10501:2;10490:9;10486:18;10456:49;:::i;:::-;10440:14;;;10433:73;10525:3;10560:49;10590:18;;;10560:49;:::i;:::-;10544:14;;;10537:73;10629:3;10664:49;10694:18;;;10664:49;:::i;:::-;10648:14;;;10641:73;10733:3;10768:47;10796:18;;;10768:47;:::i;:::-;10752:14;;;10745:71;10756:5;9513:1333;-1:-1:-1;;;9513:1333:1:o;15000:1104::-;15130:3;15159:1;15192:6;15186:13;15222:3;15244:1;15272:9;15268:2;15264:18;15254:28;;15332:2;15321:9;15317:18;15354;15344:61;;15398:4;15390:6;15386:17;15376:27;;15344:61;15424:2;15472;15464:6;15461:14;15441:18;15438:38;15435:165;;-1:-1:-1;;;15499:33:1;;15555:4;15552:1;15545:15;15585:4;15506:3;15573:17;15435:165;15616:18;15643:104;;;;15761:1;15756:323;;;;15609:470;;15643:104;-1:-1:-1;;15676:24:1;;15664:37;;15721:16;;;;-1:-1:-1;15643:104:1;;15756:323;14947:1;14940:14;;;14984:4;14971:18;;15854:1;15868:165;15882:6;15879:1;15876:13;15868:165;;;15960:14;;15947:11;;;15940:35;16003:16;;;;15897:10;;15868:165;;;15872:3;;16062:6;16057:3;16053:16;16046:23;;15609:470;-1:-1:-1;16095:3:1;;15000:1104;-1:-1:-1;;;;;;;;15000:1104:1:o;16603:188::-;16682:13;;-1:-1:-1;;;;;16724:42:1;;16714:53;;16704:81;;16781:1;16778;16771:12;16796:450;16883:6;16891;16899;16952:2;16940:9;16931:7;16927:23;16923:32;16920:52;;;16968:1;16965;16958:12;16920:52;16991:40;17021:9;16991:40;:::i;:::-;16981:50;;17050:49;17095:2;17084:9;17080:18;17050:49;:::i;:::-;17040:59;;17142:2;17131:9;17127:18;17121:25;17186:10;17179:5;17175:22;17168:5;17165:33;17155:61;;17212:1;17209;17202:12;17251:459;17482:6;17471:9;17464:25;17525:6;17520:2;17509:9;17505:18;17498:34;17597:1;17593;17588:3;17584:11;17580:19;17572:6;17568:32;17563:2;17552:9;17548:18;17541:60;17637:3;17632:2;17621:9;17617:18;17610:31;17445:4;17658:46;17699:3;17688:9;17684:19;17676:6;17658:46;:::i;18536:128::-;18576:3;18607:1;18603:6;18600:1;18597:13;18594:39;;;18613:18;;:::i;:::-;-1:-1:-1;18649:9:1;;18536:128::o;18669:168::-;18709:7;18775:1;18771;18767:6;18763:14;18760:1;18757:21;18752:1;18745:9;18738:17;18734:45;18731:71;;;18782:18;;:::i;:::-;-1:-1:-1;18822:9:1;;18669:168::o;18842:217::-;18882:1;18908;18898:132;;18952:10;18947:3;18943:20;18940:1;18933:31;18987:4;18984:1;18977:15;19015:4;19012:1;19005:15;18898:132;-1:-1:-1;19044:9:1;;18842:217::o
Swarm Source
ipfs://fb99e7be51c986887c79a7884ed7c7c5a10894b19f21e0dd0c90b99f50150a68
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Validator ID :
0 FTM
Amount Staked
0
Amount Delegated
0
Staking Total
0
Staking Start Epoch
0
Staking Start Time
0
Proof of Importance
0
Origination Score
0
Validation Score
0
Active
0
Online
0
Downtime
0 s
Address | Amount | claimed Rewards | Created On Epoch | Created On |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.