ERC-20
Overview
Max Total Supply
89,375,259.233490443923504016 svXAI
Holders
314
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
20,066.474473389434454805 svXAIValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
SideShiftVault
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {SafeCastLib} from '@rari-capital/solmate/src/utils/SafeCastLib.sol'; import {SafeTransferLib} from '@rari-capital/solmate/src/utils/SafeTransferLib.sol'; import {FixedPointMathLib} from '@rari-capital/solmate/src/utils/FixedPointMathLib.sol'; import {ERC4626} from '@rari-capital/solmate/src/mixins/ERC4626.sol'; import {ERC20} from '@rari-capital/solmate/src/tokens/ERC20.sol'; import '@openzeppelin/contracts/utils/cryptography/MerkleProof.sol'; import '@openzeppelin/contracts/access/Ownable.sol'; contract SideShiftVault is ERC4626, Ownable { using SafeCastLib for uint256; using SafeTransferLib for ERC20; using FixedPointMathLib for uint256; /// @notice the underlying token the vault accepts ERC20 public immutable UNDERLYING; /// @notice bool clarifying vault's have been initialized bool public contractInitialized; /// @notice Event emits when vault is initialized event ContractInitialization(address indexed user); /// @notice bool clarifying if shares have been minted for merkle claimees bool public merkleMinted; /// @notice The root hash of the Merkle tree - as it won't change made immutable bytes32 public immutable merkleRoot; /// @notice The number of shares in the vault not claimed from the merkle tree uint256 public merkleUnclaimed; /// @notice mapping for addresses in merkle that have claimed mapping(address => bool) public merkleClaimed; /// @notice Event emits when shares for address in merkle are minted event MerkleSharesMinted(address indexed user, uint256 shares); /// @notice Event emits when address in merkle claims shares event MerkleClaim(address indexed user, uint256 amount); /// Merkle root used as a param at deployment constructor(ERC20 _UNDERLYING, bytes32 _merkleRoot) ERC4626( _UNDERLYING, string( abi.encodePacked('SideShift ', _UNDERLYING.name(), ' Vault') ), string(abi.encodePacked('sv', _UNDERLYING.symbol())) ) { UNDERLYING = _UNDERLYING; totalSupply = type(uint256).max; merkleRoot = _merkleRoot; } // ================ VAULT ACCOUNTING ==================== // /// @notice Calculates the current balance of the underlying token i.e. XAI /// @return The contract's balance of XAI function totalAssets() public view override returns (uint256) { return UNDERLYING.balanceOf(address(this)); } /// @notice Calculates the max depositable amount of the underlying token /// @return The outstanding balance of XAI token not staked in the contract function maxDeposit(address _address) public view override returns (uint256) { return UNDERLYING.balanceOf(_address); } /// @notice Calculates the max mintable shares /// @return The amount of shares mintable for total supply of unstaked XAI function maxMint(address _address) public view override returns (uint256) { return previewDeposit(UNDERLYING.balanceOf(_address)); } // ================== MERKLE TREE CLAIM ========================== // /// @notice Mints shares to contract that can be claimed by addresses in merkle function merkleMint( uint256 _shares, uint256 _amount, address _sender ) internal { require(_amount == _shares, 'INSUFFICIENT_AMOUNT'); merkleMinted = true; merkleUnclaimed = _shares; _mint(address(this), _shares); emit MerkleSharesMinted(_sender, _shares); } /// @notice Claims eligible amount of shares for address in merkle function claimShares( address _sender, uint256 _amount, bytes32[] calldata merkleProof ) external { require(!merkleClaimed[_sender], 'ALREADY_CLAIMED'); // Verify the merkle proof bytes32 node = keccak256(abi.encodePacked(_sender, _amount)); require( MerkleProof.verify(merkleProof, merkleRoot, node), 'INVALID_PROOF' ); // Set address to claimed and deduct shares from merkle unclaimed total merkleClaimed[_sender] = true; merkleUnclaimed -= _amount; // Mint shares and burn contract shares --> Transfer uses callers as msg.sender // And TransferFrom would require allowance for every merkle address _burn(address(this), _amount); _mint(_sender, _amount); // Emit claim event emit MerkleClaim(_sender, _amount); } function checkMerkle( address _sender, uint256 _amount, bytes32[] calldata merkleProof ) external view returns (bool) { bytes32 node = keccak256(abi.encodePacked(_sender, _amount)); require( MerkleProof.verify(merkleProof, merkleRoot, node), 'INVALID_PROOF' ); return true; } /// @notice Emergency function to transfer shares to owner if the merkle root missed an address /// Shares can then be transferred from the owner to the address missed from the merkle function emergencyMerkleTransfer(uint256 _amount) external onlyOwner { require(_amount <= merkleUnclaimed, 'CLAIM_TOO_HIGH'); merkleUnclaimed -= _amount; _burn(address(this), _amount); _mint(msg.sender, _amount); } // ================= ADMIN FUNCTIONs =============== // /// @notice Initializes contract by setting totalSupply to 0 from type(uint256).max /// Added merkle + deposit to avoid front run risk on the deposit function vaultInitialize(uint256 _shares, uint256 _amount) external onlyOwner { require(!contractInitialized, 'ALREADY_INITIALIZED'); // Setting supply to 0 to initialize contract from overflow state contractInitialized = true; totalSupply = 0; // Mint shares for all addresses in merkle tree and hold in contract merkleMint(_shares, _amount, msg.sender); require( UNDERLYING.transferFrom(msg.sender, address(this), _amount), 'TRANSFER_FAIL' ); emit ContractInitialization(msg.sender); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Safe unsigned integer casting library that reverts on overflow. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeCastLib.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol) library SafeCastLib { function safeCastTo248(uint256 x) internal pure returns (uint248 y) { require(x < 1 << 248); y = uint248(x); } function safeCastTo224(uint256 x) internal pure returns (uint224 y) { require(x < 1 << 224); y = uint224(x); } function safeCastTo192(uint256 x) internal pure returns (uint192 y) { require(x < 1 << 192); y = uint192(x); } function safeCastTo160(uint256 x) internal pure returns (uint160 y) { require(x < 1 << 160); y = uint160(x); } function safeCastTo128(uint256 x) internal pure returns (uint128 y) { require(x < 1 << 128); y = uint128(x); } function safeCastTo96(uint256 x) internal pure returns (uint96 y) { require(x < 1 << 96); y = uint96(x); } function safeCastTo64(uint256 x) internal pure returns (uint64 y) { require(x < 1 << 64); y = uint64(x); } function safeCastTo32(uint256 x) internal pure returns (uint32 y) { require(x < 1 << 32); y = uint32(x); } function safeCastTo8(uint256 x) internal pure returns (uint8 y) { require(x < 1 << 8); y = uint8(x); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; /// @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"); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @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 } } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol"; /// @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 {} }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Trees proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; if (computedHash <= proofElement) { // Hash(current computed hash + current element of the proof) computedHash = _efficientHash(computedHash, proofElement); } else { // Hash(current element of the proof + current computed hash) computedHash = _efficientHash(proofElement, computedHash); } } return computedHash; } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ERC20","name":"_UNDERLYING","type":"address"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"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":"user","type":"address"}],"name":"ContractInitialization","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":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MerkleClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"MerkleSharesMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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":"UNDERLYING","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":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"checkMerkle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claimShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"emergencyMerkleTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","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":"address","name":"","type":"address"}],"name":"merkleClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleUnclaimed","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":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","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":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"vaultInitialize","outputs":[],"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
6101406040523480156200001257600080fd5b506040516200495f3803806200495f833981810160405281019062000038919062000601565b818273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200008057600080fd5b505afa15801562000095573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190620000c0919062000642565b604051602001620000d291906200085c565b6040516020818303038152906040528373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156200012857600080fd5b505afa1580156200013d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019062000168919062000642565b6040516020016200017a919062000836565b60405160208183030381529060405281818473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015620001d257600080fd5b505afa158015620001e7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020d919062000687565b8260009080519060200190620002259291906200049a565b5081600190805190602001906200023e9291906200049a565b508060ff1660808160ff1660f81b815250504660a08181525050620002686200033c60201b60201c565b60c081815250505050508273ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050505050620002cc620002c0620003cc60201b60201c565b620003d460201b60201c565b8173ffffffffffffffffffffffffffffffffffffffff166101008173ffffffffffffffffffffffffffffffffffffffff1660601b815250507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600281905550806101208181525050505062000bc4565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516200037091906200081d565b60405180910390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc64630604051602001620003b19594939291906200088f565b60405160208183030381529060405280519060200120905090565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620004a89062000a20565b90600052602060002090601f016020900481019282620004cc576000855562000518565b82601f10620004e757805160ff191683800117855562000518565b8280016001018555821562000518579182015b8281111562000517578251825591602001919060010190620004fa565b5b5090506200052791906200052b565b5090565b5b80821115620005465760008160009055506001016200052c565b5090565b6000620005616200055b8462000915565b620008ec565b9050828152602081018484840111156200057a57600080fd5b62000587848285620009ea565b509392505050565b600081519050620005a08162000b76565b92915050565b600081519050620005b78162000b90565b92915050565b600082601f830112620005cf57600080fd5b8151620005e18482602086016200054a565b91505092915050565b600081519050620005fb8162000baa565b92915050565b600080604083850312156200061557600080fd5b60006200062585828601620005a6565b925050602062000638858286016200058f565b9150509250929050565b6000602082840312156200065557600080fd5b600082015167ffffffffffffffff8111156200067057600080fd5b6200067e84828501620005bd565b91505092915050565b6000602082840312156200069a57600080fd5b6000620006aa84828501620005ea565b91505092915050565b620006be8162000981565b82525050565b620006cf8162000995565b82525050565b60008154620006e48162000a20565b620006f081866200096b565b945060018216600081146200070e5760018114620007205762000757565b60ff1983168652818601935062000757565b6200072b856200094b565b60005b838110156200074f578154818901526001820191506020810190506200072e565b838801955050505b50505092915050565b60006200076d8262000960565b62000779818562000976565b93506200078b818560208601620009ea565b80840191505092915050565b6000620007a660068362000976565b9150620007b38262000afb565b600682019050919050565b6000620007cd60028362000976565b9150620007da8262000b24565b600282019050919050565b6000620007f4600a8362000976565b9150620008018262000b4d565b600a82019050919050565b6200081781620009d3565b82525050565b60006200082b8284620006d5565b915081905092915050565b60006200084382620007be565b915062000851828462000760565b915081905092915050565b60006200086982620007e5565b915062000877828462000760565b9150620008848262000797565b915081905092915050565b600060a082019050620008a66000830188620006c4565b620008b56020830187620006c4565b620008c46040830186620006c4565b620008d360608301856200080c565b620008e26080830184620006b3565b9695505050505050565b6000620008f86200090b565b905062000906828262000a56565b919050565b6000604051905090565b600067ffffffffffffffff82111562000933576200093262000abb565b5b6200093e8262000aea565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081905092915050565b600081905092915050565b60006200098e82620009b3565b9050919050565b6000819050919050565b6000620009ac8262000981565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b8381101562000a0a578082015181840152602081019050620009ed565b8381111562000a1a576000848401525b50505050565b6000600282049050600182168062000a3957607f821691505b6020821081141562000a505762000a4f62000a8c565b5b50919050565b62000a618262000aea565b810181811067ffffffffffffffff8211171562000a835762000a8262000abb565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f205661756c740000000000000000000000000000000000000000000000000000600082015250565b7f7376000000000000000000000000000000000000000000000000000000000000600082015250565b7f5369646553686966742000000000000000000000000000000000000000000000600082015250565b62000b818162000995565b811462000b8d57600080fd5b50565b62000b9b816200099f565b811462000ba757600080fd5b50565b62000bb581620009dd565b811462000bc157600080fd5b50565b60805160f81c60a05160c05160e05160601c6101005160601c61012051613cfc62000c6360003960008181610c860152818161101001526113ce0152600081816108aa015281816110db015281816118eb01528181611f5b0152611f840152600081816110b5015281816111f30152818161158701528181611c690152611f080152600061108e0152600061105a015260006110340152613cfc6000f3fe608060405234801561001057600080fd5b50600436106102525760003560e01c80637a7ec16711610146578063ba087652116100c3578063ce96cb7711610087578063ce96cb771461079b578063d505accf146107cb578063d905777e146107e7578063dd62ed3e14610817578063ef8b30f714610847578063f2fde38b1461087757610252565b8063ba087652146106cf578063c5b97dc2146106ff578063c5d664c61461071d578063c63d75b61461073b578063c6e6f5921461076b57610252565b806395d89b411161010a57806395d89b4114610605578063a9059cbb14610623578063b27c846b14610653578063b3d7f6b91461066f578063b460af941461069f57610252565b80637a7ec1671461053b5780637ecebe001461056b5780638da5cb5b1461059b5780638e759e6c146105b957806394bf804d146105d557610252565b806323b872dd116101d4578063402d267d11610198578063402d267d146104715780634cdad506146104a15780636e553f65146104d157806370a0823114610501578063715018a61461053157610252565b806323b872dd146103c95780632eb4a7ab146103f9578063313ce567146104175780633644e5151461043557806338d52e0f1461045357610252565b8063095ea7b31161021b578063095ea7b3146103115780630a28a4771461034157806317a8d8621461037157806318160ddd1461038f5780631d310f36146103ad57610252565b8062b347471461025757806301e1d1141461027557806305b0e4ae1461029357806306fdde03146102c357806307a2d13a146102e1575b600080fd5b61025f610893565b60405161026c9190613385565b60405180910390f35b61027d6108a6565b60405161028a91906136b1565b60405180910390f35b6102ad60048036038101906102a89190612c19565b610956565b6040516102ba9190613385565b60405180910390f35b6102cb610976565b6040516102d891906134cf565b60405180910390f35b6102fb60048036038101906102f69190612e3c565b610a04565b60405161030891906136b1565b60405180910390f35b61032b60048036038101906103269190612d6b565b610a3f565b6040516103389190613385565b60405180910390f35b61035b60048036038101906103569190612e3c565b610b31565b60405161036891906136b1565b60405180910390f35b610379610b6c565b6040516103869190613385565b60405180910390f35b610397610b7f565b6040516103a491906136b1565b60405180910390f35b6103c760048036038101906103c29190612da7565b610b85565b005b6103e360048036038101906103de9190612c7e565b610dc4565b6040516103f09190613385565b60405180910390f35b61040161100e565b60405161040e91906133a0565b60405180910390f35b61041f611032565b60405161042c91906136f5565b60405180910390f35b61043d611056565b60405161044a91906133a0565b60405180910390f35b61045b6110b3565b60405161046891906134b4565b60405180910390f35b61048b60048036038101906104869190612c19565b6110d7565b60405161049891906136b1565b60405180910390f35b6104bb60048036038101906104b69190612e3c565b611189565b6040516104c891906136b1565b60405180910390f35b6104eb60048036038101906104e69190612e8e565b61119b565b6040516104f891906136b1565b60405180910390f35b61051b60048036038101906105169190612c19565b6112b9565b60405161052891906136b1565b60405180910390f35b6105396112d1565b005b61055560048036038101906105509190612da7565b611359565b6040516105629190613385565b60405180910390f35b61058560048036038101906105809190612c19565b61143f565b60405161059291906136b1565b60405180910390f35b6105a3611457565b6040516105b09190613333565b60405180910390f35b6105d360048036038101906105ce9190612e3c565b611481565b005b6105ef60048036038101906105ea9190612e8e565b611572565b6040516105fc91906136b1565b60405180910390f35b61060d61164d565b60405161061a91906134cf565b60405180910390f35b61063d60048036038101906106389190612d6b565b6116db565b60405161064a9190613385565b60405180910390f35b61066d60048036038101906106689190612f19565b6117ef565b005b61068960048036038101906106849190612e3c565b611a1e565b60405161069691906136b1565b60405180910390f35b6106b960048036038101906106b49190612eca565b611a59565b6040516106c691906136b1565b60405180910390f35b6106e960048036038101906106e49190612eca565b611cb4565b6040516106f691906136b1565b60405180910390f35b610707611f53565b60405161071491906136b1565b60405180910390f35b610725611f59565b60405161073291906134b4565b60405180910390f35b61075560048036038101906107509190612c19565b611f7d565b60405161076291906136b1565b60405180910390f35b61078560048036038101906107809190612e3c565b612037565b60405161079291906136b1565b60405180910390f35b6107b560048036038101906107b09190612c19565b612072565b6040516107c291906136b1565b60405180910390f35b6107e560048036038101906107e09190612ccd565b6120c3565b005b61080160048036038101906107fc9190612c19565b6123bc565b60405161080e91906136b1565b60405180910390f35b610831600480360381019061082c9190612c42565b612405565b60405161083e91906136b1565b60405180910390f35b610861600480360381019061085c9190612e3c565b61242a565b60405161086e91906136b1565b60405180910390f35b610891600480360381019061088c9190612c19565b61243c565b005b600660149054906101000a900460ff1681565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109019190613333565b60206040518083038186803b15801561091957600080fd5b505afa15801561092d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109519190612e65565b905090565b60086020528060005260406000206000915054906101000a900460ff1681565b6000805461098390613897565b80601f01602080910402602001604051908101604052809291908181526020018280546109af90613897565b80156109fc5780601f106109d1576101008083540402835291602001916109fc565b820191906000526020600020905b8154815290600101906020018083116109df57829003601f168201915b505050505081565b600080600254905060008114610a3557610a30610a1f6108a6565b82856125349092919063ffffffff16565b610a37565b825b915050919050565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610b1f91906136b1565b60405180910390a36001905092915050565b600080600254905060008114610b6257610b5d81610b4d6108a6565b8561255c9092919063ffffffff16565b610b64565b825b915050919050565b600660159054906101000a900460ff1681565b60025481565b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610c12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0990613691565b60405180910390fd5b60008484604051602001610c279291906132b9565b604051602081830303815290604052805190602001209050610cab838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050507f00000000000000000000000000000000000000000000000000000000000000008361258e565b610cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce190613551565b60405180910390fd5b6001600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508360076000828254610d5491906137ad565b92505081905550610d6530856125a5565b610d6f8585612675565b8473ffffffffffffffffffffffffffffffffffffffff167f106e78f4438686ffff0ca4b3ec52c71cf3ef479de98aeaad834f46f440552e9785604051610db591906136b1565b60405180910390a25050505050565b600080600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610efa578281610e7991906137ad565b600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b82600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610f4991906137ad565b9250508190555082600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610ffa91906136b1565b60405180910390a360019150509392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f0000000000000000000000000000000000000000000000000000000000000000461461108c57611087612745565b6110ae565b7f00000000000000000000000000000000000000000000000000000000000000005b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016111329190613333565b60206040518083038186803b15801561114a57600080fd5b505afa15801561115e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111829190612e65565b9050919050565b600061119482610a04565b9050919050565b6000806111a78461242a565b91508114156111eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e2906134f1565b60405180910390fd5b6112383330857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166127d1909392919063ffffffff16565b6112428282612675565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d785846040516112a19291906136cc565b60405180910390a36112b38382612870565b92915050565b60036020528060005260406000206000915090505481565b6112d9612874565b73ffffffffffffffffffffffffffffffffffffffff166112f7611457565b73ffffffffffffffffffffffffffffffffffffffff161461134d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611344906135d1565b60405180910390fd5b611357600061287c565b565b600080858560405160200161136f9291906132b9565b6040516020818303038152906040528051906020012090506113f3848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050507f00000000000000000000000000000000000000000000000000000000000000008361258e565b611432576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142990613551565b60405180910390fd5b6001915050949350505050565b60056020528060005260406000206000915090505481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611489612874565b73ffffffffffffffffffffffffffffffffffffffff166114a7611457565b73ffffffffffffffffffffffffffffffffffffffff16146114fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f4906135d1565b60405180910390fd5b600754811115611542576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611539906135f1565b60405180910390fd5b806007600082825461155491906137ad565b9250508190555061156530826125a5565b61156f3382612675565b50565b600061157d83611a1e565b90506115cc3330837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166127d1909392919063ffffffff16565b6115d68284612675565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d783866040516116359291906136cc565b60405180910390a36116478184612870565b92915050565b6001805461165a90613897565b80601f016020809104026020016040519081016040528092919081815260200182805461168690613897565b80156116d35780601f106116a8576101008083540402835291602001916116d3565b820191906000526020600020905b8154815290600101906020018083116116b657829003601f168201915b505050505081565b600081600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172c91906137ad565b9250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516117dd91906136b1565b60405180910390a36001905092915050565b6117f7612874565b73ffffffffffffffffffffffffffffffffffffffff16611815611457565b73ffffffffffffffffffffffffffffffffffffffff161461186b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611862906135d1565b60405180910390fd5b600660149054906101000a900460ff16156118bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b290613511565b60405180910390fd5b6001600660146101000a81548160ff02191690831515021790555060006002819055506118e9828233612942565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b81526004016119469392919061334e565b602060405180830381600087803b15801561196057600080fd5b505af1158015611974573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119989190612e13565b6119d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ce90613571565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f2a1fd7531301a9bc9c459bb79a90dafb0f939766e2a8cec6931cb9034d9c1c0160405160405180910390a25050565b600080600254905060008114611a4f57611a4a611a396108a6565b828561255c9092919063ffffffff16565b611a51565b825b915050919050565b6000611a6484610b31565b90508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611bd0576000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611bce578181611b4d91906137ad565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b611bda8482612a03565b611be482826125a5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8785604051611c5a9291906136cc565b60405180910390a4611cad83857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16612a079092919063ffffffff16565b9392505050565b60008173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e20576000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611e1e578481611d9d91906137ad565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b6000611e2b85611189565b9150811415611e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6690613631565b60405180910390fd5b611e798185612a03565b611e8382856125a5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8488604051611ef99291906136cc565b60405180910390a4611f4c83827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16612a079092919063ffffffff16565b9392505050565b60075481565b7f000000000000000000000000000000000000000000000000000000000000000081565b60006120307f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b8152600401611fdb9190613333565b60206040518083038186803b158015611ff357600080fd5b505afa158015612007573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202b9190612e65565b61242a565b9050919050565b60008060025490506000811461206857612063816120536108a6565b856125349092919063ffffffff16565b61206a565b825b915050919050565b60006120bc600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610a04565b9050919050565b42841015612106576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120fd90613651565b60405180910390fd5b60006001612112611056565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98a8a8a600560008f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190600101919050558b60405160200161219a969594939291906133bb565b604051602081830303815290604052805190602001206040516020016121c19291906132fc565b60405160208183030381529060405280519060200120858585604051600081526020016040526040516121f7949392919061346f565b6020604051602081039080840390855afa158015612219573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561228d57508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6122cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c390613611565b60405180910390fd5b85600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925876040516123ab91906136b1565b60405180910390a350505050505050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6004602052816000526040600020602052806000526040600020600091509150505481565b600061243582612037565b9050919050565b612444612874565b73ffffffffffffffffffffffffffffffffffffffff16612462611457565b73ffffffffffffffffffffffffffffffffffffffff16146124b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124af906135d1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612528576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161251f90613531565b60405180910390fd5b6125318161287c565b50565b6000828402905082848204148415178215151661255057600080fd5b81810490509392505050565b6000828402905082848204148415178215151661257857600080fd5b6001826001830304018115150290509392505050565b60008261259b8584612a9f565b1490509392505050565b80600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546125f491906137ad565b9250508190555080600260008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161266991906136b1565b60405180910390a35050565b80600260008282546126879190613757565b9250508190555080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161273991906136b1565b60405180910390a35050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405161277791906132e5565b60405180910390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc646306040516020016127b695949392919061341c565b60405160208183030381529060405280519060200120905090565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080612869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286090613591565b60405180910390fd5b5050505050565b5050565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828214612984576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161297b90613671565b60405180910390fd5b6001600660156101000a81548160ff021916908315150217905550826007819055506129b03084612675565b8073ffffffffffffffffffffffffffffffffffffffff167f5e2721114e39241d48a241ba2ab0e6ed19218ce65096c56e4f5b90f9fbcdd821846040516129f691906136b1565b60405180910390a2505050565b5050565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080612a99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a90906135b1565b60405180910390fd5b50505050565b60008082905060005b8451811015612b2f576000858281518110612aec577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050808311612b0e57612b078382612b3a565b9250612b1b565b612b188184612b3a565b92505b508080612b27906138c9565b915050612aa8565b508091505092915050565b600082600052816020526040600020905092915050565b600081359050612b6081613c53565b92915050565b60008083601f840112612b7857600080fd5b8235905067ffffffffffffffff811115612b9157600080fd5b602083019150836020820283011115612ba957600080fd5b9250929050565b600081519050612bbf81613c6a565b92915050565b600081359050612bd481613c81565b92915050565b600081359050612be981613c98565b92915050565b600081519050612bfe81613c98565b92915050565b600081359050612c1381613caf565b92915050565b600060208284031215612c2b57600080fd5b6000612c3984828501612b51565b91505092915050565b60008060408385031215612c5557600080fd5b6000612c6385828601612b51565b9250506020612c7485828601612b51565b9150509250929050565b600080600060608486031215612c9357600080fd5b6000612ca186828701612b51565b9350506020612cb286828701612b51565b9250506040612cc386828701612bda565b9150509250925092565b600080600080600080600060e0888a031215612ce857600080fd5b6000612cf68a828b01612b51565b9750506020612d078a828b01612b51565b9650506040612d188a828b01612bda565b9550506060612d298a828b01612bda565b9450506080612d3a8a828b01612c04565b93505060a0612d4b8a828b01612bc5565b92505060c0612d5c8a828b01612bc5565b91505092959891949750929550565b60008060408385031215612d7e57600080fd5b6000612d8c85828601612b51565b9250506020612d9d85828601612bda565b9150509250929050565b60008060008060608587031215612dbd57600080fd5b6000612dcb87828801612b51565b9450506020612ddc87828801612bda565b935050604085013567ffffffffffffffff811115612df957600080fd5b612e0587828801612b66565b925092505092959194509250565b600060208284031215612e2557600080fd5b6000612e3384828501612bb0565b91505092915050565b600060208284031215612e4e57600080fd5b6000612e5c84828501612bda565b91505092915050565b600060208284031215612e7757600080fd5b6000612e8584828501612bef565b91505092915050565b60008060408385031215612ea157600080fd5b6000612eaf85828601612bda565b9250506020612ec085828601612b51565b9150509250929050565b600080600060608486031215612edf57600080fd5b6000612eed86828701612bda565b9350506020612efe86828701612b51565b9250506040612f0f86828701612b51565b9150509250925092565b60008060408385031215612f2c57600080fd5b6000612f3a85828601612bda565b9250506020612f4b85828601612bda565b9150509250929050565b612f5e816137e1565b82525050565b612f75612f70826137e1565b613912565b82525050565b612f84816137f3565b82525050565b612f93816137ff565b82525050565b612faa612fa5826137ff565b613924565b82525050565b60008154612fbd81613897565b612fc78186613730565b94506001821660008114612fe25760018114612ff357613026565b60ff19831686528186019350613026565b612ffc85613710565b60005b8381101561301e57815481890152600182019150602081019050612fff565b838801955050505b50505092915050565b61303881613840565b82525050565b600061304982613725565b613053818561373b565b9350613063818560208601613864565b61306c816139a8565b840191505092915050565b6000613084600b8361373b565b915061308f826139c6565b602082019050919050565b60006130a760138361373b565b91506130b2826139ef565b602082019050919050565b60006130ca60268361373b565b91506130d582613a18565b604082019050919050565b60006130ed60028361374c565b91506130f882613a67565b600282019050919050565b6000613110600d8361373b565b915061311b82613a90565b602082019050919050565b6000613133600d8361373b565b915061313e82613ab9565b602082019050919050565b600061315660148361373b565b915061316182613ae2565b602082019050919050565b6000613179600f8361373b565b915061318482613b0b565b602082019050919050565b600061319c60208361373b565b91506131a782613b34565b602082019050919050565b60006131bf600e8361373b565b91506131ca82613b5d565b602082019050919050565b60006131e2600e8361373b565b91506131ed82613b86565b602082019050919050565b6000613205600b8361373b565b915061321082613baf565b602082019050919050565b600061322860178361373b565b915061323382613bd8565b602082019050919050565b600061324b60138361373b565b915061325682613c01565b602082019050919050565b600061326e600f8361373b565b915061327982613c2a565b602082019050919050565b61328d81613829565b82525050565b6132a461329f82613829565b613940565b82525050565b6132b381613833565b82525050565b60006132c58285612f64565b6014820191506132d58284613293565b6020820191508190509392505050565b60006132f18284612fb0565b915081905092915050565b6000613307826130e0565b91506133138285612f99565b6020820191506133238284612f99565b6020820191508190509392505050565b60006020820190506133486000830184612f55565b92915050565b60006060820190506133636000830186612f55565b6133706020830185612f55565b61337d6040830184613284565b949350505050565b600060208201905061339a6000830184612f7b565b92915050565b60006020820190506133b56000830184612f8a565b92915050565b600060c0820190506133d06000830189612f8a565b6133dd6020830188612f55565b6133ea6040830187612f55565b6133f76060830186613284565b6134046080830185613284565b61341160a0830184613284565b979650505050505050565b600060a0820190506134316000830188612f8a565b61343e6020830187612f8a565b61344b6040830186612f8a565b6134586060830185613284565b6134656080830184612f55565b9695505050505050565b60006080820190506134846000830187612f8a565b61349160208301866132aa565b61349e6040830185612f8a565b6134ab6060830184612f8a565b95945050505050565b60006020820190506134c9600083018461302f565b92915050565b600060208201905081810360008301526134e9818461303e565b905092915050565b6000602082019050818103600083015261350a81613077565b9050919050565b6000602082019050818103600083015261352a8161309a565b9050919050565b6000602082019050818103600083015261354a816130bd565b9050919050565b6000602082019050818103600083015261356a81613103565b9050919050565b6000602082019050818103600083015261358a81613126565b9050919050565b600060208201905081810360008301526135aa81613149565b9050919050565b600060208201905081810360008301526135ca8161316c565b9050919050565b600060208201905081810360008301526135ea8161318f565b9050919050565b6000602082019050818103600083015261360a816131b2565b9050919050565b6000602082019050818103600083015261362a816131d5565b9050919050565b6000602082019050818103600083015261364a816131f8565b9050919050565b6000602082019050818103600083015261366a8161321b565b9050919050565b6000602082019050818103600083015261368a8161323e565b9050919050565b600060208201905081810360008301526136aa81613261565b9050919050565b60006020820190506136c66000830184613284565b92915050565b60006040820190506136e16000830185613284565b6136ee6020830184613284565b9392505050565b600060208201905061370a60008301846132aa565b92915050565b60008190508160005260206000209050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600061376282613829565b915061376d83613829565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156137a2576137a161394a565b5b828201905092915050565b60006137b882613829565b91506137c383613829565b9250828210156137d6576137d561394a565b5b828203905092915050565b60006137ec82613809565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061384b82613852565b9050919050565b600061385d82613809565b9050919050565b60005b83811015613882578082015181840152602081019050613867565b83811115613891576000848401525b50505050565b600060028204905060018216806138af57607f821691505b602082108114156138c3576138c2613979565b5b50919050565b60006138d482613829565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156139075761390661394a565b5b600182019050919050565b600061391d8261392e565b9050919050565b6000819050919050565b6000613939826139b9565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f5a45524f5f534841524553000000000000000000000000000000000000000000600082015250565b7f414c52454144595f494e495449414c495a454400000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b7f494e56414c49445f50524f4f4600000000000000000000000000000000000000600082015250565b7f5452414e534645525f4641494c00000000000000000000000000000000000000600082015250565b7f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000600082015250565b7f5452414e534645525f4641494c45440000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f434c41494d5f544f4f5f48494748000000000000000000000000000000000000600082015250565b7f494e56414c49445f5349474e4552000000000000000000000000000000000000600082015250565b7f5a45524f5f415353455453000000000000000000000000000000000000000000600082015250565b7f5045524d49545f444541444c494e455f45585049524544000000000000000000600082015250565b7f494e53554646494349454e545f414d4f554e5400000000000000000000000000600082015250565b7f414c52454144595f434c41494d45440000000000000000000000000000000000600082015250565b613c5c816137e1565b8114613c6757600080fd5b50565b613c73816137f3565b8114613c7e57600080fd5b50565b613c8a816137ff565b8114613c9557600080fd5b50565b613ca181613829565b8114613cac57600080fd5b50565b613cb881613833565b8114613cc357600080fd5b5056fea264697066735822122043d69df03a002bac0a079a7abac53568908dfb3ac6776337f411081088e36c5064736f6c6343000804003300000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23228b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f18
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102525760003560e01c80637a7ec16711610146578063ba087652116100c3578063ce96cb7711610087578063ce96cb771461079b578063d505accf146107cb578063d905777e146107e7578063dd62ed3e14610817578063ef8b30f714610847578063f2fde38b1461087757610252565b8063ba087652146106cf578063c5b97dc2146106ff578063c5d664c61461071d578063c63d75b61461073b578063c6e6f5921461076b57610252565b806395d89b411161010a57806395d89b4114610605578063a9059cbb14610623578063b27c846b14610653578063b3d7f6b91461066f578063b460af941461069f57610252565b80637a7ec1671461053b5780637ecebe001461056b5780638da5cb5b1461059b5780638e759e6c146105b957806394bf804d146105d557610252565b806323b872dd116101d4578063402d267d11610198578063402d267d146104715780634cdad506146104a15780636e553f65146104d157806370a0823114610501578063715018a61461053157610252565b806323b872dd146103c95780632eb4a7ab146103f9578063313ce567146104175780633644e5151461043557806338d52e0f1461045357610252565b8063095ea7b31161021b578063095ea7b3146103115780630a28a4771461034157806317a8d8621461037157806318160ddd1461038f5780631d310f36146103ad57610252565b8062b347471461025757806301e1d1141461027557806305b0e4ae1461029357806306fdde03146102c357806307a2d13a146102e1575b600080fd5b61025f610893565b60405161026c9190613385565b60405180910390f35b61027d6108a6565b60405161028a91906136b1565b60405180910390f35b6102ad60048036038101906102a89190612c19565b610956565b6040516102ba9190613385565b60405180910390f35b6102cb610976565b6040516102d891906134cf565b60405180910390f35b6102fb60048036038101906102f69190612e3c565b610a04565b60405161030891906136b1565b60405180910390f35b61032b60048036038101906103269190612d6b565b610a3f565b6040516103389190613385565b60405180910390f35b61035b60048036038101906103569190612e3c565b610b31565b60405161036891906136b1565b60405180910390f35b610379610b6c565b6040516103869190613385565b60405180910390f35b610397610b7f565b6040516103a491906136b1565b60405180910390f35b6103c760048036038101906103c29190612da7565b610b85565b005b6103e360048036038101906103de9190612c7e565b610dc4565b6040516103f09190613385565b60405180910390f35b61040161100e565b60405161040e91906133a0565b60405180910390f35b61041f611032565b60405161042c91906136f5565b60405180910390f35b61043d611056565b60405161044a91906133a0565b60405180910390f35b61045b6110b3565b60405161046891906134b4565b60405180910390f35b61048b60048036038101906104869190612c19565b6110d7565b60405161049891906136b1565b60405180910390f35b6104bb60048036038101906104b69190612e3c565b611189565b6040516104c891906136b1565b60405180910390f35b6104eb60048036038101906104e69190612e8e565b61119b565b6040516104f891906136b1565b60405180910390f35b61051b60048036038101906105169190612c19565b6112b9565b60405161052891906136b1565b60405180910390f35b6105396112d1565b005b61055560048036038101906105509190612da7565b611359565b6040516105629190613385565b60405180910390f35b61058560048036038101906105809190612c19565b61143f565b60405161059291906136b1565b60405180910390f35b6105a3611457565b6040516105b09190613333565b60405180910390f35b6105d360048036038101906105ce9190612e3c565b611481565b005b6105ef60048036038101906105ea9190612e8e565b611572565b6040516105fc91906136b1565b60405180910390f35b61060d61164d565b60405161061a91906134cf565b60405180910390f35b61063d60048036038101906106389190612d6b565b6116db565b60405161064a9190613385565b60405180910390f35b61066d60048036038101906106689190612f19565b6117ef565b005b61068960048036038101906106849190612e3c565b611a1e565b60405161069691906136b1565b60405180910390f35b6106b960048036038101906106b49190612eca565b611a59565b6040516106c691906136b1565b60405180910390f35b6106e960048036038101906106e49190612eca565b611cb4565b6040516106f691906136b1565b60405180910390f35b610707611f53565b60405161071491906136b1565b60405180910390f35b610725611f59565b60405161073291906134b4565b60405180910390f35b61075560048036038101906107509190612c19565b611f7d565b60405161076291906136b1565b60405180910390f35b61078560048036038101906107809190612e3c565b612037565b60405161079291906136b1565b60405180910390f35b6107b560048036038101906107b09190612c19565b612072565b6040516107c291906136b1565b60405180910390f35b6107e560048036038101906107e09190612ccd565b6120c3565b005b61080160048036038101906107fc9190612c19565b6123bc565b60405161080e91906136b1565b60405180910390f35b610831600480360381019061082c9190612c42565b612405565b60405161083e91906136b1565b60405180910390f35b610861600480360381019061085c9190612e3c565b61242a565b60405161086e91906136b1565b60405180910390f35b610891600480360381019061088c9190612c19565b61243c565b005b600660149054906101000a900460ff1681565b60007f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109019190613333565b60206040518083038186803b15801561091957600080fd5b505afa15801561092d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109519190612e65565b905090565b60086020528060005260406000206000915054906101000a900460ff1681565b6000805461098390613897565b80601f01602080910402602001604051908101604052809291908181526020018280546109af90613897565b80156109fc5780601f106109d1576101008083540402835291602001916109fc565b820191906000526020600020905b8154815290600101906020018083116109df57829003601f168201915b505050505081565b600080600254905060008114610a3557610a30610a1f6108a6565b82856125349092919063ffffffff16565b610a37565b825b915050919050565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610b1f91906136b1565b60405180910390a36001905092915050565b600080600254905060008114610b6257610b5d81610b4d6108a6565b8561255c9092919063ffffffff16565b610b64565b825b915050919050565b600660159054906101000a900460ff1681565b60025481565b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610c12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0990613691565b60405180910390fd5b60008484604051602001610c279291906132b9565b604051602081830303815290604052805190602001209050610cab838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050507f28b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f188361258e565b610cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce190613551565b60405180910390fd5b6001600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508360076000828254610d5491906137ad565b92505081905550610d6530856125a5565b610d6f8585612675565b8473ffffffffffffffffffffffffffffffffffffffff167f106e78f4438686ffff0ca4b3ec52c71cf3ef479de98aeaad834f46f440552e9785604051610db591906136b1565b60405180910390a25050505050565b600080600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610efa578281610e7991906137ad565b600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b82600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610f4991906137ad565b9250508190555082600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610ffa91906136b1565b60405180910390a360019150509392505050565b7f28b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f1881565b7f000000000000000000000000000000000000000000000000000000000000001281565b60007f0000000000000000000000000000000000000000000000000000000000000001461461108c57611087612745565b6110ae565b7f25397cdf941a1602956af6334de7c2e9c07bfd9c86b545cbdc4f7976dc4aa0a85b905090565b7f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23281565b60007f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016111329190613333565b60206040518083038186803b15801561114a57600080fd5b505afa15801561115e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111829190612e65565b9050919050565b600061119482610a04565b9050919050565b6000806111a78461242a565b91508114156111eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e2906134f1565b60405180910390fd5b6112383330857f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166127d1909392919063ffffffff16565b6112428282612675565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d785846040516112a19291906136cc565b60405180910390a36112b38382612870565b92915050565b60036020528060005260406000206000915090505481565b6112d9612874565b73ffffffffffffffffffffffffffffffffffffffff166112f7611457565b73ffffffffffffffffffffffffffffffffffffffff161461134d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611344906135d1565b60405180910390fd5b611357600061287c565b565b600080858560405160200161136f9291906132b9565b6040516020818303038152906040528051906020012090506113f3848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050507f28b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f188361258e565b611432576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142990613551565b60405180910390fd5b6001915050949350505050565b60056020528060005260406000206000915090505481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611489612874565b73ffffffffffffffffffffffffffffffffffffffff166114a7611457565b73ffffffffffffffffffffffffffffffffffffffff16146114fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f4906135d1565b60405180910390fd5b600754811115611542576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611539906135f1565b60405180910390fd5b806007600082825461155491906137ad565b9250508190555061156530826125a5565b61156f3382612675565b50565b600061157d83611a1e565b90506115cc3330837f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166127d1909392919063ffffffff16565b6115d68284612675565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d783866040516116359291906136cc565b60405180910390a36116478184612870565b92915050565b6001805461165a90613897565b80601f016020809104026020016040519081016040528092919081815260200182805461168690613897565b80156116d35780601f106116a8576101008083540402835291602001916116d3565b820191906000526020600020905b8154815290600101906020018083116116b657829003601f168201915b505050505081565b600081600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172c91906137ad565b9250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516117dd91906136b1565b60405180910390a36001905092915050565b6117f7612874565b73ffffffffffffffffffffffffffffffffffffffff16611815611457565b73ffffffffffffffffffffffffffffffffffffffff161461186b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611862906135d1565b60405180910390fd5b600660149054906101000a900460ff16156118bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b290613511565b60405180910390fd5b6001600660146101000a81548160ff02191690831515021790555060006002819055506118e9828233612942565b7f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b81526004016119469392919061334e565b602060405180830381600087803b15801561196057600080fd5b505af1158015611974573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119989190612e13565b6119d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ce90613571565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f2a1fd7531301a9bc9c459bb79a90dafb0f939766e2a8cec6931cb9034d9c1c0160405160405180910390a25050565b600080600254905060008114611a4f57611a4a611a396108a6565b828561255c9092919063ffffffff16565b611a51565b825b915050919050565b6000611a6484610b31565b90508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611bd0576000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611bce578181611b4d91906137ad565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b611bda8482612a03565b611be482826125a5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8785604051611c5a9291906136cc565b60405180910390a4611cad83857f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff16612a079092919063ffffffff16565b9392505050565b60008173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e20576000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611e1e578481611d9d91906137ad565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b6000611e2b85611189565b9150811415611e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6690613631565b60405180910390fd5b611e798185612a03565b611e8382856125a5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8488604051611ef99291906136cc565b60405180910390a4611f4c83827f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff16612a079092919063ffffffff16565b9392505050565b60075481565b7f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23281565b60006120307f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b8152600401611fdb9190613333565b60206040518083038186803b158015611ff357600080fd5b505afa158015612007573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202b9190612e65565b61242a565b9050919050565b60008060025490506000811461206857612063816120536108a6565b856125349092919063ffffffff16565b61206a565b825b915050919050565b60006120bc600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610a04565b9050919050565b42841015612106576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120fd90613651565b60405180910390fd5b60006001612112611056565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98a8a8a600560008f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190600101919050558b60405160200161219a969594939291906133bb565b604051602081830303815290604052805190602001206040516020016121c19291906132fc565b60405160208183030381529060405280519060200120858585604051600081526020016040526040516121f7949392919061346f565b6020604051602081039080840390855afa158015612219573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561228d57508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6122cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c390613611565b60405180910390fd5b85600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925876040516123ab91906136b1565b60405180910390a350505050505050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6004602052816000526040600020602052806000526040600020600091509150505481565b600061243582612037565b9050919050565b612444612874565b73ffffffffffffffffffffffffffffffffffffffff16612462611457565b73ffffffffffffffffffffffffffffffffffffffff16146124b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124af906135d1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612528576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161251f90613531565b60405180910390fd5b6125318161287c565b50565b6000828402905082848204148415178215151661255057600080fd5b81810490509392505050565b6000828402905082848204148415178215151661257857600080fd5b6001826001830304018115150290509392505050565b60008261259b8584612a9f565b1490509392505050565b80600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546125f491906137ad565b9250508190555080600260008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161266991906136b1565b60405180910390a35050565b80600260008282546126879190613757565b9250508190555080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161273991906136b1565b60405180910390a35050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405161277791906132e5565b60405180910390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc646306040516020016127b695949392919061341c565b60405160208183030381529060405280519060200120905090565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080612869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286090613591565b60405180910390fd5b5050505050565b5050565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828214612984576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161297b90613671565b60405180910390fd5b6001600660156101000a81548160ff021916908315150217905550826007819055506129b03084612675565b8073ffffffffffffffffffffffffffffffffffffffff167f5e2721114e39241d48a241ba2ab0e6ed19218ce65096c56e4f5b90f9fbcdd821846040516129f691906136b1565b60405180910390a2505050565b5050565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080612a99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a90906135b1565b60405180910390fd5b50505050565b60008082905060005b8451811015612b2f576000858281518110612aec577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050808311612b0e57612b078382612b3a565b9250612b1b565b612b188184612b3a565b92505b508080612b27906138c9565b915050612aa8565b508091505092915050565b600082600052816020526040600020905092915050565b600081359050612b6081613c53565b92915050565b60008083601f840112612b7857600080fd5b8235905067ffffffffffffffff811115612b9157600080fd5b602083019150836020820283011115612ba957600080fd5b9250929050565b600081519050612bbf81613c6a565b92915050565b600081359050612bd481613c81565b92915050565b600081359050612be981613c98565b92915050565b600081519050612bfe81613c98565b92915050565b600081359050612c1381613caf565b92915050565b600060208284031215612c2b57600080fd5b6000612c3984828501612b51565b91505092915050565b60008060408385031215612c5557600080fd5b6000612c6385828601612b51565b9250506020612c7485828601612b51565b9150509250929050565b600080600060608486031215612c9357600080fd5b6000612ca186828701612b51565b9350506020612cb286828701612b51565b9250506040612cc386828701612bda565b9150509250925092565b600080600080600080600060e0888a031215612ce857600080fd5b6000612cf68a828b01612b51565b9750506020612d078a828b01612b51565b9650506040612d188a828b01612bda565b9550506060612d298a828b01612bda565b9450506080612d3a8a828b01612c04565b93505060a0612d4b8a828b01612bc5565b92505060c0612d5c8a828b01612bc5565b91505092959891949750929550565b60008060408385031215612d7e57600080fd5b6000612d8c85828601612b51565b9250506020612d9d85828601612bda565b9150509250929050565b60008060008060608587031215612dbd57600080fd5b6000612dcb87828801612b51565b9450506020612ddc87828801612bda565b935050604085013567ffffffffffffffff811115612df957600080fd5b612e0587828801612b66565b925092505092959194509250565b600060208284031215612e2557600080fd5b6000612e3384828501612bb0565b91505092915050565b600060208284031215612e4e57600080fd5b6000612e5c84828501612bda565b91505092915050565b600060208284031215612e7757600080fd5b6000612e8584828501612bef565b91505092915050565b60008060408385031215612ea157600080fd5b6000612eaf85828601612bda565b9250506020612ec085828601612b51565b9150509250929050565b600080600060608486031215612edf57600080fd5b6000612eed86828701612bda565b9350506020612efe86828701612b51565b9250506040612f0f86828701612b51565b9150509250925092565b60008060408385031215612f2c57600080fd5b6000612f3a85828601612bda565b9250506020612f4b85828601612bda565b9150509250929050565b612f5e816137e1565b82525050565b612f75612f70826137e1565b613912565b82525050565b612f84816137f3565b82525050565b612f93816137ff565b82525050565b612faa612fa5826137ff565b613924565b82525050565b60008154612fbd81613897565b612fc78186613730565b94506001821660008114612fe25760018114612ff357613026565b60ff19831686528186019350613026565b612ffc85613710565b60005b8381101561301e57815481890152600182019150602081019050612fff565b838801955050505b50505092915050565b61303881613840565b82525050565b600061304982613725565b613053818561373b565b9350613063818560208601613864565b61306c816139a8565b840191505092915050565b6000613084600b8361373b565b915061308f826139c6565b602082019050919050565b60006130a760138361373b565b91506130b2826139ef565b602082019050919050565b60006130ca60268361373b565b91506130d582613a18565b604082019050919050565b60006130ed60028361374c565b91506130f882613a67565b600282019050919050565b6000613110600d8361373b565b915061311b82613a90565b602082019050919050565b6000613133600d8361373b565b915061313e82613ab9565b602082019050919050565b600061315660148361373b565b915061316182613ae2565b602082019050919050565b6000613179600f8361373b565b915061318482613b0b565b602082019050919050565b600061319c60208361373b565b91506131a782613b34565b602082019050919050565b60006131bf600e8361373b565b91506131ca82613b5d565b602082019050919050565b60006131e2600e8361373b565b91506131ed82613b86565b602082019050919050565b6000613205600b8361373b565b915061321082613baf565b602082019050919050565b600061322860178361373b565b915061323382613bd8565b602082019050919050565b600061324b60138361373b565b915061325682613c01565b602082019050919050565b600061326e600f8361373b565b915061327982613c2a565b602082019050919050565b61328d81613829565b82525050565b6132a461329f82613829565b613940565b82525050565b6132b381613833565b82525050565b60006132c58285612f64565b6014820191506132d58284613293565b6020820191508190509392505050565b60006132f18284612fb0565b915081905092915050565b6000613307826130e0565b91506133138285612f99565b6020820191506133238284612f99565b6020820191508190509392505050565b60006020820190506133486000830184612f55565b92915050565b60006060820190506133636000830186612f55565b6133706020830185612f55565b61337d6040830184613284565b949350505050565b600060208201905061339a6000830184612f7b565b92915050565b60006020820190506133b56000830184612f8a565b92915050565b600060c0820190506133d06000830189612f8a565b6133dd6020830188612f55565b6133ea6040830187612f55565b6133f76060830186613284565b6134046080830185613284565b61341160a0830184613284565b979650505050505050565b600060a0820190506134316000830188612f8a565b61343e6020830187612f8a565b61344b6040830186612f8a565b6134586060830185613284565b6134656080830184612f55565b9695505050505050565b60006080820190506134846000830187612f8a565b61349160208301866132aa565b61349e6040830185612f8a565b6134ab6060830184612f8a565b95945050505050565b60006020820190506134c9600083018461302f565b92915050565b600060208201905081810360008301526134e9818461303e565b905092915050565b6000602082019050818103600083015261350a81613077565b9050919050565b6000602082019050818103600083015261352a8161309a565b9050919050565b6000602082019050818103600083015261354a816130bd565b9050919050565b6000602082019050818103600083015261356a81613103565b9050919050565b6000602082019050818103600083015261358a81613126565b9050919050565b600060208201905081810360008301526135aa81613149565b9050919050565b600060208201905081810360008301526135ca8161316c565b9050919050565b600060208201905081810360008301526135ea8161318f565b9050919050565b6000602082019050818103600083015261360a816131b2565b9050919050565b6000602082019050818103600083015261362a816131d5565b9050919050565b6000602082019050818103600083015261364a816131f8565b9050919050565b6000602082019050818103600083015261366a8161321b565b9050919050565b6000602082019050818103600083015261368a8161323e565b9050919050565b600060208201905081810360008301526136aa81613261565b9050919050565b60006020820190506136c66000830184613284565b92915050565b60006040820190506136e16000830185613284565b6136ee6020830184613284565b9392505050565b600060208201905061370a60008301846132aa565b92915050565b60008190508160005260206000209050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600061376282613829565b915061376d83613829565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156137a2576137a161394a565b5b828201905092915050565b60006137b882613829565b91506137c383613829565b9250828210156137d6576137d561394a565b5b828203905092915050565b60006137ec82613809565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061384b82613852565b9050919050565b600061385d82613809565b9050919050565b60005b83811015613882578082015181840152602081019050613867565b83811115613891576000848401525b50505050565b600060028204905060018216806138af57607f821691505b602082108114156138c3576138c2613979565b5b50919050565b60006138d482613829565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156139075761390661394a565b5b600182019050919050565b600061391d8261392e565b9050919050565b6000819050919050565b6000613939826139b9565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f5a45524f5f534841524553000000000000000000000000000000000000000000600082015250565b7f414c52454144595f494e495449414c495a454400000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b7f494e56414c49445f50524f4f4600000000000000000000000000000000000000600082015250565b7f5452414e534645525f4641494c00000000000000000000000000000000000000600082015250565b7f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000600082015250565b7f5452414e534645525f4641494c45440000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f434c41494d5f544f4f5f48494748000000000000000000000000000000000000600082015250565b7f494e56414c49445f5349474e4552000000000000000000000000000000000000600082015250565b7f5a45524f5f415353455453000000000000000000000000000000000000000000600082015250565b7f5045524d49545f444541444c494e455f45585049524544000000000000000000600082015250565b7f494e53554646494349454e545f414d4f554e5400000000000000000000000000600082015250565b7f414c52454144595f434c41494d45440000000000000000000000000000000000600082015250565b613c5c816137e1565b8114613c6757600080fd5b50565b613c73816137f3565b8114613c7e57600080fd5b50565b613c8a816137ff565b8114613c9557600080fd5b50565b613ca181613829565b8114613cac57600080fd5b50565b613cb881613833565b8114613cc357600080fd5b5056fea264697066735822122043d69df03a002bac0a079a7abac53568908dfb3ac6776337f411081088e36c5064736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23228b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f18
-----Decoded View---------------
Arg [0] : _UNDERLYING (address): 0x35e78b3982E87ecfD5b3f3265B601c046cDBe232
Arg [1] : _merkleRoot (bytes32): 0x28b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f18
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe232
Arg [1] : 28b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f18
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.