More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 307 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Approve | 129423912 | 32 days ago | IN | 0 ETH | 0.000000274474 | ||||
Approve | 129423635 | 32 days ago | IN | 0 ETH | 0.000000317705 | ||||
Approve | 126763220 | 93 days ago | IN | 0 ETH | 0.00000035114 | ||||
Approve | 123086378 | 178 days ago | IN | 0 ETH | 0.000002877057 | ||||
Approve | 115100887 | 363 days ago | IN | 0 ETH | 0.000018866465 | ||||
Approve | 114880565 | 368 days ago | IN | 0 ETH | 0.000045386866 | ||||
Approve | 114723936 | 372 days ago | IN | 0 ETH | 0.000031277991 | ||||
Approve | 113798588 | 393 days ago | IN | 0 ETH | 0.00006207113 | ||||
Approve | 111920700 | 437 days ago | IN | 0 ETH | 0.000033587626 | ||||
Approve | 111920675 | 437 days ago | IN | 0 ETH | 0.000033723202 | ||||
Approve | 111646782 | 443 days ago | IN | 0 ETH | 0.000046734865 | ||||
Approve | 110553536 | 468 days ago | IN | 0 ETH | 0.00001229604 | ||||
Approve | 110265134 | 475 days ago | IN | 0 ETH | 0.000013552572 | ||||
Approve | 109481464 | 493 days ago | IN | 0 ETH | 0.000016000176 | ||||
Approve | 108906198 | 507 days ago | IN | 0 ETH | 0.000065071534 | ||||
Approve | 108903506 | 507 days ago | IN | 0 ETH | 0.000092007887 | ||||
Approve | 108903142 | 507 days ago | IN | 0 ETH | 0.000070966569 | ||||
Approve | 108752762 | 510 days ago | IN | 0 ETH | 0.000017221024 | ||||
Approve | 108211414 | 523 days ago | IN | 0 ETH | 0.000036966301 | ||||
Approve | 108069778 | 526 days ago | IN | 0 ETH | 0.000024299348 | ||||
Approve | 107505009 | 539 days ago | IN | 0 ETH | 0.000028431244 | ||||
Approve | 107116649 | 548 days ago | IN | 0 ETH | 0.000024453709 | ||||
Approve | 107083306 | 549 days ago | IN | 0 ETH | 0.00002421784 | ||||
Approve | 106977866 | 551 days ago | IN | 0 ETH | 0.00002221298 | ||||
Approve | 106908136 | 553 days ago | IN | 0 ETH | 0.000021106618 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
107558218 | 538 days ago | 0 ETH | ||||
107558218 | 538 days ago | 0 ETH | ||||
107558218 | 538 days ago | 0 ETH | ||||
107558218 | 538 days ago | 0 ETH | ||||
107558218 | 538 days ago | 0 ETH | ||||
107558218 | 538 days ago | 0 ETH | ||||
107558218 | 538 days ago | 0 ETH | ||||
107558218 | 538 days ago | 0 ETH | ||||
107558218 | 538 days ago | 0 ETH | ||||
107558218 | 538 days ago | 0 ETH | ||||
107557978 | 538 days ago | 0 ETH | ||||
107557978 | 538 days ago | 0 ETH | ||||
107557978 | 538 days ago | 0 ETH | ||||
107557978 | 538 days ago | 0 ETH | ||||
107557978 | 538 days ago | 0 ETH | ||||
107557978 | 538 days ago | 0 ETH | ||||
107557978 | 538 days ago | 0 ETH | ||||
107557978 | 538 days ago | 0 ETH | ||||
107557978 | 538 days ago | 0 ETH | ||||
107557978 | 538 days ago | 0 ETH | ||||
107557843 | 538 days ago | 0 ETH | ||||
107557843 | 538 days ago | 0 ETH | ||||
107557843 | 538 days ago | 0 ETH | ||||
107557843 | 538 days ago | 0 ETH | ||||
107557843 | 538 days ago | 0 ETH |
Loading...
Loading
Contract Name:
StablePool
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.0; import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol"; import {ReentrancyGuard} from "@rari-capital/solmate/src/utils/ReentrancyGuard.sol"; import {IBentoBoxMinimal} from "../../interfaces/IBentoBoxMinimal.sol"; import {IMasterDeployerV2} from "../../interfaces/IMasterDeployerV2.sol"; import {IPool} from "../../interfaces/IPool.sol"; import {IStablePoolFactory} from "../../interfaces/IStablePoolFactory.sol"; import {IERC20, SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {TridentMath} from "../../libraries/TridentMath.sol"; import "../../libraries/RebaseLibrary.sol"; /// @dev Custom Errors error ZeroAddress(); error IdenticalAddress(); error InvalidSwapFee(); error InsufficientLiquidityMinted(); error InvalidAmounts(); error InvalidInputToken(); error PoolUninitialized(); error InvalidOutputToken(); /// @notice Trident exchange pool template with stable swap (solidly exchange) for swapping between tightly correlated assets contract StablePool is IPool, ERC20, ReentrancyGuard { using RebaseLibrary for Rebase; using SafeERC20 for IERC20; event Mint(address indexed sender, uint256 amount0, uint256 amount1, address indexed recipient); event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed recipient); event Sync(uint256 reserve0, uint256 reserve1); uint256 internal constant MINIMUM_LIQUIDITY = 1000; uint256 internal constant MAX_FEE = 10000; // @dev 100%. uint256 public immutable swapFee; uint256 internal immutable MAX_FEE_MINUS_SWAP_FEE; IBentoBoxMinimal public immutable bento; IMasterDeployerV2 public immutable masterDeployer; address public immutable token0; address public immutable token1; uint256 public barFee; address public barFeeTo; uint256 public kLast; uint256 internal reserve0; uint256 internal reserve1; uint256 public immutable decimals0; uint256 public immutable decimals1; bytes32 public constant poolIdentifier = "Trident:StablePool"; constructor() ERC20("Sushi Stable LP Token", "SSLP", 18) { (bytes memory _deployData, IMasterDeployerV2 _masterDeployer) = IStablePoolFactory(msg.sender).getDeployData(); (address _token0, address _token1, uint256 _swapFee) = abi.decode(_deployData, (address, address, uint256)); // Factory ensures that the tokens are sorted. if (_token0 == address(0)) revert ZeroAddress(); if (_token0 == _token1) revert IdenticalAddress(); if (_swapFee > MAX_FEE) revert InvalidSwapFee(); token0 = _token0; token1 = _token1; swapFee = _swapFee; // This is safe from underflow - `swapFee` cannot exceed `MAX_FEE` per previous check. unchecked { MAX_FEE_MINUS_SWAP_FEE = MAX_FEE - _swapFee; } decimals0 = uint256(10)**(ERC20(_token0).decimals()); decimals1 = uint256(10)**(ERC20(_token1).decimals()); barFee = _masterDeployer.barFee(); barFeeTo = _masterDeployer.barFeeTo(); bento = IBentoBoxMinimal(_masterDeployer.bento()); masterDeployer = _masterDeployer; } /// @dev Mints LP tokens - should be called via the router after transferring `bento` tokens. /// The router must ensure that sufficient LP tokens are minted by using the return value. function mint(bytes calldata data) public override nonReentrant returns (uint256 liquidity) { address recipient = abi.decode(data, (address)); (uint256 _reserve0, uint256 _reserve1) = _getReserves(); (uint256 balance0, uint256 balance1) = _balance(); uint256 newLiq = _computeLiquidity(balance0, balance1); uint256 amount0 = balance0 - _reserve0; uint256 amount1 = balance1 - _reserve1; (uint256 fee0, uint256 fee1) = _nonOptimalMintFee(amount0, amount1, _reserve0, _reserve1); _reserve0 += uint112(fee0); _reserve1 += uint112(fee1); (uint256 _totalSupply, uint256 oldLiq) = _mintFee(_reserve0, _reserve1); if (_totalSupply == 0) { if (amount0 == 0 || amount1 == 0) revert InvalidAmounts(); liquidity = newLiq - MINIMUM_LIQUIDITY; _mint(address(0), MINIMUM_LIQUIDITY); } else { liquidity = ((newLiq - oldLiq) * _totalSupply) / oldLiq; } if (liquidity == 0) revert InsufficientLiquidityMinted(); _mint(recipient, liquidity); _updateReserves(); kLast = newLiq; emit Mint(msg.sender, amount0, amount1, recipient); } /// @dev Burns LP tokens sent to this contract. The router must ensure that the user gets sufficient output tokens. function burn(bytes calldata data) public override nonReentrant returns (IPool.TokenAmount[] memory withdrawnAmounts) { (address recipient, bool unwrapBento) = abi.decode(data, (address, bool)); (uint256 balance0, uint256 balance1) = _balance(); uint256 liquidity = balanceOf[address(this)]; (uint256 _totalSupply, ) = _mintFee(balance0, balance1); uint256 amount0 = (liquidity * balance0) / _totalSupply; uint256 amount1 = (liquidity * balance1) / _totalSupply; _burn(address(this), liquidity); _transfer(token0, amount0, recipient, unwrapBento); _transfer(token1, amount1, recipient, unwrapBento); _updateReserves(); withdrawnAmounts = new TokenAmount[](2); withdrawnAmounts[0] = TokenAmount({token: token0, amount: amount0}); withdrawnAmounts[1] = TokenAmount({token: token1, amount: amount1}); kLast = _computeLiquidity(balance0 - amount0, balance1 - amount1); emit Burn(msg.sender, amount0, amount1, recipient); } function burnSingle(bytes calldata data) public override nonReentrant returns (uint256 amountOut) { (address tokenOut, address recipient, bool unwrapBento) = abi.decode(data, (address, address, bool)); (uint256 _reserve0, uint256 _reserve1) = _getReserves(); (uint256 balance0, uint256 balance1) = _balance(); uint256 liquidity = balanceOf[address(this)]; (uint256 _totalSupply, ) = _mintFee(balance0, balance1); uint256 amount0 = (liquidity * balance0) / _totalSupply; uint256 amount1 = (liquidity * balance1) / _totalSupply; kLast = _computeLiquidity(balance0 - amount0, balance1 - amount1); _burn(address(this), liquidity); unchecked { if (tokenOut == token1) { amount1 += _getAmountOut(amount0, _reserve0 - amount0, _reserve1 - amount1, true); _transfer(token1, amount1, recipient, unwrapBento); amountOut = amount1; amount0 = 0; } else { if (tokenOut != token0) revert InvalidOutputToken(); amount0 += _getAmountOut(amount1, _reserve0 - amount0, _reserve1 - amount1, false); _transfer(token0, amount0, recipient, unwrapBento); amountOut = amount0; amount1 = 0; } } _updateReserves(); emit Burn(msg.sender, amount0, amount1, recipient); } /// @dev Swaps one token for another. The router must prefund this contract and ensure there isn't too much slippage. function swap(bytes calldata data) public override nonReentrant returns (uint256 amountOut) { (address tokenIn, address recipient, bool unwrapBento) = abi.decode(data, (address, address, bool)); (uint256 _reserve0, uint256 _reserve1, uint256 balance0, uint256 balance1) = _getReservesAndBalances(); uint256 amountIn; address tokenOut; if (tokenIn == token0) { tokenOut = token1; unchecked { amountIn = balance0 - _reserve0; } amountOut = _getAmountOut(amountIn, _reserve0, _reserve1, true); } else { if (tokenIn != token1) revert InvalidInputToken(); tokenOut = token0; unchecked { amountIn = balance1 - _reserve1; } amountOut = _getAmountOut(amountIn, _reserve0, _reserve1, false); } _transfer(tokenOut, amountOut, recipient, unwrapBento); _updateReserves(); emit Swap(recipient, tokenIn, tokenOut, amountIn, amountOut); } /// @dev Updates `barFee` and `barFeeTo` for Trident protocol. function updateBarParameters() public { barFee = masterDeployer.barFee(); barFeeTo = masterDeployer.barFeeTo(); } function _balance() internal view returns (uint256 balance0, uint256 balance1) { balance0 = bento.toAmount(token0, bento.balanceOf(token0, address(this)), false); balance1 = bento.toAmount(token1, bento.balanceOf(token1, address(this)), false); } function _getReservesAndBalances() internal view returns ( uint256 _reserve0, uint256 _reserve1, uint256 balance0, uint256 balance1 ) { (_reserve0, _reserve1) = (reserve0, reserve1); balance0 = bento.balanceOf(token0, address(this)); balance1 = bento.balanceOf(token1, address(this)); Rebase memory total0 = bento.totals(token0); Rebase memory total1 = bento.totals(token1); balance0 = total0.toElastic(balance0); balance1 = total1.toElastic(balance1); } function _updateReserves() internal { (uint256 _reserve0, uint256 _reserve1) = _balance(); reserve0 = _reserve0; reserve1 = _reserve1; emit Sync(_reserve0, _reserve1); } function _computeLiquidity(uint256 _reserve0, uint256 _reserve1) internal view returns (uint256 liquidity) { unchecked { uint256 adjustedReserve0 = (_reserve0 * 1e12) / decimals0; uint256 adjustedReserve1 = (_reserve1 * 1e12) / decimals1; liquidity = _computeLiquidityFromAdjustedBalances(adjustedReserve0, adjustedReserve1); } } function _computeLiquidityFromAdjustedBalances(uint256 x, uint256 y) internal pure returns (uint256 computed) { return TridentMath.sqrt(TridentMath.sqrt(_k(x, y))); } function _mintFee(uint256 _reserve0, uint256 _reserve1) internal returns (uint256 _totalSupply, uint256 computed) { _totalSupply = totalSupply; uint256 _kLast = kLast; if (_kLast != 0) { computed = _computeLiquidity(_reserve0, _reserve1); if (computed > _kLast) { // `barFee` % of increase in liquidity. uint256 _barFee = barFee; uint256 numerator = _totalSupply * (computed - _kLast) * _barFee; uint256 denominator = (MAX_FEE - _barFee) * computed + _barFee * _kLast; uint256 liquidity = numerator / denominator; if (liquidity != 0) { _mint(barFeeTo, liquidity); _totalSupply += liquidity; } } } } /// @dev This fee is charged to cover for `swapFee` when users add unbalanced liquidity. function _nonOptimalMintFee( uint256 _amount0, uint256 _amount1, uint256 _reserve0, uint256 _reserve1 ) internal view returns (uint256 token0Fee, uint256 token1Fee) { if (_reserve0 == 0 || _reserve1 == 0) return (0, 0); uint256 amount1Optimal = (_amount0 * _reserve1) / _reserve0; if (amount1Optimal <= _amount1) { token1Fee = (swapFee * (_amount1 - amount1Optimal)) / (2 * MAX_FEE); } else { uint256 amount0Optimal = (_amount1 * _reserve0) / _reserve1; token0Fee = (swapFee * (_amount0 - amount0Optimal)) / (2 * MAX_FEE); } } function _k(uint256 x, uint256 y) internal pure returns (uint256) { uint256 _a = (x * y) / 1e12; uint256 _b = ((x * x) / 1e12 + (y * y) / 1e12); return ((_a * _b) / 1e12); // x3y+y3x >= k } function _f(uint256 x0, uint256 y) internal pure returns (uint256) { return (x0 * ((((y * y) / 1e12) * y) / 1e12)) / 1e12 + (((((x0 * x0) / 1e12) * x0) / 1e12) * y) / 1e12; } function _d(uint256 x0, uint256 y) internal pure returns (uint256) { return (3 * x0 * ((y * y) / 1e12)) / 1e12 + ((((x0 * x0) / 1e12) * x0) / 1e12); } function _get_y( uint256 x0, uint256 xy, uint256 y ) internal pure returns (uint256) { for (uint256 i = 0; i < 255; i++) { uint256 y_prev = y; uint256 k = _f(x0, y); if (k < xy) { uint256 dy = ((xy - k) * 1e12) / _d(x0, y); y = y + dy; } else { uint256 dy = ((k - xy) * 1e12) / _d(x0, y); y = y - dy; } if (y > y_prev) { if (y - y_prev <= 1) { return y; } } else { if (y_prev - y <= 1) { return y; } } } return y; } function _getAmountOut( uint256 amountIn, uint256 _reserve0, uint256 _reserve1, bool token0In ) internal view returns (uint256 dy) { unchecked { uint256 adjustedReserve0 = (_reserve0 * 1e12) / decimals0; uint256 adjustedReserve1 = (_reserve1 * 1e12) / decimals1; uint256 feeDeductedAmountIn = amountIn - (amountIn * swapFee) / MAX_FEE; uint256 xy = _k(adjustedReserve0, adjustedReserve1); if (token0In) { uint256 x0 = adjustedReserve0 + ((feeDeductedAmountIn * 1e12) / decimals0); uint256 y = _get_y(x0, xy, adjustedReserve1); dy = adjustedReserve1 - y; dy = (dy * decimals1) / 1e12; } else { uint256 x0 = adjustedReserve1 + ((feeDeductedAmountIn * 1e12) / decimals1); uint256 y = _get_y(x0, xy, adjustedReserve0); dy = adjustedReserve0 - y; dy = (dy * decimals0) / 1e12; } } } function getAmountOut(bytes calldata data) public view override returns (uint256 finalAmountOut) { (address tokenIn, uint256 amountIn) = abi.decode(data, (address, uint256)); (uint256 _reserve0, uint256 _reserve1) = _getReserves(); amountIn = bento.toAmount(tokenIn, amountIn, false); if (tokenIn == token0) { finalAmountOut = bento.toShare(token1, _getAmountOut(amountIn, _reserve0, _reserve1, true), false); } else { if (tokenIn != token1) revert InvalidInputToken(); finalAmountOut = bento.toShare(token0, _getAmountOut(amountIn, _reserve0, _reserve1, false), false); } } function _transfer( address token, uint256 amount, address to, bool unwrapBento ) internal { if (unwrapBento) { bento.withdraw(token, address(this), to, amount, 0); } else { uint256 shares = bento.toShare(token, amount, false); bento.transfer(token, address(this), to, shares); } } function getAssets() public view returns (address[] memory assets) { assets = new address[](2); assets[0] = token0; assets[1] = token1; } function skim() public nonReentrant { address _token0 = token0; address _token1 = token1; address receiver = masterDeployer.owner(); IERC20(_token0).safeTransfer(receiver, IERC20(_token0).balanceOf(address(this))); IERC20(_token1).safeTransfer(receiver, IERC20(_token1).balanceOf(address(this))); } function _getReserves() internal view returns (uint256 _reserve0, uint256 _reserve1) { (_reserve0, _reserve1) = (reserve0, reserve1); } function getReserves() public view returns (uint256 _reserve0, uint256 _reserve1) { return _getReserves(); } function getNativeReserves() public view returns (uint256 _nativeReserve0, uint256 _nativeReserve1) { return _getReserves(); } function flashSwap(bytes calldata) external pure override returns (uint256) { revert(); } function getAmountIn(bytes calldata) external pure override returns (uint256) { revert(); } }
// 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 //////////////////////////////////////////////////////////////*/ bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); 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 { bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, 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: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Gas optimized reentrancy protection for smart contracts. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol) abstract contract ReentrancyGuard { uint256 private reentrancyStatus = 1; modifier nonReentrant() { require(reentrancyStatus == 1, "REENTRANCY"); reentrancyStatus = 2; _; reentrancyStatus = 1; } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.0; import "../libraries/RebaseLibrary.sol"; /// @notice Minimal BentoBox vault interface. /// @dev `token` is aliased as `address` from `IERC20` for simplicity. interface IBentoBoxMinimal { /// @notice Balance per ERC-20 token per account in shares. function balanceOf(address, address) external view returns (uint256); /// @dev Helper function to represent an `amount` of `token` in shares. /// @param token The ERC-20 token. /// @param amount The `token` amount. /// @param roundUp If the result `share` should be rounded up. /// @return share The token amount represented in shares. function toShare( address token, uint256 amount, bool roundUp ) external view returns (uint256 share); /// @dev Helper function to represent shares back into the `token` amount. /// @param token The ERC-20 token. /// @param share The amount of shares. /// @param roundUp If the result should be rounded up. /// @return amount The share amount back into native representation. function toAmount( address token, uint256 share, bool roundUp ) external view returns (uint256 amount); /// @notice Registers this contract so that users can approve it for BentoBox. function registerProtocol() external; /// @notice Deposit an amount of `token` represented in either `amount` or `share`. /// @param token The ERC-20 token to deposit. /// @param from which account to pull the tokens. /// @param to which account to push the tokens. /// @param amount Token amount in native representation to deposit. /// @param share Token amount represented in shares to deposit. Takes precedence over `amount`. /// @return amountOut The amount deposited. /// @return shareOut The deposited amount represented in shares. function deposit( address token, address from, address to, uint256 amount, uint256 share ) external payable returns (uint256 amountOut, uint256 shareOut); /// @notice Withdraws an amount of `token` from a user account. /// @param token_ The ERC-20 token to withdraw. /// @param from which user to pull the tokens. /// @param to which user to push the tokens. /// @param amount of tokens. Either one of `amount` or `share` needs to be supplied. /// @param share Like above, but `share` takes precedence over `amount`. function withdraw( address token_, address from, address to, uint256 amount, uint256 share ) external returns (uint256 amountOut, uint256 shareOut); /// @notice Transfer shares from a user account to another one. /// @param token The ERC-20 token to transfer. /// @param from which user to pull the tokens. /// @param to which user to push the tokens. /// @param share The amount of `token` in shares. function transfer( address token, address from, address to, uint256 share ) external; /// @dev Reads the Rebase `totals`from storage for a given token function totals(address token) external view returns (Rebase memory total); /// @dev Approves users' BentoBox assets to a "master" contract. function setMasterContractApproval( address user, address masterContract, bool approved, uint8 v, bytes32 r, bytes32 s ) external; function harvest( address token, bool balance, uint256 maxChangeAmount ) external; }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.0; import "./IMasterDeployer.sol"; /// @notice Trident pool deployer interface. interface IMasterDeployerV2 is IMasterDeployer { function barFee() external view returns (uint256); function barFeeTo() external view returns (address); function bento() external view returns (address); function migrator() external view returns (address); function pools(address pool) external view returns (bool); function deployPool(address factory, bytes calldata deployData) external returns (address); function owner() external returns (address); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.5.0; pragma experimental ABIEncoderV2; /// @notice Trident pool interface. interface IPool { /// @notice Executes a swap from one token to another. /// @dev The input tokens must've already been sent to the pool. /// @param data ABI-encoded params that the pool requires. /// @return finalAmountOut The amount of output tokens that were sent to the user. function swap(bytes calldata data) external returns (uint256 finalAmountOut); /// @notice Executes a swap from one token to another with a callback. /// @dev This function allows borrowing the output tokens and sending the input tokens in the callback. /// @param data ABI-encoded params that the pool requires. /// @return finalAmountOut The amount of output tokens that were sent to the user. function flashSwap(bytes calldata data) external returns (uint256 finalAmountOut); /// @notice Mints liquidity tokens. /// @param data ABI-encoded params that the pool requires. /// @return liquidity The amount of liquidity tokens that were minted for the user. function mint(bytes calldata data) external returns (uint256 liquidity); /// @notice Burns liquidity tokens. /// @dev The input LP tokens must've already been sent to the pool. /// @param data ABI-encoded params that the pool requires. /// @return withdrawnAmounts The amount of various output tokens that were sent to the user. function burn(bytes calldata data) external returns (TokenAmount[] memory withdrawnAmounts); /// @notice Burns liquidity tokens for a single output token. /// @dev The input LP tokens must've already been sent to the pool. /// @param data ABI-encoded params that the pool requires. /// @return amountOut The amount of output tokens that were sent to the user. function burnSingle(bytes calldata data) external returns (uint256 amountOut); /// @return A unique identifier for the pool type. function poolIdentifier() external pure returns (bytes32); /// @return An array of tokens supported by the pool. function getAssets() external view returns (address[] memory); /// @notice Simulates a trade and returns the expected output. /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library. /// @param data ABI-encoded params that the pool requires. /// @return finalAmountOut The amount of output tokens that will be sent to the user if the trade is executed. function getAmountOut(bytes calldata data) external view returns (uint256 finalAmountOut); /// @notice Simulates a trade and returns the expected output. /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library. /// @param data ABI-encoded params that the pool requires. /// @return finalAmountIn The amount of input tokens that are required from the user if the trade is executed. function getAmountIn(bytes calldata data) external view returns (uint256 finalAmountIn); /// @dev This event must be emitted on all swaps. event Swap(address indexed recipient, address indexed tokenIn, address indexed tokenOut, uint256 amountIn, uint256 amountOut); /// @dev This struct frames output tokens for burns. struct TokenAmount { address token; uint256 amount; } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.0; import "./IMasterDeployerV2.sol"; interface IStablePoolFactory { function getDeployData() external view returns (bytes memory, IMasterDeployerV2); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.0; /// @notice Trident sqrt helper library. library TridentMath { /// @dev Modified from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol) function sqrt(uint256 x) internal pure returns (uint256 z) { assembly { // This segment is to get a reasonable initial estimate for the Babylonian method. // If the initial estimate is bad, the number of correct bits increases ~linearly // each iteration instead of ~quadratically. // The idea is to get z*z*y within a small factor of x. // More iterations here gets y in a tighter range. Currently, we will have // y in [256, 256*2^16). We ensure y>= 256 so that the relative difference // between y and y+1 is small. If x < 256 this is not possible, but those cases // are easy enough to verify exhaustively. z := 181 // The 'correct' value is 1, but this saves a multiply later let y := x // Note that we check y>= 2^(k + 8) but shift right by k bits each branch, // this is to ensure that if x >= 256, then y >= 256. if iszero(lt(y, 0x10000000000000000000000000000000000)) { y := shr(128, y) z := shl(64, z) } if iszero(lt(y, 0x1000000000000000000)) { y := shr(64, y) z := shl(32, z) } if iszero(lt(y, 0x10000000000)) { y := shr(32, y) z := shl(16, z) } if iszero(lt(y, 0x1000000)) { y := shr(16, y) z := shl(8, z) } // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), // and either y >= 256, or x < 256. // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) // is in the range (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s=1 // and when s = 256 or 1/256. Since y is in [256, 256*2^16), let a = y/65536, so // that a is in [1/256, 256). Then we can estimate sqrt(y) as // sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18 // There is no overflow risk here since y < 2^136 after the first branch above. z := shr(18, mul(z, add(y, 65536))) // A multiply is saved from the initial z := 181 // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. // Possibly with a quadratic/cubic polynomial above we could get 4-6. 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))) // See https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division. // If x+1 is a perfect square, the Babylonian method cycles between // floor(sqrt(x)) and ceil(sqrt(x)). This check ensures we return floor. // Since this case is rare, we choose to save gas on the assignment and // repeat division in the rare case. // If you don't care whether floor or ceil is returned, you can skip this. if lt(div(x, z), z) { z := div(x, z) } } } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8; struct Rebase { uint128 elastic; uint128 base; } /// @notice A rebasing library library RebaseLibrary { /// @notice Calculates the base value in relationship to `elastic` and `total`. function toBase(Rebase memory total, uint256 elastic) internal pure returns (uint256 base) { if (total.elastic == 0) { base = elastic; } else { base = (elastic * total.base) / total.elastic; } } /// @notice Calculates the elastic value in relationship to `base` and `total`. function toElastic(Rebase memory total, uint256 base) internal pure returns (uint256 elastic) { if (total.base == 0) { elastic = base; } else { elastic = (base * total.elastic) / total.base; } } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.0; /// @notice Trident pool deployer interface. interface IMasterDeployer { function barFee() external view returns (uint256); function barFeeTo() external view returns (address); function bento() external view returns (address); function migrator() external view returns (address); function pools(address pool) external view returns (bool); function deployPool(address factory, bytes calldata deployData) external returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "optimizer": { "enabled": true, "runs": 999999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"IdenticalAddress","type":"error"},{"inputs":[],"name":"InsufficientLiquidityMinted","type":"error"},{"inputs":[],"name":"InvalidAmounts","type":"error"},{"inputs":[],"name":"InvalidInputToken","type":"error"},{"inputs":[],"name":"InvalidOutputToken","type":"error"},{"inputs":[],"name":"InvalidSwapFee","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reserve0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reserve1","type":"uint256"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"barFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"barFeeTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bento","outputs":[{"internalType":"contract IBentoBoxMinimal","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"burn","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPool.TokenAmount[]","name":"withdrawnAmounts","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"burnSingle","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"flashSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"finalAmountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAssets","outputs":[{"internalType":"address[]","name":"assets","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNativeReserves","outputs":[{"internalType":"uint256","name":"_nativeReserve0","type":"uint256"},{"internalType":"uint256","name":"_nativeReserve1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint256","name":"_reserve0","type":"uint256"},{"internalType":"uint256","name":"_reserve1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"masterDeployer","outputs":[{"internalType":"contract IMasterDeployerV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"poolIdentifier","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"skim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"swap","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[],"name":"updateBarParameters","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101e060405260016006553480156200001757600080fd5b50604080518082018252601581527f537573686920537461626c65204c5020546f6b656e0000000000000000000000602080830191825283518085019094526004845263053534c560e41b9084015281519192916012916200007d9160009190620004f6565b50815162000093906001906020850190620004f6565b5060ff81166080524660a052620000a96200045a565b60c08181525050505050600080336001600160a01b031663d039f6226040518163ffffffff1660e01b8152600401600060405180830381865afa158015620000f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200011f9190810190620005dd565b915091506000806000848060200190518101906200013e9190620006ce565b919450925090506001600160a01b0383166200016d5760405163d92e233d60e01b815260040160405180910390fd5b816001600160a01b0316836001600160a01b03161415620001a15760405163065af08d60e01b815260040160405180910390fd5b612710811115620001c55760405163da7459b760e01b815260040160405180910390fd5b6001600160a01b038084166101608190529083166101805260e0829052612710829003610100526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa15801562000228573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200024e919062000716565b6200025b90600a62000857565b6101a08181525050816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002c8919062000716565b620002d590600a62000857565b6101c08181525050836001600160a01b031663c14ad8026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200031c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000342919062000868565b600781905550836001600160a01b0316630c0a0cd26040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000387573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003ad919062000882565b600860006101000a8154816001600160a01b0302191690836001600160a01b03160217905550836001600160a01b0316634da318276040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000412573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000438919062000882565b6001600160a01b03908116610120529390931661014052506200098392505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516200048e9190620008df565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b8280546200050490620008a2565b90600052602060002090601f01602090048101928262000528576000855562000573565b82601f106200054357805160ff191683800117855562000573565b8280016001018555821562000573579182015b828111156200057357825182559160200191906001019062000556565b506200058192915062000585565b5090565b5b8082111562000581576000815560010162000586565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114620005c857600080fd5b50565b8051620005d881620005b2565b919050565b60008060408385031215620005f157600080fd5b82516001600160401b03808211156200060957600080fd5b818501915085601f8301126200061e57600080fd5b8151818111156200063357620006336200059c565b604051601f8201601f19908116603f011681019083821181831017156200065e576200065e6200059c565b816040528281526020935088848487010111156200067b57600080fd5b600091505b828210156200069f578482018401518183018501529083019062000680565b82821115620006b15760008484830101525b9550620006c3915050858201620005cb565b925050509250929050565b600080600060608486031215620006e457600080fd5b8351620006f181620005b2565b60208501519093506200070481620005b2565b80925050604084015190509250925092565b6000602082840312156200072957600080fd5b815160ff811681146200073b57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600181815b80851115620007995781600019048211156200077d576200077d62000742565b808516156200078b57918102915b93841c93908002906200075d565b509250929050565b600082620007b25750600162000851565b81620007c15750600062000851565b8160018114620007da5760028114620007e55762000805565b600191505062000851565b60ff841115620007f957620007f962000742565b50506001821b62000851565b5060208310610133831016604e8410600b84101617156200082a575081810a62000851565b62000836838362000758565b80600019048211156200084d576200084d62000742565b0290505b92915050565b60006200073b60ff841683620007a1565b6000602082840312156200087b57600080fd5b5051919050565b6000602082840312156200089557600080fd5b81516200073b81620005b2565b600181811c90821680620008b757607f821691505b60208210811415620008d957634e487b7160e01b600052602260045260246000fd5b50919050565b600080835481600182811c915080831680620008fc57607f831692505b60208084108214156200091d57634e487b7160e01b86526022600452602486fd5b818015620009345760018114620009465762000975565b60ff1986168952848901965062000975565b60008a81526020902060005b868110156200096d5781548b82015290850190830162000952565b505084890196505b509498975050505050505050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c051613e6262000b73600039600081816104fc0152818161288201528181612d2e01528181612df70152612e260152600081816104ad0152818161284701528181612cf301528181612da60152612e770152600081816105b3015281816107e401528181610c7001528181610d5401528181610f8e01528181610fc3015281816111bc0152818161162a015281816116f801528181611a2901528181611a92015281816122e701528181612a840152612c34015260008181610326015281816107bf01528181610c4401528181610ceb01528181610f350152818161104d0152818161114e0152818161159a015281816117b901528181611ac701528181611b640152818161216a015281816129a90152612b5f01526000818161058c0152818161080901528181611f320152611fc70152600081816103fb01528181611529015281816115ee0152818161177d0152818161219e01528181612319015281816125f1015281816126ba01528181612784015281816129dc01528181612ab501528181612b8d0152612c620152600050506000818161042201528181612d6a01528181612f040152612f6f01526000610e6f01526000610e3a015260006103ba0152613e626000f3fe608060405234801561001057600080fd5b506004361061025c5760003560e01c806367e4ac2c11610145578063a8f1f52e116100bd578063cf58879a1161008c578063d505accf11610071578063d505accf146105d5578063dd62ed3e146105e8578063f1c49a391461061357600080fd5b8063cf58879a14610587578063d21220a7146105ae57600080fd5b8063a8f1f52e14610545578063a9059cbb14610558578063af8c09bf1461056b578063c14ad8021461057e57600080fd5b80637bdd6b441161011457806395d89b41116100f957806395d89b41146104ef578063a28af8a4146104f7578063a69840a81461051e57600080fd5b80637bdd6b44146104a85780637ecebe00146104cf57600080fd5b806367e4ac2c1461045757806370a082311461046c5780637464fc3d1461048c5780637ba0e2e71461049557600080fd5b80632a07b6c7116101d8578063499a3c50116101a757806354cf2aeb1161018c57806354cf2aeb1461041d578063627dd56a1461044457806365dfc7671461029c57600080fd5b8063499a3c50146102615780634da31827146103f657600080fd5b80632a07b6c71461036e57806330adf81f1461038e578063313ce567146103b55780633644e515146103ee57600080fd5b80630c0a0cd21161022f57806318160ddd1161021457806318160ddd146103485780631dd19cb41461035157806323b872dd1461035b57600080fd5b80630c0a0cd2146102dc5780630dfe16811461032157600080fd5b8063053da1c81461026157806306fdde03146102875780630902f1ac1461029c578063095ea7b3146102b9575b600080fd5b61027461026f3660046136cf565b61061b565b6040519081526020015b60405180910390f35b61028f610622565b60405161027e919061376d565b6102a46106b0565b6040805192835260208301919091520161027e565b6102cc6102c73660046137e3565b6106c8565b604051901515815260200161027e565b6008546102fc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161027e565b6102fc7f000000000000000000000000000000000000000000000000000000000000000081565b61027460025481565b610359610742565b005b6102cc61036936600461380f565b610a09565b61038161037c3660046136cf565b610b4f565b60405161027e9190613850565b6102747f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6103dc7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161027e565b610274610e36565b6102fc7f000000000000000000000000000000000000000000000000000000000000000081565b6102747f000000000000000000000000000000000000000000000000000000000000000081565b6102746104523660046136cf565b610e91565b61045f61112c565b60405161027e91906138b5565b61027461047a36600461390f565b60036020526000908152604090205481565b61027460095481565b6102746104a33660046136cf565b61122b565b6102747f000000000000000000000000000000000000000000000000000000000000000081565b6102746104dd36600461390f565b60056020526000908152604090205481565b61028f61149f565b6102747f000000000000000000000000000000000000000000000000000000000000000081565b6102747f54726964656e743a537461626c65506f6f6c000000000000000000000000000081565b6102746105533660046136cf565b6114ac565b6102cc6105663660046137e3565b61188b565b6102746105793660046136cf565b611910565b61027460075481565b6102fc7f000000000000000000000000000000000000000000000000000000000000000081565b6102fc7f000000000000000000000000000000000000000000000000000000000000000081565b6103596105e336600461392c565b611c04565b6102746105f63660046139a3565b600460209081526000928352604080842090915290825290205481565b610359611f30565b6000806000fd5b6000805461062f906139dc565b80601f016020809104026020016040519081016040528092919081815260200182805461065b906139dc565b80156106a85780601f1061067d576101008083540402835291602001916106a8565b820191906000526020600020905b81548152906001019060200180831161068b57829003601f168201915b505050505081565b6000806106c0600a54600b549091565b915091509091565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906107309086815260200190565b60405180910390a35060015b92915050565b6006546001146107b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600260068190555060007f0000000000000000000000000000000000000000000000000000000000000000905060007f0000000000000000000000000000000000000000000000000000000000000000905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610874573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108989190613a30565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915061094d90829073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa15801561090b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092f9190613a4d565b73ffffffffffffffffffffffffffffffffffffffff8616919061209b565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526109ff90829073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156109bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e19190613a4d565b73ffffffffffffffffffffffffffffffffffffffff8516919061209b565b5050600160065550565b73ffffffffffffffffffffffffffffffffffffffff831660009081526004602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610a9d57610a6b8382613a95565b73ffffffffffffffffffffffffffffffffffffffff861660009081526004602090815260408083203384529091529020555b73ffffffffffffffffffffffffffffffffffffffff851660009081526003602052604081208054859290610ad2908490613a95565b909155505073ffffffffffffffffffffffffffffffffffffffff808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610b3a9087815260200190565b60405180910390a360019150505b9392505050565b6060600654600114610bbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016107aa565b6002600655600080610bd184860186613aba565b91509150600080610be061212d565b30600090815260036020526040812054929450909250610c00848461242b565b509050600081610c108685613ae8565b610c1a9190613b54565b9050600082610c298686613ae8565b610c339190613b54565b9050610c3f30856124f4565b610c6b7f0000000000000000000000000000000000000000000000000000000000000000838a8a61258a565b610c977f0000000000000000000000000000000000000000000000000000000000000000828a8a61258a565b610c9f6127ea565b6040805160028082526060820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081610cb557905050985060405180604001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020018381525089600081518110610d3c57610d3c613b8f565b602002602001018190525060405180604001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020018281525089600181518110610da557610da5613b8f565b6020908102919091010152610dcc610dbd8388613a95565b610dc78388613a95565b612842565b600955604080518381526020810183905273ffffffffffffffffffffffffffffffffffffffff8a169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a3505060016006555094979650505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610e6c57610e676128cc565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b6000600654600114610eff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016107aa565b600260065560008080610f1485870187613bbe565b925092509250600080600080610f28612966565b93509350935093506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff161415610fc15750508382037f0000000000000000000000000000000000000000000000000000000000000000610fba8287876001612cee565b995061107c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614611046576040517f2df9739b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50508281037f00000000000000000000000000000000000000000000000000000000000000006110798287876000612cee565b99505b611088818b8a8a61258a565b6110906127ea565b8073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fcd3829a3813dc3cdd188fd3d01dcf3268c16be2fdd2dd21d0665418816e46062858e60405161110f929190918252602082015260400190565b60405180910390a450506001600655509598975050505050505050565b60408051600280825260608083018452926020830190803683370190505090507f00000000000000000000000000000000000000000000000000000000000000008160008151811061118057611180613b8f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250507f0000000000000000000000000000000000000000000000000000000000000000816001815181106111ee576111ee613b8f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505090565b6000600654600114611299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016107aa565b600260065560006112ac8385018561390f565b90506000806112be600a54600b549091565b915091506000806112cd61212d565b9150915060006112dd8383612842565b905060006112eb8685613a95565b905060006112f98685613a95565b905060008061130a84848b8b612ea9565b90925090506113296dffffffffffffffffffffffffffff83168a613c09565b98506113456dffffffffffffffffffffffffffff821689613c09565b97506000806113548b8b61242b565b9150915081600014156113c35785158061136c575084155b156113a3576040517fd856fc5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113af6103e888613a95565b9c506113be60006103e8612fac565b6113e6565b80826113cf828a613a95565b6113d99190613ae8565b6113e39190613b54565b9c505b8c61141d576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114278c8e612fac565b61142f6127ea565b6009879055604080518781526020810187905273ffffffffffffffffffffffffffffffffffffffff8e169133917fdbba30eb0402b389513e87f51f4db2db80bed454384ec6925a24097c3548a02a910160405180910390a35050600160065550989b9a5050505050505050505050565b6001805461062f906139dc565b600080806114bc848601866137e3565b915091506000806114d0600a54600b549091565b6040517f5662311800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260248201879052600060448301529294509092507f000000000000000000000000000000000000000000000000000000000000000090911690635662311890606401602060405180830381865afa158015611572573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115969190613a4d565b92507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156116f6577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663da5139ca7f00000000000000000000000000000000000000000000000000000000000000006116568686866001612cee565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482015260006044820152606401602060405180830381865afa1580156116cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ef9190613a4d565b9450611881565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461177b576040517f2df9739b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663da5139ca7f00000000000000000000000000000000000000000000000000000000000000006117e58686866000612cee565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482015260006044820152606401602060405180830381865afa15801561185a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187e9190613a4d565b94505b5050505092915050565b336000908152600360205260408120805483919083906118ac908490613a95565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906107309086815260200190565b600060065460011461197e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016107aa565b60026006556000808061199385870187613bbe565b9250925092506000806119a9600a54600b549091565b915091506000806119b861212d565b306000908152600360205260408120549294509092506119d8848461242b565b5090506000816119e88685613ae8565b6119f29190613b54565b9050600082611a018686613ae8565b611a0b9190613b54565b9050611a1a610dbd8388613a95565b600955611a2730856124f4565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff161415611ac557611a8c82838a03838a036001612cee565b01611ab97f0000000000000000000000000000000000000000000000000000000000000000828c8c61258a565b809b5060009150611b92565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff1614611b4a576040517f0620202000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b5b81838a03838a036000612cee565b82019150611b8b7f0000000000000000000000000000000000000000000000000000000000000000838c8c61258a565b5099508960005b611b9a6127ea565b604080518381526020810183905273ffffffffffffffffffffffffffffffffffffffff8c169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a35050600160065550979a9950505050505050505050565b42841015611c6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016107aa565b6000611c78610e36565b73ffffffffffffffffffffffffffffffffffffffff89811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938c166060840152608083018b905260a083019390935260c08083018a90528151808403909101815260e0830190915280519201919091207f190100000000000000000000000000000000000000000000000000000000000061010083015261010282019290925261012281019190915261014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015611dd7573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590611e5257508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611eb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f494e56414c49445f5349474e455200000000000000000000000000000000000060448201526064016107aa565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526004602090815260408083208b8516808552908352928190208a905551898152919350918a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c14ad8026040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fbf9190613a4d565b6007819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630c0a0cd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015612030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120549190613a30565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261212890849061301d565b505050565b6040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000818116600484015230602484015260009283927f00000000000000000000000000000000000000000000000000000000000000001691635662311891839063f7888aec90604401602060405180830381865afa1580156121ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122119190613a4d565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482015260006044820152606401602060405180830381865afa158015612286573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122aa9190613a4d565b6040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081811660048401523060248401529294507f00000000000000000000000000000000000000000000000000000000000000001691635662311891839063f7888aec90604401602060405180830381865afa158015612368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238c9190613a4d565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482015260006044820152606401602060405180830381865afa158015612401573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124259190613a4d565b90509091565b60025460095460009080156124ec576124448585612842565b9150808211156124ec5760075460008161245e8486613a95565b6124689087613ae8565b6124729190613ae8565b905060006124808484613ae8565b8561248d85612710613a95565b6124979190613ae8565b6124a19190613c09565b905060006124af8284613b54565b905080156124e7576008546124da9073ffffffffffffffffffffffffffffffffffffffff1682612fac565b6124e48188613c09565b96505b505050505b509250929050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054839290612529908490613a95565b909155505060028054829003905560405181815260009073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b8015612664576040517f97da6d3000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152306024830152838116604483015260648201859052600060848301527f000000000000000000000000000000000000000000000000000000000000000016906397da6d309060a40160408051808303816000875af1158015612639573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061265d9190613c21565b50506127e4565b6040517fda5139ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260248201859052600060448301819052917f00000000000000000000000000000000000000000000000000000000000000009091169063da5139ca90606401602060405180830381865afa158015612703573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127279190613a4d565b6040517ff18d03cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301523060248301528581166044830152606482018390529192507f00000000000000000000000000000000000000000000000000000000000000009091169063f18d03cc90608401600060405180830381600087803b1580156127ca57600080fd5b505af11580156127de573d6000803e3d6000fd5b50505050505b50505050565b6000806127f561212d565b600a829055600b81905560408051838152602081018390529294509092507fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a15050565b6000807f00000000000000000000000000000000000000000000000000000000000000008464e8d4a51000028161287b5761287b613b25565b04905060007f00000000000000000000000000000000000000000000000000000000000000008464e8d4a5100002816128b6576128b6613b25565b0490506128c38282613129565b95945050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516128fe9190613c45565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b600a54600b546040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015260009182917f0000000000000000000000000000000000000000000000000000000000000000169063f7888aec90604401602060405180830381865afa158015612a23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a479190613a4d565b6040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301523060248301529193507f00000000000000000000000000000000000000000000000000000000000000009091169063f7888aec90604401602060405180830381865afa158015612afe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b229190613a4d565b6040517f4ffe34db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301529192506000917f00000000000000000000000000000000000000000000000000000000000000001690634ffe34db906024016040805180830381865afa158015612bd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf79190613d38565b6040517f4ffe34db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301529192506000917f00000000000000000000000000000000000000000000000000000000000000001690634ffe34db906024016040805180830381865afa158015612ca8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ccc9190613d38565b9050612cd88285613140565b9350612ce48184613140565b9250505090919293565b6000807f00000000000000000000000000000000000000000000000000000000000000008564e8d4a510000281612d2757612d27613b25565b04905060007f00000000000000000000000000000000000000000000000000000000000000008564e8d4a510000281612d6257612d62613b25565b0490506127107f000000000000000000000000000000000000000000000000000000000000000088020487036000612d9a8484613199565b90508515612e225760007f00000000000000000000000000000000000000000000000000000000000000008364e8d4a510000281612dda57612dda613b25565b04850190506000612dec828487613214565b64e8d4a510009086037f000000000000000000000000000000000000000000000000000000000000000002049650612e9d915050565b60007f00000000000000000000000000000000000000000000000000000000000000008364e8d4a510000281612e5a57612e5a613b25565b04840190506000612e6c828488613214565b64e8d4a510009087037f00000000000000000000000000000000000000000000000000000000000000000204965050505b50505050949350505050565b600080831580612eb7575082155b15612ec757506000905080612fa3565b600084612ed48589613ae8565b612ede9190613b54565b9050858111612f3957612ef46127106002613ae8565b612efe8288613a95565b612f28907f0000000000000000000000000000000000000000000000000000000000000000613ae8565b612f329190613b54565b9150612fa1565b600084612f468789613ae8565b612f509190613b54565b9050612f5f6127106002613ae8565b612f69828a613a95565b612f93907f0000000000000000000000000000000000000000000000000000000000000000613ae8565b612f9d9190613b54565b9350505b505b94509492505050565b8060026000828254612fbe9190613c09565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910161257e565b600061307f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661331d9092919063ffffffff16565b805190915015612128578080602001905181019061309d9190613dba565b612128576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107aa565b6000610b4861313b61313b8585613199565b613334565b600082602001516fffffffffffffffffffffffffffffffff166000141561316857508061073c565b602083015183516fffffffffffffffffffffffffffffffff9182169161318f911684613ae8565b610b489190613b54565b60008064e8d4a510006131ac8486613ae8565b6131b69190613b54565b9050600064e8d4a510006131ca8580613ae8565b6131d49190613b54565b64e8d4a510006131e48780613ae8565b6131ee9190613b54565b6131f89190613c09565b905064e8d4a5100061320a8284613ae8565b6128c39190613b54565b6000805b60ff8110156133145782600061322e87836133ed565b90508581101561327b5760006132448887613484565b61324e8389613a95565b61325d9064e8d4a51000613ae8565b6132679190613b54565b90506132738187613c09565b9550506132ba565b60006132878887613484565b6132918884613a95565b6132a09064e8d4a51000613ae8565b6132aa9190613b54565b90506132b68187613a95565b9550505b818511156132e35760016132ce8387613a95565b116132de57849350505050610b48565b6132ff565b60016132ef8684613a95565b116132ff57849350505050610b48565b5050808061330c90613dd7565b915050613218565b50909392505050565b606061332c84846000856134e6565b949350505050565b60b58171010000000000000000000000000000000000811061335b5760409190911b9060801c5b690100000000000000000081106133775760209190911b9060401c5b65010000000000811061338f5760109190911b9060201c5b630100000081106133a55760089190911b9060101c5b62010000010260121c80820401600190811c80830401811c80830401811c80830401811c80830401811c80830401811c80830401901c8082048111156133e85781045b919050565b600064e8d4a51000828185816134038280613ae8565b61340d9190613b54565b6134179190613ae8565b6134219190613b54565b61342b9190613ae8565b6134359190613b54565b64e8d4a510008084816134488280613ae8565b6134529190613b54565b61345c9190613ae8565b6134669190613b54565b6134709086613ae8565b61347a9190613b54565b610b489190613c09565b600064e8d4a5100083816134988280613ae8565b6134a29190613b54565b6134ac9190613ae8565b6134b69190613b54565b64e8d4a51000806134c78580613ae8565b6134d19190613b54565b6134dc866003613ae8565b6134709190613ae8565b606082471015613578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107aa565b73ffffffffffffffffffffffffffffffffffffffff85163b6135f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107aa565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161361f9190613e10565b60006040518083038185875af1925050503d806000811461365c576040519150601f19603f3d011682016040523d82523d6000602084013e613661565b606091505b509150915061367182828661367c565b979650505050505050565b6060831561368b575081610b48565b82511561369b5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107aa919061376d565b600080602083850312156136e257600080fd5b823567ffffffffffffffff808211156136fa57600080fd5b818501915085601f83011261370e57600080fd5b81358181111561371d57600080fd5b86602082850101111561372f57600080fd5b60209290920196919550909350505050565b60005b8381101561375c578181015183820152602001613744565b838111156127e45750506000910152565b602081526000825180602084015261378c816040850160208701613741565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff811681146137e057600080fd5b50565b600080604083850312156137f657600080fd5b8235613801816137be565b946020939093013593505050565b60008060006060848603121561382457600080fd5b833561382f816137be565b9250602084013561383f816137be565b929592945050506040919091013590565b602080825282518282018190526000919060409081850190868401855b828110156138a8578151805173ffffffffffffffffffffffffffffffffffffffff16855286015186850152928401929085019060010161386d565b5091979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561390357835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016138d1565b50909695505050505050565b60006020828403121561392157600080fd5b8135610b48816137be565b600080600080600080600060e0888a03121561394757600080fd5b8735613952816137be565b96506020880135613962816137be565b95506040880135945060608801359350608088013560ff8116811461398657600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156139b657600080fd5b82356139c1816137be565b915060208301356139d1816137be565b809150509250929050565b600181811c908216806139f057607f821691505b60208210811415613a2a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613a4257600080fd5b8151610b48816137be565b600060208284031215613a5f57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015613aa757613aa7613a66565b500390565b80151581146137e057600080fd5b60008060408385031215613acd57600080fd5b8235613ad8816137be565b915060208301356139d181613aac565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613b2057613b20613a66565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613b8a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080600060608486031215613bd357600080fd5b8335613bde816137be565b92506020840135613bee816137be565b91506040840135613bfe81613aac565b809150509250925092565b60008219821115613c1c57613c1c613a66565b500190565b60008060408385031215613c3457600080fd5b505080516020909101519092909150565b600080835481600182811c915080831680613c6157607f831692505b6020808410821415613c9a577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b818015613cae5760018114613cdd57613d0a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861689528489019650613d0a565b60008a81526020902060005b86811015613d025781548b820152908501908301613ce9565b505084890196505b509498975050505050505050565b80516fffffffffffffffffffffffffffffffff811681146133e857600080fd5b600060408284031215613d4a57600080fd5b6040516040810181811067ffffffffffffffff82111715613d94577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052613da083613d18565b8152613dae60208401613d18565b60208201529392505050565b600060208284031215613dcc57600080fd5b8151610b4881613aac565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613e0957613e09613a66565b5060010190565b60008251613e22818460208701613741565b919091019291505056fea26469706673582212205896af001c312e838d0681c524a1611a530550596c1663962913eec2cd7f22e664736f6c634300080a0033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061025c5760003560e01c806367e4ac2c11610145578063a8f1f52e116100bd578063cf58879a1161008c578063d505accf11610071578063d505accf146105d5578063dd62ed3e146105e8578063f1c49a391461061357600080fd5b8063cf58879a14610587578063d21220a7146105ae57600080fd5b8063a8f1f52e14610545578063a9059cbb14610558578063af8c09bf1461056b578063c14ad8021461057e57600080fd5b80637bdd6b441161011457806395d89b41116100f957806395d89b41146104ef578063a28af8a4146104f7578063a69840a81461051e57600080fd5b80637bdd6b44146104a85780637ecebe00146104cf57600080fd5b806367e4ac2c1461045757806370a082311461046c5780637464fc3d1461048c5780637ba0e2e71461049557600080fd5b80632a07b6c7116101d8578063499a3c50116101a757806354cf2aeb1161018c57806354cf2aeb1461041d578063627dd56a1461044457806365dfc7671461029c57600080fd5b8063499a3c50146102615780634da31827146103f657600080fd5b80632a07b6c71461036e57806330adf81f1461038e578063313ce567146103b55780633644e515146103ee57600080fd5b80630c0a0cd21161022f57806318160ddd1161021457806318160ddd146103485780631dd19cb41461035157806323b872dd1461035b57600080fd5b80630c0a0cd2146102dc5780630dfe16811461032157600080fd5b8063053da1c81461026157806306fdde03146102875780630902f1ac1461029c578063095ea7b3146102b9575b600080fd5b61027461026f3660046136cf565b61061b565b6040519081526020015b60405180910390f35b61028f610622565b60405161027e919061376d565b6102a46106b0565b6040805192835260208301919091520161027e565b6102cc6102c73660046137e3565b6106c8565b604051901515815260200161027e565b6008546102fc9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161027e565b6102fc7f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160781565b61027460025481565b610359610742565b005b6102cc61036936600461380f565b610a09565b61038161037c3660046136cf565b610b4f565b60405161027e9190613850565b6102747f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6103dc7f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff909116815260200161027e565b610274610e36565b6102fc7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c481565b6102747f000000000000000000000000000000000000000000000000000000000000000181565b6102746104523660046136cf565b610e91565b61045f61112c565b60405161027e91906138b5565b61027461047a36600461390f565b60036020526000908152604090205481565b61027460095481565b6102746104a33660046136cf565b61122b565b6102747f00000000000000000000000000000000000000000000000000000000000f424081565b6102746104dd36600461390f565b60056020526000908152604090205481565b61028f61149f565b6102747f00000000000000000000000000000000000000000000000000000000000f424081565b6102747f54726964656e743a537461626c65506f6f6c000000000000000000000000000081565b6102746105533660046136cf565b6114ac565b6102cc6105663660046137e3565b61188b565b6102746105793660046136cf565b611910565b61027460075481565b6102fc7f000000000000000000000000caabdd9cf4b61813d4a52f980d6bc1b713fe66f581565b6102fc7f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5881565b6103596105e336600461392c565b611c04565b6102746105f63660046139a3565b600460209081526000928352604080842090915290825290205481565b610359611f30565b6000806000fd5b6000805461062f906139dc565b80601f016020809104026020016040519081016040528092919081815260200182805461065b906139dc565b80156106a85780601f1061067d576101008083540402835291602001916106a8565b820191906000526020600020905b81548152906001019060200180831161068b57829003601f168201915b505050505081565b6000806106c0600a54600b549091565b915091509091565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906107309086815260200190565b60405180910390a35060015b92915050565b6006546001146107b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600260068190555060007f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607905060007f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58905060007f000000000000000000000000caabdd9cf4b61813d4a52f980d6bc1b713fe66f573ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610874573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108989190613a30565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290915061094d90829073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa15801561090b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092f9190613a4d565b73ffffffffffffffffffffffffffffffffffffffff8616919061209b565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526109ff90829073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa1580156109bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e19190613a4d565b73ffffffffffffffffffffffffffffffffffffffff8516919061209b565b5050600160065550565b73ffffffffffffffffffffffffffffffffffffffff831660009081526004602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610a9d57610a6b8382613a95565b73ffffffffffffffffffffffffffffffffffffffff861660009081526004602090815260408083203384529091529020555b73ffffffffffffffffffffffffffffffffffffffff851660009081526003602052604081208054859290610ad2908490613a95565b909155505073ffffffffffffffffffffffffffffffffffffffff808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610b3a9087815260200190565b60405180910390a360019150505b9392505050565b6060600654600114610bbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016107aa565b6002600655600080610bd184860186613aba565b91509150600080610be061212d565b30600090815260036020526040812054929450909250610c00848461242b565b509050600081610c108685613ae8565b610c1a9190613b54565b9050600082610c298686613ae8565b610c339190613b54565b9050610c3f30856124f4565b610c6b7f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607838a8a61258a565b610c977f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58828a8a61258a565b610c9f6127ea565b6040805160028082526060820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081610cb557905050985060405180604001604052807f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160773ffffffffffffffffffffffffffffffffffffffff1681526020018381525089600081518110610d3c57610d3c613b8f565b602002602001018190525060405180604001604052807f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5873ffffffffffffffffffffffffffffffffffffffff1681526020018281525089600181518110610da557610da5613b8f565b6020908102919091010152610dcc610dbd8388613a95565b610dc78388613a95565b612842565b600955604080518381526020810183905273ffffffffffffffffffffffffffffffffffffffff8a169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a3505060016006555094979650505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000a4614610e6c57610e676128cc565b905090565b507fbbe9b25e3de3142d7f9b2c43c0dceb86da06d81d16f136d35151b39f1f3aae2690565b6000600654600114610eff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016107aa565b600260065560008080610f1485870187613bbe565b925092509250600080600080610f28612966565b93509350935093506000807f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff161415610fc15750508382037f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58610fba8287876001612cee565b995061107c565b7f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5873ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614611046576040517f2df9739b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50508281037f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316076110798287876000612cee565b99505b611088818b8a8a61258a565b6110906127ea565b8073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fcd3829a3813dc3cdd188fd3d01dcf3268c16be2fdd2dd21d0665418816e46062858e60405161110f929190918252602082015260400190565b60405180910390a450506001600655509598975050505050505050565b60408051600280825260608083018452926020830190803683370190505090507f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316078160008151811061118057611180613b8f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250507f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58816001815181106111ee576111ee613b8f565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505090565b6000600654600114611299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016107aa565b600260065560006112ac8385018561390f565b90506000806112be600a54600b549091565b915091506000806112cd61212d565b9150915060006112dd8383612842565b905060006112eb8685613a95565b905060006112f98685613a95565b905060008061130a84848b8b612ea9565b90925090506113296dffffffffffffffffffffffffffff83168a613c09565b98506113456dffffffffffffffffffffffffffff821689613c09565b97506000806113548b8b61242b565b9150915081600014156113c35785158061136c575084155b156113a3576040517fd856fc5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113af6103e888613a95565b9c506113be60006103e8612fac565b6113e6565b80826113cf828a613a95565b6113d99190613ae8565b6113e39190613b54565b9c505b8c61141d576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114278c8e612fac565b61142f6127ea565b6009879055604080518781526020810187905273ffffffffffffffffffffffffffffffffffffffff8e169133917fdbba30eb0402b389513e87f51f4db2db80bed454384ec6925a24097c3548a02a910160405180910390a35050600160065550989b9a5050505050505050505050565b6001805461062f906139dc565b600080806114bc848601866137e3565b915091506000806114d0600a54600b549091565b6040517f5662311800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015260248201879052600060448301529294509092507f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c490911690635662311890606401602060405180830381865afa158015611572573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115969190613a4d565b92507f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156116f6577f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c473ffffffffffffffffffffffffffffffffffffffff1663da5139ca7f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e586116568686866001612cee565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482015260006044820152606401602060405180830381865afa1580156116cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ef9190613a4d565b9450611881565b7f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5873ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461177b576040517f2df9739b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c473ffffffffffffffffffffffffffffffffffffffff1663da5139ca7f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316076117e58686866000612cee565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482015260006044820152606401602060405180830381865afa15801561185a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187e9190613a4d565b94505b5050505092915050565b336000908152600360205260408120805483919083906118ac908490613a95565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906107309086815260200190565b600060065460011461197e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016107aa565b60026006556000808061199385870187613bbe565b9250925092506000806119a9600a54600b549091565b915091506000806119b861212d565b306000908152600360205260408120549294509092506119d8848461242b565b5090506000816119e88685613ae8565b6119f29190613b54565b9050600082611a018686613ae8565b611a0b9190613b54565b9050611a1a610dbd8388613a95565b600955611a2730856124f4565b7f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5873ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff161415611ac557611a8c82838a03838a036001612cee565b01611ab97f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58828c8c61258a565b809b5060009150611b92565b7f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160773ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff1614611b4a576040517f0620202000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b5b81838a03838a036000612cee565b82019150611b8b7f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607838c8c61258a565b5099508960005b611b9a6127ea565b604080518381526020810183905273ffffffffffffffffffffffffffffffffffffffff8c169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a35050600160065550979a9950505050505050505050565b42841015611c6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016107aa565b6000611c78610e36565b73ffffffffffffffffffffffffffffffffffffffff89811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938c166060840152608083018b905260a083019390935260c08083018a90528151808403909101815260e0830190915280519201919091207f190100000000000000000000000000000000000000000000000000000000000061010083015261010282019290925261012281019190915261014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015611dd7573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590611e5257508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611eb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f494e56414c49445f5349474e455200000000000000000000000000000000000060448201526064016107aa565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526004602090815260408083208b8516808552908352928190208a905551898152919350918a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b7f000000000000000000000000caabdd9cf4b61813d4a52f980d6bc1b713fe66f573ffffffffffffffffffffffffffffffffffffffff1663c14ad8026040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fbf9190613a4d565b6007819055507f000000000000000000000000caabdd9cf4b61813d4a52f980d6bc1b713fe66f573ffffffffffffffffffffffffffffffffffffffff16630c0a0cd26040518163ffffffff1660e01b8152600401602060405180830381865afa158015612030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120549190613a30565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261212890849061301d565b505050565b6040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607818116600484015230602484015260009283927f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c41691635662311891839063f7888aec90604401602060405180830381865afa1580156121ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122119190613a4d565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482015260006044820152606401602060405180830381865afa158015612286573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122aa9190613a4d565b6040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5881811660048401523060248401529294507f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c41691635662311891839063f7888aec90604401602060405180830381865afa158015612368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238c9190613a4d565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482015260006044820152606401602060405180830381865afa158015612401573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124259190613a4d565b90509091565b60025460095460009080156124ec576124448585612842565b9150808211156124ec5760075460008161245e8486613a95565b6124689087613ae8565b6124729190613ae8565b905060006124808484613ae8565b8561248d85612710613a95565b6124979190613ae8565b6124a19190613c09565b905060006124af8284613b54565b905080156124e7576008546124da9073ffffffffffffffffffffffffffffffffffffffff1682612fac565b6124e48188613c09565b96505b505050505b509250929050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054839290612529908490613a95565b909155505060028054829003905560405181815260009073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b8015612664576040517f97da6d3000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152306024830152838116604483015260648201859052600060848301527f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c416906397da6d309060a40160408051808303816000875af1158015612639573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061265d9190613c21565b50506127e4565b6040517fda5139ca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015260248201859052600060448301819052917f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c49091169063da5139ca90606401602060405180830381865afa158015612703573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127279190613a4d565b6040517ff18d03cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301523060248301528581166044830152606482018390529192507f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c49091169063f18d03cc90608401600060405180830381600087803b1580156127ca57600080fd5b505af11580156127de573d6000803e3d6000fd5b50505050505b50505050565b6000806127f561212d565b600a829055600b81905560408051838152602081018390529294509092507fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a15050565b6000807f00000000000000000000000000000000000000000000000000000000000f42408464e8d4a51000028161287b5761287b613b25565b04905060007f00000000000000000000000000000000000000000000000000000000000f42408464e8d4a5100002816128b6576128b6613b25565b0490506128c38282613129565b95945050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516128fe9190613c45565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b600a54600b546040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316078116600483015230602483015260009182917f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c4169063f7888aec90604401602060405180830381865afa158015612a23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a479190613a4d565b6040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58811660048301523060248301529193507f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c49091169063f7888aec90604401602060405180830381865afa158015612afe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b229190613a4d565b6040517f4ffe34db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607811660048301529192506000917f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c41690634ffe34db906024016040805180830381865afa158015612bd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf79190613d38565b6040517f4ffe34db00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58811660048301529192506000917f000000000000000000000000c35dadb65012ec5796536bd9864ed8773abc74c41690634ffe34db906024016040805180830381865afa158015612ca8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ccc9190613d38565b9050612cd88285613140565b9350612ce48184613140565b9250505090919293565b6000807f00000000000000000000000000000000000000000000000000000000000f42408564e8d4a510000281612d2757612d27613b25565b04905060007f00000000000000000000000000000000000000000000000000000000000f42408564e8d4a510000281612d6257612d62613b25565b0490506127107f000000000000000000000000000000000000000000000000000000000000000188020487036000612d9a8484613199565b90508515612e225760007f00000000000000000000000000000000000000000000000000000000000f42408364e8d4a510000281612dda57612dda613b25565b04850190506000612dec828487613214565b64e8d4a510009086037f00000000000000000000000000000000000000000000000000000000000f424002049650612e9d915050565b60007f00000000000000000000000000000000000000000000000000000000000f42408364e8d4a510000281612e5a57612e5a613b25565b04840190506000612e6c828488613214565b64e8d4a510009087037f00000000000000000000000000000000000000000000000000000000000f42400204965050505b50505050949350505050565b600080831580612eb7575082155b15612ec757506000905080612fa3565b600084612ed48589613ae8565b612ede9190613b54565b9050858111612f3957612ef46127106002613ae8565b612efe8288613a95565b612f28907f0000000000000000000000000000000000000000000000000000000000000001613ae8565b612f329190613b54565b9150612fa1565b600084612f468789613ae8565b612f509190613b54565b9050612f5f6127106002613ae8565b612f69828a613a95565b612f93907f0000000000000000000000000000000000000000000000000000000000000001613ae8565b612f9d9190613b54565b9350505b505b94509492505050565b8060026000828254612fbe9190613c09565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910161257e565b600061307f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661331d9092919063ffffffff16565b805190915015612128578080602001905181019061309d9190613dba565b612128576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107aa565b6000610b4861313b61313b8585613199565b613334565b600082602001516fffffffffffffffffffffffffffffffff166000141561316857508061073c565b602083015183516fffffffffffffffffffffffffffffffff9182169161318f911684613ae8565b610b489190613b54565b60008064e8d4a510006131ac8486613ae8565b6131b69190613b54565b9050600064e8d4a510006131ca8580613ae8565b6131d49190613b54565b64e8d4a510006131e48780613ae8565b6131ee9190613b54565b6131f89190613c09565b905064e8d4a5100061320a8284613ae8565b6128c39190613b54565b6000805b60ff8110156133145782600061322e87836133ed565b90508581101561327b5760006132448887613484565b61324e8389613a95565b61325d9064e8d4a51000613ae8565b6132679190613b54565b90506132738187613c09565b9550506132ba565b60006132878887613484565b6132918884613a95565b6132a09064e8d4a51000613ae8565b6132aa9190613b54565b90506132b68187613a95565b9550505b818511156132e35760016132ce8387613a95565b116132de57849350505050610b48565b6132ff565b60016132ef8684613a95565b116132ff57849350505050610b48565b5050808061330c90613dd7565b915050613218565b50909392505050565b606061332c84846000856134e6565b949350505050565b60b58171010000000000000000000000000000000000811061335b5760409190911b9060801c5b690100000000000000000081106133775760209190911b9060401c5b65010000000000811061338f5760109190911b9060201c5b630100000081106133a55760089190911b9060101c5b62010000010260121c80820401600190811c80830401811c80830401811c80830401811c80830401811c80830401811c80830401901c8082048111156133e85781045b919050565b600064e8d4a51000828185816134038280613ae8565b61340d9190613b54565b6134179190613ae8565b6134219190613b54565b61342b9190613ae8565b6134359190613b54565b64e8d4a510008084816134488280613ae8565b6134529190613b54565b61345c9190613ae8565b6134669190613b54565b6134709086613ae8565b61347a9190613b54565b610b489190613c09565b600064e8d4a5100083816134988280613ae8565b6134a29190613b54565b6134ac9190613ae8565b6134b69190613b54565b64e8d4a51000806134c78580613ae8565b6134d19190613b54565b6134dc866003613ae8565b6134709190613ae8565b606082471015613578576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107aa565b73ffffffffffffffffffffffffffffffffffffffff85163b6135f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107aa565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161361f9190613e10565b60006040518083038185875af1925050503d806000811461365c576040519150601f19603f3d011682016040523d82523d6000602084013e613661565b606091505b509150915061367182828661367c565b979650505050505050565b6060831561368b575081610b48565b82511561369b5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107aa919061376d565b600080602083850312156136e257600080fd5b823567ffffffffffffffff808211156136fa57600080fd5b818501915085601f83011261370e57600080fd5b81358181111561371d57600080fd5b86602082850101111561372f57600080fd5b60209290920196919550909350505050565b60005b8381101561375c578181015183820152602001613744565b838111156127e45750506000910152565b602081526000825180602084015261378c816040850160208701613741565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff811681146137e057600080fd5b50565b600080604083850312156137f657600080fd5b8235613801816137be565b946020939093013593505050565b60008060006060848603121561382457600080fd5b833561382f816137be565b9250602084013561383f816137be565b929592945050506040919091013590565b602080825282518282018190526000919060409081850190868401855b828110156138a8578151805173ffffffffffffffffffffffffffffffffffffffff16855286015186850152928401929085019060010161386d565b5091979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561390357835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016138d1565b50909695505050505050565b60006020828403121561392157600080fd5b8135610b48816137be565b600080600080600080600060e0888a03121561394757600080fd5b8735613952816137be565b96506020880135613962816137be565b95506040880135945060608801359350608088013560ff8116811461398657600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156139b657600080fd5b82356139c1816137be565b915060208301356139d1816137be565b809150509250929050565b600181811c908216806139f057607f821691505b60208210811415613a2a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613a4257600080fd5b8151610b48816137be565b600060208284031215613a5f57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015613aa757613aa7613a66565b500390565b80151581146137e057600080fd5b60008060408385031215613acd57600080fd5b8235613ad8816137be565b915060208301356139d181613aac565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613b2057613b20613a66565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613b8a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080600060608486031215613bd357600080fd5b8335613bde816137be565b92506020840135613bee816137be565b91506040840135613bfe81613aac565b809150509250925092565b60008219821115613c1c57613c1c613a66565b500190565b60008060408385031215613c3457600080fd5b505080516020909101519092909150565b600080835481600182811c915080831680613c6157607f831692505b6020808410821415613c9a577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b818015613cae5760018114613cdd57613d0a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861689528489019650613d0a565b60008a81526020902060005b86811015613d025781548b820152908501908301613ce9565b505084890196505b509498975050505050505050565b80516fffffffffffffffffffffffffffffffff811681146133e857600080fd5b600060408284031215613d4a57600080fd5b6040516040810181811067ffffffffffffffff82111715613d94577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052613da083613d18565b8152613dae60208401613d18565b60208201529392505050565b600060208284031215613dcc57600080fd5b8151610b4881613aac565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613e0957613e09613a66565b5060010190565b60008251613e22818460208701613741565b919091019291505056fea26469706673582212205896af001c312e838d0681c524a1611a530550596c1663962913eec2cd7f22e664736f6c634300080a0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.