Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
16975698 | 54 days ago | Contract Creation | 0 ETH | |||
12585319 | 209 days ago | Contract Creation | 0 ETH | |||
12512644 | 212 days ago | Contract Creation | 0 ETH | |||
6313620 | 424 days ago | Contract Creation | 0 ETH | |||
6166082 | 429 days ago | Contract Creation | 0 ETH | |||
5944972 | 437 days ago | Contract Creation | 0 ETH | |||
5618022 | 449 days ago | Contract Creation | 0 ETH | |||
1918998 | 530 days ago | Contract Creation | 0 ETH | |||
1641556 | 535 days ago | Contract Creation | 0 ETH | |||
1493771 | 538 days ago | Contract Creation | 0 ETH | |||
1365801 | 541 days ago | Contract Creation | 0 ETH | |||
1062715 | 546 days ago | Contract Creation | 0 ETH | |||
879903 | 550 days ago | Contract Creation | 0 ETH | |||
877035 | 550 days ago | Contract Creation | 0 ETH | |||
754762 | 554 days ago | Contract Creation | 0 ETH | |||
491108 | 565 days ago | Contract Creation | 0 ETH | |||
433648 | 567 days ago | Contract Creation | 0 ETH | |||
428772 | 567 days ago | Contract Creation | 0 ETH | |||
388616 | 569 days ago | Contract Creation | 0 ETH | |||
335884 | 572 days ago | Contract Creation | 0 ETH | |||
270206 | 577 days ago | Contract Creation | 0 ETH | |||
270179 | 577 days ago | Contract Creation | 0 ETH | |||
243891 | 579 days ago | Contract Creation | 0 ETH | |||
243433 | 579 days ago | Contract Creation | 0 ETH | |||
240216 | 579 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
AntfarmFactory
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; import "./AntfarmPair.sol"; import "./AntfarmAtfPair.sol"; import "../utils/AntfarmFactoryErrors.sol"; /// @title Antfarm Factory /// @notice The Factory is used to create new Pair contracts for each unique ERC20 token pair contract AntfarmFactory is IAntfarmFactory { uint16[8] public possibleFees = [10, 50, 100, 150, 250, 500, 750, 1000]; address[] public allPairs; address public antfarmToken; mapping(address => mapping(address => mapping(uint16 => address))) public getPair; mapping(address => mapping(address => uint16[8])) public feesForPair; constructor(address _antfarmToken) { require(_antfarmToken != address(0), "NULL_ATF_ADDRESS"); antfarmToken = _antfarmToken; } /// @notice Get list of fees for existing Antfarm Pair of a specific pair /// @param _token0 token0 from the pair /// @param _token1 token1 from the pair /// @return uint16 Fixed fees array function getFeesForPair(address _token0, address _token1) external view override returns (uint16[8] memory) { return feesForPair[_token0][_token1]; } /// @notice Get total number of Antfarm Pairs /// @return uint Number of created pairs function allPairsLength() public view returns (uint256) { return allPairs.length; } /// @notice Get Antfarm Pairs addresses /// @param startIndex Index of the first pair to query /// @param numOfPairs Number of pairs to be queried /// @return pairs Addresses of created pairs /// @return newIndex New index for chained calls function getPairs(uint256 startIndex, uint256 numOfPairs) external view returns (address[] memory pairs, uint256 newIndex) { if (numOfPairs > allPairsLength() - startIndex) { numOfPairs = allPairsLength() - startIndex; } pairs = new address[](numOfPairs); for (uint256 i; i < numOfPairs; ++i) { pairs[i] = allPairs[startIndex + i]; } newIndex = startIndex + numOfPairs; } /// @notice Get all possible fees /// @return uint16[8] List of possible fees function getPossibleFees() external view returns (uint16[8] memory) { return possibleFees; } /// @notice Create new Antfarm Pair /// @param tokenA token0 to be used for the new Antfarm Pair /// @param tokenB token1 to be used for the new Antfarm Pair /// @param fee Fee to be used in the new Antfarm Pair /// @return address The address of the deployed Antfarm Pair function createPair( address tokenA, address tokenB, uint16 fee ) external returns (address) { uint16 feeIndex = validateFee(fee); if (tokenA == tokenB) revert IdenticalAddresses(); address token0; address token1; if (tokenA == antfarmToken || tokenB == antfarmToken) { (token0, token1) = tokenA == antfarmToken ? (antfarmToken, tokenB) : (antfarmToken, tokenA); if (token1 == address(0)) revert ZeroAddress(); // antfarmToken can't be 0 but other could if (fee == 1000) revert ForbiddenFee(); } else { (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); if (token0 == address(0)) revert ZeroAddress(); } if (getPair[token0][token1][fee] != address(0)) revert PairExists(); address pair; bytes memory bytecode = token0 == antfarmToken ? type(AntfarmAtfPair).creationCode : type(AntfarmPair).creationCode; bytes32 salt = keccak256( abi.encodePacked(token0, token1, fee, antfarmToken) ); assembly { pair := create2(0, add(bytecode, 32), mload(bytecode), salt) } getPair[token0][token1][fee] = pair; getPair[token1][token0][fee] = pair; writeFee(token0, token1, feeIndex); allPairs.push(pair); token0 == antfarmToken ? IAntfarmAtfPair(pair).initialize(token0, token1, fee) : IAntfarmPair(pair).initialize(token0, token1, fee, antfarmToken); emit PairCreated(token0, token1, pair, fee, allPairs.length); return pair; } // updates the fee array for a pair with the fee amount in its index function writeFee( address token0, address token1, uint16 index ) internal { uint16[8] memory fees = feesForPair[token0][token1]; fees[index] = possibleFees[index]; feesForPair[token0][token1] = fees; feesForPair[token1][token0] = fees; } // check the fee provided is one of the available ones function validateFee(uint16 fee) internal view returns (uint16) { for (uint16 i; i < 8; ++i) { if (fee == possibleFees[i]) { return i; } } revert IncorrectFee(); } }
// 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 locked = 1; modifier nonReentrant() virtual { require(locked == 1, "REENTRANCY"); locked = 2; _; locked = 1; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.10; import "../interfaces/IERC20.sol"; import "../interfaces/IAntfarmFactory.sol"; import "../interfaces/IAntfarmAtfPair.sol"; import "../interfaces/IAntfarmOracle.sol"; import "../libraries/math.sol"; import "../libraries/UQ112x112.sol"; import "../libraries/TransferHelper.sol"; import "../utils/AntfarmPairErrors.sol"; import "@rari-capital/solmate/src/utils/ReentrancyGuard.sol"; /// @title Core contract for Antfarm Pairs with ATF token /// @notice Low-level contract to mint/burn/swap and claim contract AntfarmAtfPair is IAntfarmAtfPair, ReentrancyGuard, Math { using UQ112x112 for uint224; /// @inheritdoc IAntfarmPairState address public immutable factory; /// @inheritdoc IAntfarmPairState address public token0; /// @inheritdoc IAntfarmPairState address public token1; /// @inheritdoc IAntfarmPairState uint16 public fee; /// @inheritdoc IAntfarmPairState uint256 public totalSupply; /// @inheritdoc IAntfarmAtfPair uint256 public price1CumulativeLast; /// @inheritdoc IAntfarmPairState uint256 public antfarmTokenReserve; /// @inheritdoc IAntfarmAtfPair address public antfarmOracle; uint112 private reserve0; uint112 private reserve1; uint32 private blockTimestampLast; // DIVIDEND VARIABLES uint256 private totalDividendPoints; uint256 private constant POINT_MULTIPLIER = 1 ether; uint256 private constant MINIMUM_LIQUIDITY = 1000; struct Position { uint128 lp; uint256 dividend; uint256 lastDividendPoints; } mapping(address => mapping(uint256 => Position)) public positions; modifier updateDividend(address operator, uint256 positionId) { if (positions[operator][positionId].lp > 0) { uint256 owing = newDividends( operator, positionId, totalDividendPoints ); if (owing > 0) { positions[operator][positionId].dividend += owing; positions[operator][positionId] .lastDividendPoints = totalDividendPoints; } } else { positions[operator][positionId] .lastDividendPoints = totalDividendPoints; } _; } constructor() { factory = msg.sender; } function initialize( address _token0, address _token1, uint16 _fee ) external { if (msg.sender != factory) revert SenderNotFactory(); token0 = _token0; token1 = _token1; fee = _fee; } /// @inheritdoc IAntfarmPairActions function mint(address to, uint256 positionId) external override nonReentrant updateDividend(to, positionId) returns (uint256) { (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); uint256 balance0 = IERC20(token0).balanceOf(address(this)) - antfarmTokenReserve; uint256 balance1 = IERC20(token1).balanceOf(address(this)); uint256 amount0 = balance0 - _reserve0; uint256 amount1 = balance1 - _reserve1; uint256 liquidity; uint256 _totalSupply = totalSupply; if (_totalSupply == 0) { liquidity = Math.sqrt(amount0 * amount1) - MINIMUM_LIQUIDITY; totalSupply = MINIMUM_LIQUIDITY; } else { liquidity = Math.min( (amount0 * totalSupply) / _reserve0, (amount1 * totalSupply) / _reserve1 ); } if (liquidity == 0) revert InsufficientLiquidityMinted(); positions[to][positionId].lp += uint128(liquidity); totalSupply = totalSupply + liquidity; _update(balance0, balance1, _reserve0, _reserve1); if (_totalSupply == 0) { if (fee == 10) { setOracleInstance(); } } emit Mint(to, amount0, amount1); return liquidity; } /// @inheritdoc IAntfarmPairActions function burn( address to, uint256 positionId, uint256 liquidity ) external override nonReentrant updateDividend(msg.sender, positionId) returns (uint256, uint256) { (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings uint256 balance0 = IERC20(token0).balanceOf(address(this)) - antfarmTokenReserve; uint256 balance1 = IERC20(token1).balanceOf(address(this)); if (positions[msg.sender][positionId].lp < liquidity) { revert InsufficientLiquidity(); } positions[msg.sender][positionId].lp -= uint128(liquidity); if (liquidity == 0) revert InsufficientLiquidity(); uint256 _totalSupply = totalSupply; // gas savings uint256 amount0 = (liquidity * balance0) / _totalSupply; uint256 amount1 = (liquidity * balance1) / _totalSupply; totalSupply = totalSupply - liquidity; if (amount0 == 0 || amount1 == 0) revert InsufficientLiquidityBurned(); TransferHelper.safeTransfer(token0, to, amount0); TransferHelper.safeTransfer(token1, to, amount1); balance0 = IERC20(token0).balanceOf(address(this)) - antfarmTokenReserve; balance1 = IERC20(token1).balanceOf(address(this)); _update(balance0, balance1, _reserve0, _reserve1); emit Burn(msg.sender, amount0, amount1, to); return (amount0, amount1); } /// @inheritdoc IAntfarmPairActions function swap( uint256 amount0Out, uint256 amount1Out, address to ) external nonReentrant { if (amount0Out == 0 && amount1Out == 0) { revert InsufficientOutputAmount(); } (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings if (amount0Out >= _reserve0 || amount1Out >= _reserve1) { revert InsufficientLiquidity(); } uint256 balance0; uint256 balance1; address _token0 = token0; { address _token1 = token1; if (to == _token0 || to == _token1) revert InvalidReceiver(); if (amount0Out > 0) TransferHelper.safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens if (amount1Out > 0) TransferHelper.safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens balance0 = IERC20(_token0).balanceOf(address(this)) - antfarmTokenReserve; balance1 = IERC20(_token1).balanceOf(address(this)); } uint256 amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0; uint256 amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0; if (amount0In == 0 && amount1In == 0) revert InsufficientInputAmount(); emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to); // MINIMUM_LIQUIDITY is used instead of 1000 uint256 feeToPay = ((amount0In * fee) / (MINIMUM_LIQUIDITY + fee)) + ((amount0Out * fee) / (MINIMUM_LIQUIDITY - fee)); if (feeToPay < MINIMUM_LIQUIDITY) revert SwapAmountTooLow(); balance0 -= feeToPay; if (balance0 * balance1 < uint256(_reserve0) * _reserve1) revert K(); _update(balance0, balance1, _reserve0, _reserve1); // only 1% pool have oracles if (fee == 10) { IAntfarmOracle(antfarmOracle).update( price1CumulativeLast, blockTimestampLast ); } uint256 feeToDisburse = (feeToPay * 8500) / 10000; uint256 feeToBurn = feeToPay - feeToDisburse; _disburse(feeToDisburse); TransferHelper.safeTransfer( _token0, address(0x000000000000000000000000000000000000dEaD), feeToBurn ); } /// @inheritdoc IAntfarmPairActions function claimDividend(address to, uint256 positionId) external override nonReentrant updateDividend(msg.sender, positionId) returns (uint256 claimAmount) { claimAmount = positions[msg.sender][positionId].dividend; if (claimAmount != 0) { positions[msg.sender][positionId].dividend = 0; antfarmTokenReserve -= claimAmount; TransferHelper.safeTransfer(token0, to, claimAmount); } } /// @inheritdoc IAntfarmPairActions function skim(address to) external nonReentrant { address _token0 = token0; // gas savings address _token1 = token1; // gas savings TransferHelper.safeTransfer( _token0, to, IERC20(_token0).balanceOf(address(this)) - reserve0 - antfarmTokenReserve ); TransferHelper.safeTransfer( _token1, to, IERC20(_token1).balanceOf(address(this)) - reserve1 ); } /// @inheritdoc IAntfarmPairActions function sync() external nonReentrant { _update( IERC20(token0).balanceOf(address(this)) - antfarmTokenReserve, IERC20(token1).balanceOf(address(this)), reserve0, reserve1 ); } /// @inheritdoc IAntfarmPairDerivedState function getPositionLP(address operator, uint256 positionId) external view override returns (uint128) { return positions[operator][positionId].lp; } /// @inheritdoc IAntfarmPairDerivedState function getReserves() public view override returns ( uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast ) { _reserve0 = reserve0; _reserve1 = reserve1; _blockTimestampLast = blockTimestampLast; } /// @inheritdoc IAntfarmPairDerivedState function claimableDividends(address operator, uint256 positionId) external view override returns (uint256 amount) { uint256 tempTotalDividendPoints = totalDividendPoints; uint256 newDividend = newDividends( operator, positionId, tempTotalDividendPoints ); amount = positions[operator][positionId].dividend + newDividend; } function newDividends( address operator, uint256 positionId, uint256 tempTotalDividendPoints ) internal view returns (uint256 amount) { uint256 newDividendPoints = tempTotalDividendPoints - positions[operator][positionId].lastDividendPoints; amount = (positions[operator][positionId].lp * newDividendPoints) / POINT_MULTIPLIER; } function setOracleInstance() internal { antfarmOracle = address( new AntfarmOracle(token1, price1CumulativeLast, blockTimestampLast) ); } function _update( uint256 balance0, uint256 balance1, uint112 _reserve0, uint112 _reserve1 ) private { if (balance0 > type(uint112).max || balance1 > type(uint112).max) { revert BalanceOverflow(); } uint32 blockTimestamp = uint32(block.timestamp % 2**32); uint32 timeElapsed; unchecked { timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired } if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) { // * never overflows, and + overflow is desired price1CumulativeLast = price1CumulativeLast + (uint256(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed); } reserve0 = uint112(balance0); reserve1 = uint112(balance1); blockTimestampLast = blockTimestamp; emit Sync(reserve0, reserve1); } function _disburse(uint256 amount) private { totalDividendPoints = totalDividendPoints + ((amount * POINT_MULTIPLIER) / (totalSupply - MINIMUM_LIQUIDITY)); antfarmTokenReserve = antfarmTokenReserve + amount; } }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; import "../libraries/fixedpoint/FixedPoint.sol"; error InvalidToken(); /// @title Antfarm Oracle for AntfarmPair /// @notice Fixed window oracle that recomputes the average price for the entire period once every period contract AntfarmOracle { using FixedPoint for *; uint256 public constant PERIOD = 1 hours; address public token1; address public pair; uint256 public price1CumulativeLast; uint32 public blockTimestampLast; FixedPoint.uq112x112 public price1Average; bool public firstUpdateCall; constructor( address _token1, uint256 _price1CumulativeLast, uint32 _blockTimestampLast ) { token1 = _token1; pair = msg.sender; price1CumulativeLast = _price1CumulativeLast; // fetch the current accumulated price value (1 / 0) blockTimestampLast = _blockTimestampLast; firstUpdateCall = true; } /// @notice Average price update /// @param price1Cumulative Price cumulative for the associated AntfarmPair's token1 /// @param blockTimestamp Last block timestamp for the associated AntfarmPair /// @dev Only usable by the associated AntfarmPair function update(uint256 price1Cumulative, uint32 blockTimestamp) external { require(msg.sender == pair); unchecked { uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired // ensure that at least one full period has passed since the last update if (timeElapsed >= PERIOD || firstUpdateCall) { // overflow is desired, casting never truncates // cumulative price is in (uq112x112 price * seconds) units so we simply wrap it after division by time elapsed price1Average = FixedPoint.uq112x112( uint224( (price1Cumulative - price1CumulativeLast) / timeElapsed ) ); price1CumulativeLast = price1Cumulative; blockTimestampLast = blockTimestamp; if (firstUpdateCall) { firstUpdateCall = false; } } } } /// @notice Consult the average price for a given token /// @param token Price cumulative for the associated AntfarmPair's token /// @param amountIn The amount to get the value of /// @return amountOut Return the calculated amount (always return 0 before update has been called successfully for the first time) function consult(address token, uint256 amountIn) external view returns (uint256 amountOut) { if (token == token1) { amountOut = price1Average.mul(amountIn).decode144(); } else { revert InvalidToken(); } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.10; import "../interfaces/IERC20.sol"; import "../interfaces/IAntfarmFactory.sol"; import "../interfaces/IAntfarmPair.sol"; import "../interfaces/IAntfarmAtfPair.sol"; import "../interfaces/IAntfarmOracle.sol"; import "../libraries/math.sol"; import "../libraries/UQ112x112.sol"; import "../libraries/TransferHelper.sol"; import "../utils/AntfarmPairErrors.sol"; import "@rari-capital/solmate/src/utils/ReentrancyGuard.sol"; /// @title Core contract for Antfarm /// @notice Low-level contract to mint/burn/swap and claim contract AntfarmPair is IAntfarmPair, ReentrancyGuard, Math { using UQ112x112 for uint224; /// @inheritdoc IAntfarmPairState address public immutable factory; /// @inheritdoc IAntfarmPairState address public token0; /// @inheritdoc IAntfarmPairState address public token1; /// @inheritdoc IAntfarmPairState uint16 public fee; /// @inheritdoc IAntfarmPairState uint256 public totalSupply; /// @inheritdoc IAntfarmPairState uint256 public antfarmTokenReserve; /// @inheritdoc IAntfarmPair address public antfarmToken; /// @inheritdoc IAntfarmPair address public antfarmOracle; uint112 private reserve0; uint112 private reserve1; // DIVIDEND VARIABLES uint256 private totalDividendPoints; uint256 private constant POINT_MULTIPLIER = 1 ether; uint256 private constant MINIMUM_LIQUIDITY = 1000; struct Position { uint128 lp; uint256 dividend; uint256 lastDividendPoints; } mapping(address => mapping(uint256 => Position)) public positions; modifier updateDividend(address operator, uint256 positionId) { if (positions[operator][positionId].lp > 0) { uint256 owing = newDividends( operator, positionId, totalDividendPoints ); if (owing > 0) { positions[operator][positionId].dividend += owing; positions[operator][positionId] .lastDividendPoints = totalDividendPoints; } } else { positions[operator][positionId] .lastDividendPoints = totalDividendPoints; } _; } constructor() { factory = msg.sender; } function initialize( address _token0, address _token1, uint16 _fee, address _antfarmToken ) external { if (msg.sender != factory) revert SenderNotFactory(); token0 = _token0; token1 = _token1; fee = _fee; antfarmToken = _antfarmToken; } /// @inheritdoc IAntfarmPairActions function mint(address to, uint256 positionId) external override nonReentrant updateDividend(to, positionId) returns (uint256) { (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); uint256 balance0 = IERC20(token0).balanceOf(address(this)); uint256 balance1 = IERC20(token1).balanceOf(address(this)); uint256 amount0 = balance0 - _reserve0; uint256 amount1 = balance1 - _reserve1; uint256 liquidity; uint256 _totalSupply = totalSupply; if (_totalSupply == 0) { liquidity = Math.sqrt(amount0 * amount1) - MINIMUM_LIQUIDITY; totalSupply = MINIMUM_LIQUIDITY; } else { liquidity = Math.min( (amount0 * totalSupply) / _reserve0, (amount1 * totalSupply) / _reserve1 ); } if (liquidity == 0) revert InsufficientLiquidityMinted(); positions[to][positionId].lp += uint128(liquidity); totalSupply = totalSupply + liquidity; _update(balance0, balance1); if (_totalSupply == 0) { setOracleInstance(); } emit Mint(to, amount0, amount1); return liquidity; } /// @inheritdoc IAntfarmPairActions function burn( address to, uint256 positionId, uint256 liquidity ) external override nonReentrant updateDividend(msg.sender, positionId) returns (uint256, uint256) { address _token0 = token0; // gas savings address _token1 = token1; // gas savings uint256 balance0 = IERC20(_token0).balanceOf(address(this)); uint256 balance1 = IERC20(_token1).balanceOf(address(this)); if (positions[msg.sender][positionId].lp < liquidity) { revert InsufficientLiquidity(); } positions[msg.sender][positionId].lp -= uint128(liquidity); if (liquidity == 0) revert InsufficientLiquidity(); uint256 _totalSupply = totalSupply; // gas savings uint256 amount0 = (liquidity * balance0) / _totalSupply; uint256 amount1 = (liquidity * balance1) / _totalSupply; totalSupply = totalSupply - liquidity; if (amount0 == 0 || amount1 == 0) revert InsufficientLiquidityBurned(); TransferHelper.safeTransfer(_token0, to, amount0); TransferHelper.safeTransfer(_token1, to, amount1); balance0 = IERC20(_token0).balanceOf(address(this)); balance1 = IERC20(_token1).balanceOf(address(this)); _update(balance0, balance1); emit Burn(msg.sender, amount0, amount1, to); return (amount0, amount1); } /// @inheritdoc IAntfarmPairActions function swap( uint256 amount0Out, uint256 amount1Out, address to ) external nonReentrant { if (amount0Out == 0 && amount1Out == 0) { revert InsufficientOutputAmount(); } (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings if (amount0Out >= _reserve0 || amount1Out >= _reserve1) { revert InsufficientLiquidity(); } uint256 balance0; uint256 balance1; { address _token0 = token0; address _token1 = token1; if (to == _token0 || to == _token1) revert InvalidReceiver(); if (amount0Out > 0) TransferHelper.safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens if (amount1Out > 0) TransferHelper.safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens balance0 = IERC20(_token0).balanceOf(address(this)); balance1 = IERC20(_token1).balanceOf(address(this)); } uint256 amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0; uint256 amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0; if (amount0In == 0 && amount1In == 0) revert InsufficientInputAmount(); emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to); uint256 feeToPay; feeToPay = getFees(amount0Out, amount0In, amount1Out, amount1In); if (feeToPay < MINIMUM_LIQUIDITY) revert SwapAmountTooLow(); if ( IERC20(antfarmToken).balanceOf(address(this)) - antfarmTokenReserve < feeToPay ) { revert InsufficientFee(); } if (balance0 * balance1 < uint256(_reserve0) * _reserve1) revert K(); _update(balance0, balance1); uint256 feeToDisburse = (feeToPay * 8500) / 10000; uint256 feeToBurn = feeToPay - feeToDisburse; _disburse(feeToDisburse); TransferHelper.safeTransfer( antfarmToken, address(0x000000000000000000000000000000000000dEaD), feeToBurn ); } /// @inheritdoc IAntfarmPairActions function claimDividend(address to, uint256 positionId) external override nonReentrant updateDividend(msg.sender, positionId) returns (uint256 claimAmount) { claimAmount = positions[msg.sender][positionId].dividend; if (claimAmount != 0) { positions[msg.sender][positionId].dividend = 0; antfarmTokenReserve -= claimAmount; TransferHelper.safeTransfer(antfarmToken, to, claimAmount); } } /// @inheritdoc IAntfarmPairActions function skim(address to) external nonReentrant { address _token0 = token0; // gas savings address _token1 = token1; // gas savings TransferHelper.safeTransfer( _token0, to, IERC20(_token0).balanceOf(address(this)) - reserve0 ); TransferHelper.safeTransfer( _token1, to, IERC20(_token1).balanceOf(address(this)) - reserve1 ); } /// @inheritdoc IAntfarmPairActions function sync() external nonReentrant { _update( IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)) ); } /// @inheritdoc IAntfarmPairDerivedState function getPositionLP(address operator, uint256 positionId) external view override returns (uint128) { return positions[operator][positionId].lp; } /// @inheritdoc IAntfarmPair function updateOracle() public { address actualOracle; uint112 maxReserve; if (antfarmOracle != address(0)) { actualOracle = IAntfarmOracle(antfarmOracle).pair(); (maxReserve, , ) = IAntfarmAtfPair(actualOracle).getReserves(); } address bestOracle = scanOracles(maxReserve); if (bestOracle == address(0)) revert NoOracleFound(); if (bestOracle == antfarmOracle) revert NoBetterOracle(); antfarmOracle = bestOracle; } /// @inheritdoc IAntfarmPairDerivedState function getReserves() public view override returns ( uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast ) { _reserve0 = reserve0; _reserve1 = reserve1; _blockTimestampLast = 0; } /// @inheritdoc IAntfarmPair function getFees( uint256 amount0Out, uint256 amount0In, uint256 amount1Out, uint256 amount1In ) public view returns (uint256 feeToPay) { if (IAntfarmOracle(antfarmOracle).token1() == token0) { feeToPay = IAntfarmOracle(antfarmOracle).consult( token0, ((amount0In + amount0Out) * fee) / MINIMUM_LIQUIDITY ); } else { feeToPay = IAntfarmOracle(antfarmOracle).consult( token1, ((amount1In + amount1Out) * fee) / MINIMUM_LIQUIDITY ); } } /// @inheritdoc IAntfarmPairDerivedState function claimableDividends(address operator, uint256 positionId) external view override returns (uint256 amount) { uint256 tempTotalDividendPoints = totalDividendPoints; uint256 newDividend = newDividends( operator, positionId, tempTotalDividendPoints ); amount = positions[operator][positionId].dividend + newDividend; } /// @inheritdoc IAntfarmPair function scanOracles(uint112 maxReserve) public view override returns (address bestOracle) { address[2] memory tokens = [token0, token1]; for (uint256 token; token < 2; ++token) { address pairAddress = IAntfarmFactory(factory).getPair( antfarmToken, tokens[token], uint16(10) ); if (pairAddress == address(0)) { continue; } IAntfarmAtfPair pair = IAntfarmAtfPair(pairAddress); if (AntfarmOracle(pair.antfarmOracle()).firstUpdateCall()) { continue; } (uint112 _reserve0, , ) = pair.getReserves(); if (_reserve0 >= maxReserve) { bestOracle = address(pair.antfarmOracle()); maxReserve = _reserve0; } } } function newDividends( address operator, uint256 positionId, uint256 tempTotalDividendPoints ) internal view returns (uint256 amount) { uint256 newDividendPoints = tempTotalDividendPoints - positions[operator][positionId].lastDividendPoints; amount = (positions[operator][positionId].lp * newDividendPoints) / POINT_MULTIPLIER; } function setOracleInstance() internal { updateOracle(); if (antfarmOracle == address(0)) { revert NoOracleFound(); } } function _update(uint256 balance0, uint256 balance1) private { if (balance0 > type(uint112).max || balance1 > type(uint112).max) { revert BalanceOverflow(); } reserve0 = uint112(balance0); reserve1 = uint112(balance1); emit Sync(reserve0, reserve1); } function _disburse(uint256 amount) private { totalDividendPoints = totalDividendPoints + ((amount * POINT_MULTIPLIER) / (totalSupply - MINIMUM_LIQUIDITY)); antfarmTokenReserve = antfarmTokenReserve + amount; } }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; import "../antfarm/AntfarmOracle.sol"; import "./IAntfarmBase.sol"; interface IAntfarmAtfPair is IAntfarmBase { /// @notice Initialize the pair /// @dev Can only be called by the factory function initialize( address, address, uint16 ) external; /// @notice The Oracle instance associated to the AntfarmPair /// @return AntfarmOracle Oracle instance function antfarmOracle() external view returns (address); /// @notice Average token0 price depending on the AntfarmOracle's period /// @return uint token0 Average price function price1CumulativeLast() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; import "./pair/IAntfarmPairState.sol"; import "./pair/IAntfarmPairEvents.sol"; import "./pair/IAntfarmPairActions.sol"; import "./pair/IAntfarmPairDerivedState.sol"; interface IAntfarmBase is IAntfarmPairState, IAntfarmPairEvents, IAntfarmPairActions, IAntfarmPairDerivedState {}
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; interface IAntfarmFactory { event PairCreated( address indexed token0, address indexed token1, address pair, uint16 fee, uint256 allPairsLength ); function possibleFees(uint256) external view returns (uint16); function allPairs(uint256) external view returns (address); function antfarmToken() external view returns (address); function getPairs(uint256 startIndex, uint256 numOfPairs) external view returns (address[] memory, uint256); function getPair( address tokenA, address tokenB, uint16 fee ) external view returns (address pair); function feesForPair( address tokenA, address tokenB, uint256 ) external view returns (uint16); function getFeesForPair(address tokenA, address tokenB) external view returns (uint16[8] memory fees); function allPairsLength() external view returns (uint256); function createPair( address tokenA, address tokenB, uint16 fee ) external returns (address pair); }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; interface IAntfarmOracle { function pair() external view returns (address); function token1() external view returns (address); function consult(address, uint256) external view returns (uint256); function update(uint256, uint32) external; }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; import "./IAntfarmBase.sol"; interface IAntfarmPair is IAntfarmBase { /// @notice Initialize the pair /// @dev Can only be called by the factory function initialize( address, address, uint16, address ) external; /// @notice The Antfarm token address /// @return address Address function antfarmToken() external view returns (address); /// @notice The Oracle instance used to compute swap's fees /// @return AntfarmOracle Oracle instance function antfarmOracle() external view returns (address); /// @notice Calcul fee to pay /// @param amount0Out The token0 amount going out of the pool /// @param amount0In The token0 amount going in the pool /// @param amount1Out The token1 amount going out of the pool /// @param amount1In The token1 amount going in the pool /// @return feeToPay Calculated fee to be paid function getFees( uint256 amount0Out, uint256 amount0In, uint256 amount1Out, uint256 amount1In ) external view returns (uint256 feeToPay); /// @notice Check for the best Oracle to use to perform fee calculation for a swap /// @dev Returns address(0) if no better oracle is found. /// @param maxReserve Actual oracle reserve0 /// @return bestOracle Address from the best oracle found function scanOracles(uint112 maxReserve) external view returns (address bestOracle); /// @notice Update oracle for token /// @custom:usability Update the current Oracle with a more suitable one. Revert if the current Oracle is already the more suitable function updateOracle() external; }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; interface IAntfarmToken { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function nonces(address owner) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transfer(address recipient, uint256 amount) external returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; function DOMAIN_SEPARATOR() external view returns (bytes32); function burn(uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; interface IERC20 { event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, address indexed spender, uint256 value ); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; interface IAntfarmPairActions { /// @notice Mint liquidity for a specific position /// @dev Low-level function. Should be called from another contract which performs all necessary checks /// @param to The address to mint liquidity /// @param positionId The ID to store the position to allow multiple positions for a single address /// @return liquidity Minted liquidity function mint(address to, uint256 positionId) external returns (uint256 liquidity); /// @notice Burn liquidity from a specific position /// @dev Low-level function. Should be called from another contract which performs all necessary checks /// @param to The address to return the liquidity to /// @param positionId The ID of the position to burn liquidity from /// @param liquidity Liquidity amount to be burned /// @return amount0 The token0 amount received from the liquidity burn /// @return amount1 The token1 amount received from the liquidity burn function burn( address to, uint256 liquidity, uint256 positionId ) external returns (uint256 amount0, uint256 amount1); /// @notice Swap tokens /// @dev Low-level function. Should be called from another contract which performs all necessary checks /// @param amount0Out token0 amount to be swapped /// @param amount1Out token1 amount to be swapped /// @param to The address to send the swapped tokens function swap( uint256 amount0Out, uint256 amount1Out, address to ) external; /// @notice Force balances to match reserves /// @param to The address to send excessive tokens function skim(address to) external; /// @notice Force reserves to match balances function sync() external; /// @notice Claim dividends for a specific position /// @param to The address to receive claimed dividends /// @param positionId The ID of the position to claim /// @return claimedAmount The amount claimed function claimDividend(address to, uint256 positionId) external returns (uint256 claimedAmount); }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; interface IAntfarmPairDerivedState { /// @notice Get position LP tokens /// @param operator Position owner /// @param positionId ID of the position /// @return uint128 LP tokens owned by the operator function getPositionLP(address operator, uint256 positionId) external view returns (uint128); /// @notice Get pair reserves /// @return reserve0 Reserve for token0 /// @return reserve1 Reserve for token1 /// @return blockTimestampLast Last block proceeded function getReserves() external view returns ( uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast ); /// @notice Get Dividend from a specific position /// @param operator The address used to get dividends /// @param positionId Specific position /// @return amount Dividends owned by the address function claimableDividends(address operator, uint256 positionId) external view returns (uint256 amount); }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; interface IAntfarmPairEvents { /// @notice Emitted when a position's liquidity is removed /// @param sender The address that initiated the burn call /// @param amount0 The amount of token0 withdrawn /// @param amount1 The amount of token1 withdrawn /// @param to The address to send token0 & token1 event Burn( address indexed sender, uint256 amount0, uint256 amount1, address indexed to ); /// @notice Emitted when liquidity is minted for a given position /// @param sender The address that initiated the mint call /// @param amount0 Required token0 for the minted liquidity /// @param amount1 Required token1 for the minted liquidity event Mint(address indexed sender, uint256 amount0, uint256 amount1); /// @notice Emitted by the pool for any swaps between token0 and token1 /// @param sender The address that initiated the swap call /// @param amount0In Amount of token0 sent to the pair /// @param amount1In Amount of token1 sent to the pair /// @param amount0Out Amount of token0 going out of the pair /// @param amount1Out Amount of token1 going out of the pair /// @param to Address to transfer the swapped amount event Swap( address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to ); /// @notice Emitted by the pool for any call to Sync function /// @param reserve0 reserve0 updated from the pair /// @param reserve1 reserve1 updated from the pair event Sync(uint112 reserve0, uint112 reserve1); }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; import "../IAntfarmToken.sol"; interface IAntfarmPairState { /// @notice The contract that deployed the AntfarmPair, which must adhere to the IAntfarmFactory interface /// @return address The contract address function factory() external view returns (address); /// @notice The first of the two tokens of the AntfarmPair, sorted by address /// @return address The token contract address function token0() external view returns (address); /// @notice The second of the two tokens of the AntfarmPair, sorted by address /// @return address The token contract address function token1() external view returns (address); /// @notice Fee associated to the AntfarmPair instance /// @return uint16 Fee function fee() external view returns (uint16); /// @notice The LP tokens total circulating supply /// @return uint Total LP tokens function totalSupply() external view returns (uint256); /// @notice The AntFarmPair AntFarm's tokens cumulated fees /// @return uint Total Antfarm tokens function antfarmTokenReserve() external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.0; // computes square roots using the babylonian method // https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method library Babylonian { // credit for this implementation goes to // https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.sol#L687 function sqrt(uint256 x) internal pure returns (uint256) { if (x == 0) return 0; // this block is equivalent to r = uint256(1) << (BitMath.mostSignificantBit(x) / 2); // however that code costs significantly more gas uint256 xx = x; uint256 r = 1; if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } if (xx >= 0x10000) { xx >>= 16; r <<= 8; } if (xx >= 0x100) { xx >>= 8; r <<= 4; } if (xx >= 0x10) { xx >>= 4; r <<= 2; } if (xx >= 0x8) { r <<= 1; } r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; // Seven iterations should be enough uint256 r1 = x / r; return (r < r1 ? r : r1); } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.0; library BitMath { // returns the 0 indexed position of the most significant bit of the input x // s.t. x >= 2**msb and x < 2**(msb+1) function mostSignificantBit(uint256 x) internal pure returns (uint8 r) { require(x > 0, "BitMath::mostSignificantBit: zero"); if (x >= 0x100000000000000000000000000000000) { x >>= 128; r += 128; } if (x >= 0x10000000000000000) { x >>= 64; r += 64; } if (x >= 0x100000000) { x >>= 32; r += 32; } if (x >= 0x10000) { x >>= 16; r += 16; } if (x >= 0x100) { x >>= 8; r += 8; } if (x >= 0x10) { x >>= 4; r += 4; } if (x >= 0x4) { x >>= 2; r += 2; } if (x >= 0x2) r += 1; } // returns the 0 indexed position of the least significant bit of the input x // s.t. (x & 2**lsb) != 0 and (x & (2**(lsb) - 1)) == 0) // i.e. the bit at the index is set and the mask of all lower bits is 0 function leastSignificantBit(uint256 x) internal pure returns (uint8 r) { require(x > 0, "BitMath::leastSignificantBit: zero"); r = 255; if (x & type(uint128).max > 0) { r -= 128; } else { x >>= 128; } if (x & type(uint64).max > 0) { r -= 64; } else { x >>= 64; } if (x & type(uint32).max > 0) { r -= 32; } else { x >>= 32; } if (x & type(uint16).max > 0) { r -= 16; } else { x >>= 16; } if (x & type(uint16).max > 0) { r -= 8; } else { x >>= 8; } if (x & 0xf > 0) { r -= 4; } else { x >>= 4; } if (x & 0x3 > 0) { r -= 2; } else { x >>= 2; } if (x & 0x1 > 0) r -= 1; } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.0; import "./FullMath.sol"; import "./Babylonian.sol"; import "./BitMath.sol"; // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) library FixedPoint { // range: [0, 2**112 - 1] // resolution: 1 / 2**112 struct uq112x112 { uint224 _x; } // range: [0, 2**144 - 1] // resolution: 1 / 2**112 struct uq144x112 { uint256 _x; } uint8 public constant RESOLUTION = 112; uint256 public constant Q112 = 0x10000000000000000000000000000; // 2**112 uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000; // 2**224 uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits) // encode a uint112 as a UQ112x112 function encode(uint112 x) internal pure returns (uq112x112 memory) { return uq112x112(uint224(x) << RESOLUTION); } // encodes a uint144 as a UQ144x112 function encode144(uint144 x) internal pure returns (uq144x112 memory) { return uq144x112(uint256(x) << RESOLUTION); } // decode a UQ112x112 into a uint112 by truncating after the radix point function decode(uq112x112 memory self) internal pure returns (uint112) { return uint112(self._x >> RESOLUTION); } // decode a UQ144x112 into a uint144 by truncating after the radix point function decode144(uq144x112 memory self) internal pure returns (uint144) { return uint144(self._x >> RESOLUTION); } // multiply a UQ112x112 by a uint, returning a UQ144x112 // reverts on overflow function mul(uq112x112 memory self, uint256 y) internal pure returns (uq144x112 memory) { uint256 z = 0; require(y == 0 || (z = self._x * y) / y == self._x, "FixedPoint::mul: overflow"); return uq144x112(z); } // multiply a UQ112x112 by an int and decode, returning an int // reverts on overflow function muli(uq112x112 memory self, int256 y) internal pure returns (int256) { uint256 z = FullMath.mulDiv(self._x, uint256(y < 0 ? -y : y), Q112); require(z < 2**255, "FixedPoint::muli: overflow"); return y < 0 ? -int256(z) : int256(z); } // multiply a UQ112x112 by a UQ112x112, returning a UQ112x112 // lossy function muluq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) { if (self._x == 0 || other._x == 0) { return uq112x112(0); } uint112 upper_self = uint112(self._x >> RESOLUTION); // * 2^0 uint112 lower_self = uint112(self._x & LOWER_MASK); // * 2^-112 uint112 upper_other = uint112(other._x >> RESOLUTION); // * 2^0 uint112 lower_other = uint112(other._x & LOWER_MASK); // * 2^-112 // partial products uint224 upper = uint224(upper_self) * upper_other; // * 2^0 uint224 lower = uint224(lower_self) * lower_other; // * 2^-224 uint224 uppers_lowero = uint224(upper_self) * lower_other; // * 2^-112 uint224 uppero_lowers = uint224(upper_other) * lower_self; // * 2^-112 // so the bit shift does not overflow require(upper <= type(uint112).max, "FixedPoint::muluq: upper overflow"); // this cannot exceed 256 bits, all values are 224 bits uint256 sum = uint256(upper << RESOLUTION) + uppers_lowero + uppero_lowers + (lower >> RESOLUTION); // so the cast does not overflow require(sum <= type(uint224).max, "FixedPoint::muluq: sum overflow"); return uq112x112(uint224(sum)); } // divide a UQ112x112 by a UQ112x112, returning a UQ112x112 function divuq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) { require(other._x > 0, "FixedPoint::divuq: division by zero"); if (self._x == other._x) { return uq112x112(uint224(Q112)); } if (self._x <= type(uint144).max) { uint256 value = (uint256(self._x) << RESOLUTION) / other._x; require(value <= type(uint224).max, "FixedPoint::divuq: overflow"); return uq112x112(uint224(value)); } uint256 result = FullMath.mulDiv(Q112, self._x, other._x); require(result <= type(uint224).max, "FixedPoint::divuq: overflow"); return uq112x112(uint224(result)); } // returns a UQ112x112 which represents the ratio of the numerator to the denominator // can be lossy function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) { require(denominator > 0, "FixedPoint::fraction: division by zero"); if (numerator == 0) return FixedPoint.uq112x112(0); if (numerator <= type(uint144).max) { uint256 result = (numerator << RESOLUTION) / denominator; require(result <= type(uint224).max, "FixedPoint::fraction: overflow"); return uq112x112(uint224(result)); } else { uint256 result = FullMath.mulDiv(numerator, Q112, denominator); require(result <= type(uint224).max, "FixedPoint::fraction: overflow"); return uq112x112(uint224(result)); } } // take the reciprocal of a UQ112x112 // reverts on overflow // lossy function reciprocal(uq112x112 memory self) internal pure returns (uq112x112 memory) { require(self._x != 0, "FixedPoint::reciprocal: reciprocal of zero"); require(self._x != 1, "FixedPoint::reciprocal: overflow"); return uq112x112(uint224(Q224 / self._x)); } // square root of a UQ112x112 // lossy between 0/1 and 40 bits function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) { if (self._x <= type(uint144).max) { return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << 112))); } uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x); safeShiftBits -= safeShiftBits % 2; return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << safeShiftBits) << ((112 - safeShiftBits) / 2))); } }
// SPDX-License-Identifier: CC-BY-4.0 pragma solidity >=0.8.0; // taken from https://medium.com/coinmonks/math-in-solidity-part-3-percents-and-proportions-4db014e080b1 // license is CC-BY-4.0 library FullMath { function fullMul(uint256 x, uint256 y) internal pure returns (uint256 l, uint256 h) { uint256 mm = mulmod(x, y, type(uint256).max); l = x * y; h = mm - l; if (mm < l) h -= 1; } function fullDiv( uint256 l, uint256 h, uint256 d ) private pure returns (uint256) { uint256 pow2 = d & (type(uint256).max - d + 1) & d; d /= pow2; l /= pow2; l += h * (((type(uint256).max - pow2 + 1) & pow2) / pow2 + 1); uint256 r = 1; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; return l * r; } function mulDiv( uint256 x, uint256 y, uint256 d ) internal pure returns (uint256) { (uint256 l, uint256 h) = fullMul(x, y); uint256 mm = mulmod(x, y, d); if (mm > l) h -= 1; l -= mm; if (h == 0) return l / d; require(h < d, "FullMath: FULLDIV_OVERFLOW"); return fullDiv(l, h, d); } }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; // a library for performing various math operations contract Math { function min(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x < y ? x : y; } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity =0.8.10; // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes("approve(address,uint256)"))); (bool success, bytes memory data) = token.call( abi.encodeWithSelector(0x095ea7b3, to, value) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper::safeApprove: approve failed" ); } function safeTransfer( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes("transfer(address,uint256)"))); (bool success, bytes memory data) = token.call( abi.encodeWithSelector(0xa9059cbb, to, value) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper::safeTransfer: transfer failed" ); } function safeTransferFrom( address token, address from, address to, uint256 value ) internal { // bytes4(keccak256(bytes("transferFrom(address,address,uint256)"))); (bool success, bytes memory data) = token.call( abi.encodeWithSelector(0x23b872dd, from, to, value) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper::transferFrom: transferFrom failed" ); } function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require( success, "TransferHelper::safeTransferETH: ETH transfer failed" ); } }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) // range: [0, 2**112 - 1] // resolution: 1 / 2**112 library UQ112x112 { uint224 constant Q112 = 2**112; // encode a uint112 as a UQ112x112 function encode(uint112 y) internal pure returns (uint224 z) { z = uint224(y) * Q112; // never overflows } // divide a UQ112x112 by a uint112, returning a UQ112x112 function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { z = x / uint224(y); } }
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; error IdenticalAddresses(); error ZeroAddress(); error PairExists(); error IncorrectFee(); error ForbiddenFee();
// SPDX-License-Identifier: MIT pragma solidity =0.8.10; error SenderNotFactory(); error InsufficientOutputAmount(); error InsufficientLiquidity(); error InsufficientLiquidityMinted(); error InsufficientLiquidityBurned(); error InvalidReceiver(); error InsufficientInputAmount(); error InsufficientFee(); error K(); error SwapAmountTooLow(); error NoOracleFound(); error NoBetterOracle(); error BalanceOverflow();
{ "optimizer": { "enabled": true, "runs": 1000 }, "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":[{"internalType":"address","name":"_antfarmToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ForbiddenFee","type":"error"},{"inputs":[],"name":"IdenticalAddresses","type":"error"},{"inputs":[],"name":"IncorrectFee","type":"error"},{"inputs":[],"name":"PairExists","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint16","name":"fee","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"allPairsLength","type":"uint256"}],"name":"PairCreated","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"antfarmToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint16","name":"fee","type":"uint16"}],"name":"createPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"feesForPair","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token0","type":"address"},{"internalType":"address","name":"_token1","type":"address"}],"name":"getFeesForPair","outputs":[{"internalType":"uint16[8]","name":"","type":"uint16[8]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"numOfPairs","type":"uint256"}],"name":"getPairs","outputs":[{"internalType":"address[]","name":"pairs","type":"address[]"},{"internalType":"uint256","name":"newIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPossibleFees","outputs":[{"internalType":"uint16[8]","name":"","type":"uint16[8]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"possibleFees","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
610180604052600a6080908152603260a052606460c052609660e05260fa610100526101f4610120526102ee610140526103e86101605262000046906000906008620000eb565b503480156200005457600080fd5b5060405162005f2838038062005f2883398101604081905262000077916200019f565b6001600160a01b038116620000c55760405162461bcd60e51b815260206004820152601060248201526f4e554c4c5f4154465f4144445245535360801b604482015260640160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055620001d1565b600183019183908215620001765791602002820160005b838211156200014457835183826101000a81548161ffff021916908361ffff160217905550926020019260020160208160010104928301926001030262000102565b8015620001745782816101000a81549061ffff021916905560020160208160010104928301926001030262000144565b505b506200018492915062000188565b5090565b5b8082111562000184576000815560010162000189565b600060208284031215620001b257600080fd5b81516001600160a01b0381168114620001ca57600080fd5b9392505050565b615d4780620001e16000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063af5a96f211610076578063e579c2c21161005b578063e579c2c2146101aa578063ea313891146101b2578063f2364e91146101c557600080fd5b8063af5a96f214610184578063c12a00a81461019757600080fd5b80634bc72874116100a75780634bc728741461012d578063574f2ba3146101535780638647fe2e1461016457600080fd5b806309175fa7146100c35780631e3dd18b1461011a575b600080fd5b6100fd6100d1366004610d46565b60036020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100fd610128366004610d94565b6101e6565b61014061013b366004610dad565b610210565b60405161ffff9091168152602001610111565b600154604051908152602001610111565b610177610172366004610de9565b61025a565b6040516101119190610e13565b610140610192366004610d94565b6102e3565b6002546100fd906001600160a01b031681565b610177610311565b6100fd6101c0366004610d46565b610373565b6101d86101d3366004610e49565b610964565b604051610111929190610e6b565b600181815481106101f657600080fd5b6000918252602090912001546001600160a01b0316905081565b6004602052826000526040600020602052816000526040600020816008811061023857600080fd5b6010918282040191900660020292509250509054906101000a900461ffff1681565b610262610c46565b6001600160a01b03838116600090815260046020908152604080832093861683529290528181208251610100810193849052929091600891908390855b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161029f57509498975050505050505050565b600081600881106102f357600080fd5b60109182820401919006600202915054906101000a900461ffff1681565b610319610c46565b60408051610100810191829052906000906008908280855b82829054906101000a900461ffff1661ffff16815260200190600201906020826001010492830192600103820291508084116103315790505050505050905090565b60008061037f83610a72565b9050836001600160a01b0316856001600160a01b031614156103cd576040517fbd969eb000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460009081906001600160a01b03888116911614806103fb57506002546001600160a01b038781169116145b156104a6576002546001600160a01b03888116911614610427576002546001600160a01b031687610435565b6002546001600160a01b0316865b90925090506001600160a01b0381166104615760405163d92e233d60e01b815260040160405180910390fd5b8461ffff166103e814156104a1576040517f0c3f0a8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104f5565b856001600160a01b0316876001600160a01b0316106104c65785876104c9565b86865b90925090506001600160a01b0382166104f55760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0382811660009081526003602090815260408083208585168452825280832061ffff8a1684529091529020541615610560576040517f3d77e89100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460009081906001600160a01b038581169116146105a15760405161058960208201610c65565b601f1982820381018352601f909101166040526105c4565b6040516105b060208201610c72565b601f1982820381018352601f909101166040525b6002546040516bffffffffffffffffffffffff19606088811b8216602084015287811b821660348401527fffff00000000000000000000000000000000000000000000000000000000000060f08d901b1660488401529290921b909116604a820152909150600090605e01604051602081830303815290604052805190602001209050808251602084016000f592508260036000876001600160a01b03166001600160a01b031681526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060008a61ffff1661ffff16815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508260036000866001600160a01b03166001600160a01b031681526020019081526020016000206000876001600160a01b03166001600160a01b0316815260200190815260200160002060008a61ffff1661ffff16815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061076a858588610b0c565b6001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0385811691909117909155600254811690861614610875576002546040517fb1ffa5820000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152868116602483015261ffff8b16604483015291821660648201529084169063b1ffa58290608401600060405180830381600087803b15801561085857600080fd5b505af115801561086c573d6000803e3d6000fd5b505050506108fc565b6040517f7ebef5290000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152858116602483015261ffff8a166044830152841690637ebef52990606401600060405180830381600087803b1580156108e357600080fd5b505af11580156108f7573d6000803e3d6000fd5b505050505b600154604080516001600160a01b03868116825261ffff8c1660208301529181019290925280861691908716907f510cf15a092d0302f720eeedd34384cb979a59f85143c19f100768c260bc3f5f9060600160405180910390a3509098975050505050505050565b606060008361097260015490565b61097c9190610ed2565b83111561099a578361098d60015490565b6109979190610ed2565b92505b8267ffffffffffffffff8111156109b3576109b3610ee9565b6040519080825280602002602001820160405280156109dc578160200160208202803683370190505b50915060005b83811015610a5e5760016109f68287610eff565b81548110610a0657610a06610f17565b9060005260206000200160009054906101000a90046001600160a01b0316838281518110610a3657610a36610f17565b6001600160a01b0390921660209283029190910190910152610a5781610f2d565b90506109e2565b50610a698385610eff565b90509250929050565b6000805b60088161ffff161015610ad95760008161ffff1660088110610a9a57610a9a610f17565b601091828204019190066002029054906101000a900461ffff1661ffff168361ffff161415610ac95792915050565b610ad281610f48565b9050610a76565b506040517fcd3cb2bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383811660009081526004602090815260408083209386168352929052818120825161010081019384905291926008908285855b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411610b475790505050505050905060008261ffff1660088110610b9d57610b9d610f17565b601091828204019190066002029054906101000a900461ffff16818361ffff1660088110610bcd57610bcd610f17565b61ffff909216602092830291909101526001600160a01b0380861660009081526004835260408082209287168252919092529020610c0d90826008610c7f565b506001600160a01b038084166000908152600460209081526040808320938816835292905220610c3f90826008610c7f565b5050505050565b6040518061010001604052806008906020820280368337509192915050565b61256d80610f6b83390190565b61283a806134d883390190565b600183019183908215610d055791602002820160005b83821115610cd557835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302610c95565b8015610d035782816101000a81549061ffff0219169055600201602081600101049283019260010302610cd5565b505b50610d11929150610d15565b5090565b5b80821115610d115760008155600101610d16565b80356001600160a01b0381168114610d4157600080fd5b919050565b600080600060608486031215610d5b57600080fd5b610d6484610d2a565b9250610d7260208501610d2a565b9150604084013561ffff81168114610d8957600080fd5b809150509250925092565b600060208284031215610da657600080fd5b5035919050565b600080600060608486031215610dc257600080fd5b610dcb84610d2a565b9250610dd960208501610d2a565b9150604084013590509250925092565b60008060408385031215610dfc57600080fd5b610e0583610d2a565b9150610a6960208401610d2a565b6101008101818360005b6008811015610e4057815161ffff16835260209283019290910190600101610e1d565b50505092915050565b60008060408385031215610e5c57600080fd5b50508035926020909101359150565b604080825283519082018190526000906020906060840190828701845b82811015610ead5781516001600160a01b031684529284019290840190600101610e88565b50505092019290925292915050565b634e487b7160e01b600052601160045260246000fd5b600082821015610ee457610ee4610ebc565b500390565b634e487b7160e01b600052604160045260246000fd5b60008219821115610f1257610f12610ebc565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415610f4157610f41610ebc565b5060010190565b600061ffff80831681811415610f6057610f60610ebc565b600101939250505056fe60a0604052600160005534801561001557600080fd5b503360805260805161252a610043600039600081816103680152818161113301526113e2015261252a6000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063bc25cf77116100d8578063d6f124f01161008c578063f5298aca11610066578063f5298aca146103e0578063f6c67d8d14610408578063fff6cae91461041b57600080fd5b8063d6f124f01461039d578063ddca3f43146103a5578063e680ea2c146103cd57600080fd5b8063c1be6677116100bd578063c1be6677146102fa578063c45a015514610363578063d21220a71461038a57600080fd5b8063bc25cf77146102d4578063c12a00a8146102e757600080fd5b80632f7256381161013a5780636d9a640a116101145780636d9a640a1461029957806382e6a1c6146102ae578063b1ffa582146102c157600080fd5b80632f7256381461026057806340c10f19146102735780635247ab051461028657600080fd5b80630eb290661161016b5780630eb29066146101e957806318160ddd146102005780631f9d4db21461020957600080fd5b80630902f1ac146101875780630dfe1681146101be575b600080fd5b600754604080516001600160701b038084168252600160701b90930490921660208301526000908201526060015b60405180910390f35b6001546101d1906001600160a01b031681565b6040516001600160a01b0390911681526020016101b5565b6101f260045481565b6040519081526020016101b5565b6101f260035481565b61024861021736600461218e565b6001600160a01b0391909116600090815260096020908152604080832093835292905220546001600160801b031690565b6040516001600160801b0390911681526020016101b5565b6101f261026e3660046121ba565b610423565b6101f261028136600461218e565b61063f565b6101f261029436600461218e565b610a40565b6102ac6102a73660046121ec565b610bd3565b005b6101d16102bc36600461223a565b6110f2565b6102ac6102cf366004612257565b6113d7565b6102ac6102e23660046122ba565b6114b6565b6005546101d1906001600160a01b031681565b61033e61030836600461218e565b60096020908152600092835260408084209091529082529020805460018201546002909201546001600160801b03909116919083565b604080516001600160801b0390941684526020840192909252908201526060016101b5565b6101d17f000000000000000000000000000000000000000000000000000000000000000081565b6002546101d1906001600160a01b031681565b6102ac6115e7565b6002546103ba90600160a01b900461ffff1681565b60405161ffff90911681526020016101b5565b6101f26103db36600461218e565b61178b565b6103f36103ee3660046122d7565b6117db565b604080519283526020830191909152016101b5565b6006546101d1906001600160a01b031681565b6102ac611c8d565b600154600654604080517fd21220a700000000000000000000000000000000000000000000000000000000815290516000936001600160a01b0390811693169163d21220a79160048083019260209291908290030181865afa15801561048d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b1919061230c565b6001600160a01b0316141561057e576006546001546002546001600160a01b0392831692633ddac9539216906103e890600160a01b900461ffff166104f68a8a61233f565b6105009190612357565b61050a9190612376565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015610553573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105779190612398565b9050610637565b6006546002546001600160a01b0391821691633ddac95391908116906103e890600160a01b900461ffff166105b3888861233f565b6105bd9190612357565b6105c79190612376565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015610610573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106349190612398565b90505b949350505050565b600080546001146106845760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064015b60405180910390fd5b600260009081556001600160a01b0384168152600960209081526040808320858452909152902054839083906001600160801b0316156107415760006106cd8383600854611db7565b9050801561073b576001600160a01b03831660009081526009602090815260408083208584529091528120600101805483929061070b90849061233f565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b5061076c565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b60075460009081906001600160701b0380821691600160701b9004166001546040516370a0823160e01b81523060048201529294509092506000916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156107d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fd9190612398565b6002546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa15801561084b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086f9190612398565b905060006108866001600160701b038616846123b1565b9050600061089d6001600160701b038616846123b1565b600354909150600090806108d7576103e86108c06108bb8587612357565b611e39565b6108ca91906123b1565b6103e86003559150610926565b610923886001600160701b0316600354866108f29190612357565b6108fc9190612376565b886001600160701b0316600354866109149190612357565b61091e9190612376565b611ea9565b91505b8161095d576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038d1660009081526009602090815260408083208f8452909152812080548492906109999084906001600160801b03166123c8565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550816003546109cb919061233f565b6003556109d88686611ec1565b806109e5576109e5611f84565b60408051858152602081018590526001600160a01b038f16917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a25098505050505050505b5050600160005592915050565b60008054600114610a805760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161067b565b60026000908155338082526009602090815260408084208685529091529091205483906001600160801b031615610b34576000610ac08383600854611db7565b90508015610b2e576001600160a01b038316600090815260096020908152604080832085845290915281206001018054839290610afe90849061233f565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b50610b5f565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b33600090815260096020908152604080832087845290915290206001015492508215610a3357336000908152600960209081526040808320878452909152812060010181905560048054859290610bb79084906123b1565b9091555050600554610a33906001600160a01b03168685611fb7565b600054600114610c125760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161067b565b600260005582158015610c23575081155b15610c5a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546001600160701b0380821691600160701b9004168185101580610c895750806001600160701b03168410155b15610ca75760405163bb55fd2760e01b815260040160405180910390fd5b60015460025460009182916001600160a01b0391821691908116908716821480610ce25750806001600160a01b0316876001600160a01b0316145b15610d19576040517f1e4ec46b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8815610d2a57610d2a82888b611fb7565b8715610d3b57610d3b81888a611fb7565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610d7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da39190612398565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610dea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0e9190612398565b92505050600087856001600160701b0316610e2991906123b1565b8311610e36576000610e53565b610e49886001600160701b0387166123b1565b610e5390846123b1565b90506000610e6a886001600160701b0387166123b1565b8311610e77576000610e94565b610e8a886001600160701b0387166123b1565b610e9490846123b1565b905081158015610ea2575080155b15610ed9576040517f098fb56100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051838152602081018390529081018a9052606081018990526001600160a01b0388169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a36000610f3c8a848b85610423565b90506103e8811015610f7a576040517ff570cd7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480546005546040516370a0823160e01b8152309381019390935283926001600160a01b03909116906370a0823190602401602060405180830381865afa158015610fca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fee9190612398565b610ff891906123b1565b1015611030576040517f025dbdd400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110466001600160701b03808816908916612357565b6110508587612357565b1015611088576040517fa932492f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110928585611ec1565b60006127106110a383612134612357565b6110ad9190612376565b905060006110bb82846123b1565b90506110c682612126565b6005546110df906001600160a01b031661dead83611fb7565b5050600160005550505050505050505050565b604080518082019091526001546001600160a01b039081168252600254166020820152600090815b60028110156113d0576005546000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116916309175fa7911685856002811061116e5761116e6123f3565b60200201516040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152600a6044820152606401602060405180830381865afa1580156111c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e9919061230c565b90506001600160a01b0381166111ff57506113c0565b6000819050806001600160a01b031663f6c67d8d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611242573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611266919061230c565b6001600160a01b031663fcfedfb16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c79190612409565b156112d35750506113c0565b6000816001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611313573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611337919061242b565b50509050866001600160701b0316816001600160701b0316106113bc57816001600160a01b031663f6c67d8d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611392573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b6919061230c565b95508096505b5050505b6113c981612476565b905061111a565b5050919050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611439576040517f015551dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180546001600160a01b0395861673ffffffffffffffffffffffffffffffffffffffff19918216179091556002805461ffff909416600160a01b027fffffffffffffffffffff00000000000000000000000000000000000000000000909416948616949094179290921790925560058054929093169116179055565b6000546001146114f55760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161067b565b6002600081905560015490546007546040516370a0823160e01b81523060048201526001600160a01b03938416939092169161159591849186916001600160701b03169083906370a08231906024015b602060405180830381865afa158015611562573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115869190612398565b61159091906123b1565b611fb7565b6007546040516370a0823160e01b81523060048201526115dd9183918691600160701b90046001600160701b0316906001600160a01b038416906370a0823190602401611545565b5050600160005550565b60065460009081906001600160a01b0316156116de57600660009054906101000a90046001600160a01b03166001600160a01b031663a8aa1b316040518163ffffffff1660e01b8152600401602060405180830381865afa158015611650573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611674919061230c565b9150816001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d8919061242b565b50909150505b60006116e9826110f2565b90506001600160a01b03811661171257604051639989e18760e01b815260040160405180910390fd5b6006546001600160a01b038281169116141561175a576040517febd9054000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03929092169190911790555050565b6008546000908161179d858584611db7565b6001600160a01b03861660009081526009602090815260408083208884529091529020600101549091506117d290829061233f565b95945050505050565b60008060005460011461181d5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161067b565b60026000908155338082526009602090815260408084208885529091529091205485906001600160801b0316156118d157600061185d8383600854611db7565b905080156118cb576001600160a01b03831660009081526009602090815260408083208584529091528120600101805483929061189b90849061233f565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b506118fc565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b6001546002546040516370a0823160e01b81523060048201526001600160a01b03928316929091169060009083906370a0823190602401602060405180830381865afa158015611950573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119749190612398565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156119be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e29190612398565b3360009081526009602090815260408083208e84529091529020549091506001600160801b0316891115611a295760405163bb55fd2760e01b815260040160405180910390fd5b3360009081526009602090815260408083208d8452909152812080548b9290611a5c9084906001600160801b0316612491565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508860001415611aa25760405163bb55fd2760e01b815260040160405180910390fd5b600354600081611ab2858d612357565b611abc9190612376565b9050600082611acb858e612357565b611ad59190612376565b90508b600354611ae591906123b1565b600355811580611af3575080155b15611b2a576040517f749383ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b35878f84611fb7565b611b40868f83611fb7565b6040516370a0823160e01b81523060048201526001600160a01b038816906370a0823190602401602060405180830381865afa158015611b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba89190612398565b6040516370a0823160e01b81523060048201529095506001600160a01b038716906370a0823190602401602060405180830381865afa158015611bef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c139190612398565b9350611c1f8585611ec1565b8d6001600160a01b0316336001600160a01b03167fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d819364968484604051611c6d929190918252602082015260400190565b60405180910390a36001600055909d909c509a5050505050505050505050565b600054600114611ccc5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161067b565b60026000556001546040516370a0823160e01b8152306004820152611db0916001600160a01b0316906370a0823190602401602060405180830381865afa158015611d1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3f9190612398565b6002546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611d87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dab9190612398565b611ec1565b6001600055565b6001600160a01b03831660009081526009602090815260408083208584529091528120600201548190611dea90846123b1565b6001600160a01b0386166000908152600960209081526040808320888452909152902054909150670de0b6b3a764000090611e2f9083906001600160801b0316612357565b6117d29190612376565b60006003821115611e9a5750806000611e53600283612376565b611e5e90600161233f565b90505b81811015611e9457905080600281611e798186612376565b611e83919061233f565b611e8d9190612376565b9050611e61565b50919050565b8115611ea4575060015b919050565b6000818310611eb85781611eba565b825b9392505050565b6001600160701b03821180611edc57506001600160701b0381115b15611f13576040517f89560ca100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780546001600160701b03838116600160701b9081026001600160e01b0319909316868316179290921792839055604080518483168152929093041660208201527f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1910160405180910390a15050565b611f8c6115e7565b6006546001600160a01b0316611fb557604051639989e18760e01b815260040160405180910390fd5b565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161204191906124b9565b6000604051808303816000865af19150503d806000811461207e576040519150601f19603f3d011682016040523d82523d6000602084013e612083565b606091505b50915091508180156120ad5750805115806120ad5750808060200190518101906120ad9190612409565b61211f5760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c656400000000000000000000000000000000000000606482015260840161067b565b5050505050565b6103e860035461213691906123b1565b612148670de0b6b3a764000083612357565b6121529190612376565b60085461215f919061233f565b60085560045461217090829061233f565b60045550565b6001600160a01b038116811461218b57600080fd5b50565b600080604083850312156121a157600080fd5b82356121ac81612176565b946020939093013593505050565b600080600080608085870312156121d057600080fd5b5050823594602084013594506040840135936060013592509050565b60008060006060848603121561220157600080fd5b8335925060208401359150604084013561221a81612176565b809150509250925092565b6001600160701b038116811461218b57600080fd5b60006020828403121561224c57600080fd5b8135611eba81612225565b6000806000806080858703121561226d57600080fd5b843561227881612176565b9350602085013561228881612176565b9250604085013561ffff8116811461229f57600080fd5b915060608501356122af81612176565b939692955090935050565b6000602082840312156122cc57600080fd5b8135611eba81612176565b6000806000606084860312156122ec57600080fd5b83356122f781612176565b95602085013595506040909401359392505050565b60006020828403121561231e57600080fd5b8151611eba81612176565b634e487b7160e01b600052601160045260246000fd5b6000821982111561235257612352612329565b500190565b600081600019048311821515161561237157612371612329565b500290565b60008261239357634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156123aa57600080fd5b5051919050565b6000828210156123c3576123c3612329565b500390565b60006001600160801b038083168185168083038211156123ea576123ea612329565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561241b57600080fd5b81518015158114611eba57600080fd5b60008060006060848603121561244057600080fd5b835161244b81612225565b602085015190935061245c81612225565b604085015190925063ffffffff8116811461221a57600080fd5b600060001982141561248a5761248a612329565b5060010190565b60006001600160801b03838116908316818110156124b1576124b1612329565b039392505050565b6000825160005b818110156124da57602081860181015185830152016124c0565b818111156124e9576000828501525b50919091019291505056fea2646970667358221220ed2b296666058c99a67fe8c1e2c2ec013d6cb863394d87553af151363540861f64736f6c634300080a003360a0604052600160005534801561001557600080fd5b50336080526080516127fe61003c6000396000818161034e015261103501526127fe6000f3fe60806040523480156200001157600080fd5b50600436106200016c5760003560e01c80637ebef52911620000dd578063ddca3f43116200008b578063f5298aca116200006e578063f5298aca14620003c5578063f6c67d8d14620003f2578063fff6cae9146200040657600080fd5b8063ddca3f431462000384578063e680ea2c14620003ae57600080fd5b8063c1be667711620000c0578063c1be667714620002db578063c45a01551462000348578063d21220a7146200037057600080fd5b80637ebef52914620002ad578063bc25cf7714620002c457600080fd5b80631f9d4db2116200013b5780635247ab05116200011e5780635247ab0514620002735780635a3d5493146200028a5780636d9a640a146200029457600080fd5b80631f9d4db2146200020157806340c10f19146200025c57600080fd5b80630902f1ac14620001715780630dfe168114620001b15780630eb2906614620001de57806318160ddd14620001f7575b600080fd5b600754604080516001600160701b038084168252600160701b8404166020820152600160e01b90920463ffffffff16908201526060015b60405180910390f35b600154620001c5906001600160a01b031681565b6040516001600160a01b039091168152602001620001a8565b620001e860055481565b604051908152602001620001a8565b620001e860035481565b620002436200021236600462001f12565b6001600160a01b0391909116600090815260096020908152604080832093835292905220546001600160801b031690565b6040516001600160801b039091168152602001620001a8565b620001e86200026d36600462001f12565b62000410565b620001e86200028436600462001f12565b6200087e565b620001e860045481565b620002ab620002a536600462001f3f565b62000a1f565b005b620002ab620002be36600462001f77565b6200102a565b620002ab620002d536600462001fcb565b620010f9565b62000322620002ec36600462001f12565b60096020908152600092835260408084209091529082529020805460018201546002909201546001600160801b03909116919083565b604080516001600160801b039094168452602084019290925290820152606001620001a8565b620001c57f000000000000000000000000000000000000000000000000000000000000000081565b600254620001c5906001600160a01b031681565b6002546200039a90600160a01b900461ffff1681565b60405161ffff9091168152602001620001a8565b620001e8620003bf36600462001f12565b62001283565b620003dc620003d636600462001fe9565b620012d7565b60408051928352602083019190915201620001a8565b600654620001c5906001600160a01b031681565b620002ab62001827565b60008054600114620004565760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064015b60405180910390fd5b600260009081556001600160a01b0384168152600960209081526040808320858452909152902054839083906001600160801b0316156200051a576000620004a2838360085462001982565b9050801562000513576001600160a01b038316600090815260096020908152604080832085845290915281206001018054839290620004e390849062002035565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b5062000545565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b600080620005776007546001600160701b0380821692600160701b83049091169163ffffffff600160e01b9091041690565b506005546001546040516370a0823160e01b815230600482015293955091935060009290916001600160a01b0316906370a0823190602401602060405180830381865afa158015620005cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005f3919062002050565b620005ff91906200206a565b6002546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156200064e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000674919062002050565b905060006200068d6001600160701b038616846200206a565b90506000620006a66001600160701b038616846200206a565b60035490915060009080620006e8576103e8620006ce620006c8858762002084565b62001a0a565b620006da91906200206a565b6103e8600355915062000741565b6200073e886001600160701b03166003548662000706919062002084565b620007129190620020bc565b886001600160701b0316600354866200072c919062002084565b620007389190620020bc565b62001a88565b91505b8162000779576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038d1660009081526009602090815260408083208f845290915281208054849290620007b79084906001600160801b0316620020d3565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555081600354620007eb919062002035565b600355620007fc86868a8a62001aa2565b806200082357600254600160a01b900461ffff16600a141562000823576200082362001c54565b60408051858152602081018590526001600160a01b038f16917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a25098505050505050505b5050600160005592915050565b60008054600114620008c05760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016200044d565b60026000908155338082526009602090815260408084208685529091529091205483906001600160801b0316156200097b57600062000903838360085462001982565b9050801562000974576001600160a01b0383166000908152600960209081526040808320858452909152812060010180548392906200094490849062002035565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b50620009a6565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b33600090815260096020908152604080832087845290915290206001015492508215620008715733600090815260096020908152604080832087845290915281206001018190556005805485929062000a019084906200206a565b909155505060015462000871906001600160a01b0316868562001cf6565b60005460011462000a605760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016200044d565b60026000558215801562000a72575081155b1562000aaa576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008062000adc6007546001600160701b0380821692600160701b83049091169163ffffffff600160e01b9091041690565b5091509150816001600160701b03168510158062000b035750806001600160701b03168410155b1562000b225760405163bb55fd2760e01b815260040160405180910390fd5b60015460025460009182916001600160a01b039182169190811690871682148062000b5e5750806001600160a01b0316876001600160a01b0316145b1562000b96576040517f1e4ec46b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b881562000baa5762000baa82888b62001cf6565b871562000bbe5762000bbe81888a62001cf6565b6005546040516370a0823160e01b81523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa15801562000c06573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c2c919062002050565b62000c3891906200206a565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa15801562000c80573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ca6919062002050565b92506000905062000cc1896001600160701b0388166200206a565b841162000cd057600062000cf1565b62000ce5896001600160701b0388166200206a565b62000cf190856200206a565b9050600062000d0a896001600160701b0388166200206a565b841162000d1957600062000d3a565b62000d2e896001600160701b0388166200206a565b62000d3a90856200206a565b90508115801562000d49575080155b1562000d81576040517f098fb56100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051838152602081018390529081018b9052606081018a90526001600160a01b0389169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a360025460009062000df590600160a01b900461ffff166103e86200206a565b60025462000e0f90600160a01b900461ffff168d62002084565b62000e1b9190620020bc565b60025462000e3790600160a01b900461ffff166103e862002035565b60025462000e5190600160a01b900461ffff168662002084565b62000e5d9190620020bc565b62000e69919062002035565b90506103e881101562000ea8576040517ff570cd7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000eb481876200206a565b955062000ece6001600160701b03808916908a1662002084565b62000eda868862002084565b101562000f13576040517fa932492f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000f2186868a8a62001aa2565b600254600160a01b900461ffff16600a141562000fcb57600654600480546007546040517fcebab53d00000000000000000000000000000000000000000000000000000000815292830191909152600160e01b900463ffffffff1660248201526001600160a01b039091169063cebab53d90604401600060405180830381600087803b15801562000fb157600080fd5b505af115801562000fc6573d6000803e3d6000fd5b505050505b600061271062000fde8361213462002084565b62000fea9190620020bc565b9050600062000ffa82846200206a565b9050620010078262001e5a565b620010168661dead8362001cf6565b505060016000555050505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146200108d576040517f015551dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180546001600160a01b0394851673ffffffffffffffffffffffffffffffffffffffff199091161790556002805461ffff909216600160a01b027fffffffffffffffffffff000000000000000000000000000000000000000000009092169290931691909117179055565b6000546001146200113a5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016200044d565b6002600081905560015490546005546007546040516370a0823160e01b81523060048201526001600160a01b039485169490931692620011f192859287926001600160701b039091169084906370a0823190602401602060405180830381865afa158015620011ad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011d3919062002050565b620011df91906200206a565b620011eb91906200206a565b62001cf6565b6007546040516370a0823160e01b8152306004820152620012799183918691600160701b90046001600160701b0316906001600160a01b038416906370a0823190602401602060405180830381865afa15801562001253573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011df919062002050565b5050600160005550565b600854600090816200129785858462001982565b6001600160a01b0386166000908152600960209081526040808320888452909152902060010154909150620012ce90829062002035565b95945050505050565b6000806000546001146200131b5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016200044d565b60026000908155338082526009602090815260408084208885529091529091205485906001600160801b031615620013d65760006200135e838360085462001982565b90508015620013cf576001600160a01b0383166000908152600960209081526040808320858452909152812060010180548392906200139f90849062002035565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b5062001401565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b600080620014336007546001600160701b0380821692600160701b83049091169163ffffffff600160e01b9091041690565b506005546001546040516370a0823160e01b815230600482015293955091935060009290916001600160a01b0316906370a0823190602401602060405180830381865afa15801562001489573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620014af919062002050565b620014bb91906200206a565b6002546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156200150a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001530919062002050565b3360009081526009602090815260408083208e84529091529020549091506001600160801b0316891115620015785760405163bb55fd2760e01b815260040160405180910390fd5b3360009081526009602090815260408083208d8452909152812080548b9290620015ad9084906001600160801b031662002101565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508860001415620015f45760405163bb55fd2760e01b815260040160405180910390fd5b60035460008162001606858d62002084565b620016129190620020bc565b905060008262001623858e62002084565b6200162f9190620020bc565b90508b6003546200164191906200206a565b60035581158062001650575080155b1562001688576040517f749383ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154620016a1906001600160a01b03168f8462001cf6565b600254620016ba906001600160a01b03168f8362001cf6565b6005546001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801562001706573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200172c919062002050565b6200173891906200206a565b6002546040516370a0823160e01b81523060048201529196506001600160a01b0316906370a0823190602401602060405180830381865afa15801562001782573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017a8919062002050565b9350620017b88585898962001aa2565b8d6001600160a01b0316336001600160a01b03167fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496848460405162001807929190918252602082015260400190565b60405180910390a36001600055909d909c509a5050505050505050505050565b600054600114620018685760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016200044d565b60026000556005546001546040516370a0823160e01b81523060048201526200197b92916001600160a01b0316906370a0823190602401602060405180830381865afa158015620018bd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018e3919062002050565b620018ef91906200206a565b6002546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801562001938573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200195e919062002050565b6007546001600160701b0380821691600160701b90041662001aa2565b6001600055565b6001600160a01b03831660009081526009602090815260408083208584529091528120600201548190620019b790846200206a565b6001600160a01b0386166000908152600960209081526040808320888452909152902054909150670de0b6b3a764000090620019fe9083906001600160801b031662002084565b620012ce9190620020bc565b6000600382111562001a78575080600062001a27600283620020bc565b62001a3490600162002035565b90505b8181101562001a725790508060028162001a528186620020bc565b62001a5e919062002035565b62001a6a9190620020bc565b905062001a37565b50919050565b811562001a83575060015b919050565b600081831062001a99578162001a9b565b825b9392505050565b6001600160701b0384118062001abe57506001600160701b0383115b1562001af6576040517f89560ca100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062001b09640100000000426200212c565b60075490915063ffffffff600160e01b909104811682039081161580159062001b3a57506001600160701b03841615155b801562001b4f57506001600160701b03831615155b1562001ba4578063ffffffff1662001b7c8462001b6c8762001eb4565b6001600160e01b03169062001ed5565b6001600160e01b031662001b91919062002084565b60045462001ba0919062002035565b6004555b6007805463ffffffff8416600160e01b026001600160e01b036001600160701b03898116600160701b9081027fffffffff000000000000000000000000000000000000000000000000000000009095168c83161794909417918216831794859055604080519382169282169290921783529290930490911660208201527f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1910160405180910390a1505050505050565b6002546004546007546040516001600160a01b0390931692600160e01b90910463ffffffff169062001c869062001eec565b6001600160a01b039093168352602083019190915263ffffffff166040820152606001604051809103906000f08015801562001cc6573d6000803e3d6000fd5b506006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b03167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169162001d6d919062002143565b6000604051808303816000865af19150503d806000811462001dac576040519150601f19603f3d011682016040523d82523d6000602084013e62001db1565b606091505b509150915081801562001ddf57508051158062001ddf57508080602001905181019062001ddf919062002181565b62001e535760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c65640000000000000000000000000000000000000060648201526084016200044d565b5050505050565b6103e860035462001e6c91906200206a565b62001e80670de0b6b3a76400008362002084565b62001e8c9190620020bc565b60085462001e9b919062002035565b60085560055462001eae90829062002035565b60055550565b600062001ecf600160701b6001600160701b038416620021a5565b92915050565b600062001a9b6001600160701b03831684620021d7565b6105c8806200220183390190565b80356001600160a01b038116811462001a8357600080fd5b6000806040838503121562001f2657600080fd5b62001f318362001efa565b946020939093013593505050565b60008060006060848603121562001f5557600080fd5b833592506020840135915062001f6e6040850162001efa565b90509250925092565b60008060006060848603121562001f8d57600080fd5b62001f988462001efa565b925062001fa86020850162001efa565b9150604084013561ffff8116811462001fc057600080fd5b809150509250925092565b60006020828403121562001fde57600080fd5b62001a9b8262001efa565b60008060006060848603121562001fff57600080fd5b6200200a8462001efa565b95602085013595506040909401359392505050565b634e487b7160e01b600052601160045260246000fd5b600082198211156200204b576200204b6200201f565b500190565b6000602082840312156200206357600080fd5b5051919050565b6000828210156200207f576200207f6200201f565b500390565b6000816000190483118215151615620020a157620020a16200201f565b500290565b634e487b7160e01b600052601260045260246000fd5b600082620020ce57620020ce620020a6565b500490565b60006001600160801b03808316818516808303821115620020f857620020f86200201f565b01949350505050565b60006001600160801b03838116908316818110156200212457620021246200201f565b039392505050565b6000826200213e576200213e620020a6565b500690565b6000825160005b818110156200216657602081860181015185830152016200214a565b8181111562002176576000828501525b509190910192915050565b6000602082840312156200219457600080fd5b8151801515811462001a9b57600080fd5b60006001600160e01b0380831681851681830481118215151615620021ce57620021ce6200201f565b02949350505050565b60006001600160e01b0380841680620021f457620021f4620020a6565b9216919091049291505056fe608060405234801561001057600080fd5b506040516105c83803806105c883398101604081905261002f9161008b565b600080546001600160a01b039094166001600160a01b031994851617905560018054909316331783556002919091556003805463ffffffff90921663ffffffff199092169190911790556005805460ff191690911790556100e3565b6000806000606084860312156100a057600080fd5b83516001600160a01b03811681146100b757600080fd5b60208501516040860151919450925063ffffffff811681146100d857600080fd5b809150509250925092565b6104d6806100f26000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063b4d1d79511610076578063cebab53d1161005b578063cebab53d1461015b578063d21220a714610170578063fcfedfb11461018357600080fd5b8063b4d1d7951461012d578063c5700a021461013657600080fd5b80633ddac953146100a85780635a3d5493146100ce5780635e6aaf2c146100d7578063a8aa1b3114610102575b600080fd5b6100bb6100b63660046103ca565b6101a0565b6040519081526020015b60405180910390f35b6100bb60025481565b6004546100ea906001600160e01b031681565b6040516001600160e01b0390911681526020016100c5565b600154610115906001600160a01b031681565b6040516001600160a01b0390911681526020016100c5565b6100bb610e1081565b6003546101469063ffffffff1681565b60405163ffffffff90911681526020016100c5565b61016e610169366004610402565b610238565b005b600054610115906001600160a01b031681565b6005546101909060ff1681565b60405190151581526020016100c5565b600080546001600160a01b03848116911614156102005760408051602081019091526004546001600160e01b031681526101e5906101de908461030e565b5160701c90565b71ffffffffffffffffffffffffffffffffffff169050610232565b6040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b92915050565b6001546001600160a01b0316331461024f57600080fd5b60035463ffffffff908116820390610e10908216101580610272575060055460ff165b156103095760405180602001604052808263ffffffff1660025486038161029b5761029b61043b565b046001600160e01b039081169091529051600480547fffffffff00000000000000000000000000000000000000000000000000000000169190921617905560028390556003805463ffffffff191663ffffffff841617905560055460ff1615610309576005805460ff191690555b505050565b604080516020810190915260008152600082158061034b575083516001600160e01b03168361033d8183610451565b9250610349908361047e565b145b6103b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4669786564506f696e743a3a6d756c3a206f766572666c6f7700000000000000604482015260640160405180910390fd5b60408051602081019091529081529392505050565b600080604083850312156103dd57600080fd5b82356001600160a01b03811681146103f457600080fd5b946020939093013593505050565b6000806040838503121561041557600080fd5b82359150602083013563ffffffff8116811461043057600080fd5b809150509250929050565b634e487b7160e01b600052601260045260246000fd5b600081600019048311821515161561047957634e487b7160e01b600052601160045260246000fd5b500290565b60008261049b57634e487b7160e01b600052601260045260246000fd5b50049056fea26469706673582212205f6b4dad031f2b09ee010b27cf8d81fe590b4af24b73d5b60e7c163c7aeb478764736f6c634300080a0033a2646970667358221220701ca9581e1af984f165ca7011f34f579caa8cef9f23f2d2213936d8e467e3b464736f6c634300080a0033a26469706673582212201bacf5617855e13b83230eea19c90ecb28b0139049748a47fa97384dd9d4c3be64736f6c634300080a003300000000000000000000000040df0c3bbaae5ea3a509d8f2aa9e086776c98e6c
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100be5760003560e01c8063af5a96f211610076578063e579c2c21161005b578063e579c2c2146101aa578063ea313891146101b2578063f2364e91146101c557600080fd5b8063af5a96f214610184578063c12a00a81461019757600080fd5b80634bc72874116100a75780634bc728741461012d578063574f2ba3146101535780638647fe2e1461016457600080fd5b806309175fa7146100c35780631e3dd18b1461011a575b600080fd5b6100fd6100d1366004610d46565b60036020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100fd610128366004610d94565b6101e6565b61014061013b366004610dad565b610210565b60405161ffff9091168152602001610111565b600154604051908152602001610111565b610177610172366004610de9565b61025a565b6040516101119190610e13565b610140610192366004610d94565b6102e3565b6002546100fd906001600160a01b031681565b610177610311565b6100fd6101c0366004610d46565b610373565b6101d86101d3366004610e49565b610964565b604051610111929190610e6b565b600181815481106101f657600080fd5b6000918252602090912001546001600160a01b0316905081565b6004602052826000526040600020602052816000526040600020816008811061023857600080fd5b6010918282040191900660020292509250509054906101000a900461ffff1681565b610262610c46565b6001600160a01b03838116600090815260046020908152604080832093861683529290528181208251610100810193849052929091600891908390855b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161029f57509498975050505050505050565b600081600881106102f357600080fd5b60109182820401919006600202915054906101000a900461ffff1681565b610319610c46565b60408051610100810191829052906000906008908280855b82829054906101000a900461ffff1661ffff16815260200190600201906020826001010492830192600103820291508084116103315790505050505050905090565b60008061037f83610a72565b9050836001600160a01b0316856001600160a01b031614156103cd576040517fbd969eb000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460009081906001600160a01b03888116911614806103fb57506002546001600160a01b038781169116145b156104a6576002546001600160a01b03888116911614610427576002546001600160a01b031687610435565b6002546001600160a01b0316865b90925090506001600160a01b0381166104615760405163d92e233d60e01b815260040160405180910390fd5b8461ffff166103e814156104a1576040517f0c3f0a8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104f5565b856001600160a01b0316876001600160a01b0316106104c65785876104c9565b86865b90925090506001600160a01b0382166104f55760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0382811660009081526003602090815260408083208585168452825280832061ffff8a1684529091529020541615610560576040517f3d77e89100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460009081906001600160a01b038581169116146105a15760405161058960208201610c65565b601f1982820381018352601f909101166040526105c4565b6040516105b060208201610c72565b601f1982820381018352601f909101166040525b6002546040516bffffffffffffffffffffffff19606088811b8216602084015287811b821660348401527fffff00000000000000000000000000000000000000000000000000000000000060f08d901b1660488401529290921b909116604a820152909150600090605e01604051602081830303815290604052805190602001209050808251602084016000f592508260036000876001600160a01b03166001600160a01b031681526020019081526020016000206000866001600160a01b03166001600160a01b0316815260200190815260200160002060008a61ffff1661ffff16815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508260036000866001600160a01b03166001600160a01b031681526020019081526020016000206000876001600160a01b03166001600160a01b0316815260200190815260200160002060008a61ffff1661ffff16815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061076a858588610b0c565b6001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0385811691909117909155600254811690861614610875576002546040517fb1ffa5820000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152868116602483015261ffff8b16604483015291821660648201529084169063b1ffa58290608401600060405180830381600087803b15801561085857600080fd5b505af115801561086c573d6000803e3d6000fd5b505050506108fc565b6040517f7ebef5290000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152858116602483015261ffff8a166044830152841690637ebef52990606401600060405180830381600087803b1580156108e357600080fd5b505af11580156108f7573d6000803e3d6000fd5b505050505b600154604080516001600160a01b03868116825261ffff8c1660208301529181019290925280861691908716907f510cf15a092d0302f720eeedd34384cb979a59f85143c19f100768c260bc3f5f9060600160405180910390a3509098975050505050505050565b606060008361097260015490565b61097c9190610ed2565b83111561099a578361098d60015490565b6109979190610ed2565b92505b8267ffffffffffffffff8111156109b3576109b3610ee9565b6040519080825280602002602001820160405280156109dc578160200160208202803683370190505b50915060005b83811015610a5e5760016109f68287610eff565b81548110610a0657610a06610f17565b9060005260206000200160009054906101000a90046001600160a01b0316838281518110610a3657610a36610f17565b6001600160a01b0390921660209283029190910190910152610a5781610f2d565b90506109e2565b50610a698385610eff565b90509250929050565b6000805b60088161ffff161015610ad95760008161ffff1660088110610a9a57610a9a610f17565b601091828204019190066002029054906101000a900461ffff1661ffff168361ffff161415610ac95792915050565b610ad281610f48565b9050610a76565b506040517fcd3cb2bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383811660009081526004602090815260408083209386168352929052818120825161010081019384905291926008908285855b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411610b475790505050505050905060008261ffff1660088110610b9d57610b9d610f17565b601091828204019190066002029054906101000a900461ffff16818361ffff1660088110610bcd57610bcd610f17565b61ffff909216602092830291909101526001600160a01b0380861660009081526004835260408082209287168252919092529020610c0d90826008610c7f565b506001600160a01b038084166000908152600460209081526040808320938816835292905220610c3f90826008610c7f565b5050505050565b6040518061010001604052806008906020820280368337509192915050565b61256d80610f6b83390190565b61283a806134d883390190565b600183019183908215610d055791602002820160005b83821115610cd557835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302610c95565b8015610d035782816101000a81549061ffff0219169055600201602081600101049283019260010302610cd5565b505b50610d11929150610d15565b5090565b5b80821115610d115760008155600101610d16565b80356001600160a01b0381168114610d4157600080fd5b919050565b600080600060608486031215610d5b57600080fd5b610d6484610d2a565b9250610d7260208501610d2a565b9150604084013561ffff81168114610d8957600080fd5b809150509250925092565b600060208284031215610da657600080fd5b5035919050565b600080600060608486031215610dc257600080fd5b610dcb84610d2a565b9250610dd960208501610d2a565b9150604084013590509250925092565b60008060408385031215610dfc57600080fd5b610e0583610d2a565b9150610a6960208401610d2a565b6101008101818360005b6008811015610e4057815161ffff16835260209283019290910190600101610e1d565b50505092915050565b60008060408385031215610e5c57600080fd5b50508035926020909101359150565b604080825283519082018190526000906020906060840190828701845b82811015610ead5781516001600160a01b031684529284019290840190600101610e88565b50505092019290925292915050565b634e487b7160e01b600052601160045260246000fd5b600082821015610ee457610ee4610ebc565b500390565b634e487b7160e01b600052604160045260246000fd5b60008219821115610f1257610f12610ebc565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415610f4157610f41610ebc565b5060010190565b600061ffff80831681811415610f6057610f60610ebc565b600101939250505056fe60a0604052600160005534801561001557600080fd5b503360805260805161252a610043600039600081816103680152818161113301526113e2015261252a6000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063bc25cf77116100d8578063d6f124f01161008c578063f5298aca11610066578063f5298aca146103e0578063f6c67d8d14610408578063fff6cae91461041b57600080fd5b8063d6f124f01461039d578063ddca3f43146103a5578063e680ea2c146103cd57600080fd5b8063c1be6677116100bd578063c1be6677146102fa578063c45a015514610363578063d21220a71461038a57600080fd5b8063bc25cf77146102d4578063c12a00a8146102e757600080fd5b80632f7256381161013a5780636d9a640a116101145780636d9a640a1461029957806382e6a1c6146102ae578063b1ffa582146102c157600080fd5b80632f7256381461026057806340c10f19146102735780635247ab051461028657600080fd5b80630eb290661161016b5780630eb29066146101e957806318160ddd146102005780631f9d4db21461020957600080fd5b80630902f1ac146101875780630dfe1681146101be575b600080fd5b600754604080516001600160701b038084168252600160701b90930490921660208301526000908201526060015b60405180910390f35b6001546101d1906001600160a01b031681565b6040516001600160a01b0390911681526020016101b5565b6101f260045481565b6040519081526020016101b5565b6101f260035481565b61024861021736600461218e565b6001600160a01b0391909116600090815260096020908152604080832093835292905220546001600160801b031690565b6040516001600160801b0390911681526020016101b5565b6101f261026e3660046121ba565b610423565b6101f261028136600461218e565b61063f565b6101f261029436600461218e565b610a40565b6102ac6102a73660046121ec565b610bd3565b005b6101d16102bc36600461223a565b6110f2565b6102ac6102cf366004612257565b6113d7565b6102ac6102e23660046122ba565b6114b6565b6005546101d1906001600160a01b031681565b61033e61030836600461218e565b60096020908152600092835260408084209091529082529020805460018201546002909201546001600160801b03909116919083565b604080516001600160801b0390941684526020840192909252908201526060016101b5565b6101d17f000000000000000000000000000000000000000000000000000000000000000081565b6002546101d1906001600160a01b031681565b6102ac6115e7565b6002546103ba90600160a01b900461ffff1681565b60405161ffff90911681526020016101b5565b6101f26103db36600461218e565b61178b565b6103f36103ee3660046122d7565b6117db565b604080519283526020830191909152016101b5565b6006546101d1906001600160a01b031681565b6102ac611c8d565b600154600654604080517fd21220a700000000000000000000000000000000000000000000000000000000815290516000936001600160a01b0390811693169163d21220a79160048083019260209291908290030181865afa15801561048d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b1919061230c565b6001600160a01b0316141561057e576006546001546002546001600160a01b0392831692633ddac9539216906103e890600160a01b900461ffff166104f68a8a61233f565b6105009190612357565b61050a9190612376565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015610553573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105779190612398565b9050610637565b6006546002546001600160a01b0391821691633ddac95391908116906103e890600160a01b900461ffff166105b3888861233f565b6105bd9190612357565b6105c79190612376565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015610610573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106349190612398565b90505b949350505050565b600080546001146106845760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064015b60405180910390fd5b600260009081556001600160a01b0384168152600960209081526040808320858452909152902054839083906001600160801b0316156107415760006106cd8383600854611db7565b9050801561073b576001600160a01b03831660009081526009602090815260408083208584529091528120600101805483929061070b90849061233f565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b5061076c565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b60075460009081906001600160701b0380821691600160701b9004166001546040516370a0823160e01b81523060048201529294509092506000916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156107d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fd9190612398565b6002546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa15801561084b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086f9190612398565b905060006108866001600160701b038616846123b1565b9050600061089d6001600160701b038616846123b1565b600354909150600090806108d7576103e86108c06108bb8587612357565b611e39565b6108ca91906123b1565b6103e86003559150610926565b610923886001600160701b0316600354866108f29190612357565b6108fc9190612376565b886001600160701b0316600354866109149190612357565b61091e9190612376565b611ea9565b91505b8161095d576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038d1660009081526009602090815260408083208f8452909152812080548492906109999084906001600160801b03166123c8565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550816003546109cb919061233f565b6003556109d88686611ec1565b806109e5576109e5611f84565b60408051858152602081018590526001600160a01b038f16917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a25098505050505050505b5050600160005592915050565b60008054600114610a805760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161067b565b60026000908155338082526009602090815260408084208685529091529091205483906001600160801b031615610b34576000610ac08383600854611db7565b90508015610b2e576001600160a01b038316600090815260096020908152604080832085845290915281206001018054839290610afe90849061233f565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b50610b5f565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b33600090815260096020908152604080832087845290915290206001015492508215610a3357336000908152600960209081526040808320878452909152812060010181905560048054859290610bb79084906123b1565b9091555050600554610a33906001600160a01b03168685611fb7565b600054600114610c125760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161067b565b600260005582158015610c23575081155b15610c5a576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546001600160701b0380821691600160701b9004168185101580610c895750806001600160701b03168410155b15610ca75760405163bb55fd2760e01b815260040160405180910390fd5b60015460025460009182916001600160a01b0391821691908116908716821480610ce25750806001600160a01b0316876001600160a01b0316145b15610d19576040517f1e4ec46b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8815610d2a57610d2a82888b611fb7565b8715610d3b57610d3b81888a611fb7565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610d7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da39190612398565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa158015610dea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0e9190612398565b92505050600087856001600160701b0316610e2991906123b1565b8311610e36576000610e53565b610e49886001600160701b0387166123b1565b610e5390846123b1565b90506000610e6a886001600160701b0387166123b1565b8311610e77576000610e94565b610e8a886001600160701b0387166123b1565b610e9490846123b1565b905081158015610ea2575080155b15610ed9576040517f098fb56100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051838152602081018390529081018a9052606081018990526001600160a01b0388169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a36000610f3c8a848b85610423565b90506103e8811015610f7a576040517ff570cd7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480546005546040516370a0823160e01b8152309381019390935283926001600160a01b03909116906370a0823190602401602060405180830381865afa158015610fca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fee9190612398565b610ff891906123b1565b1015611030576040517f025dbdd400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110466001600160701b03808816908916612357565b6110508587612357565b1015611088576040517fa932492f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110928585611ec1565b60006127106110a383612134612357565b6110ad9190612376565b905060006110bb82846123b1565b90506110c682612126565b6005546110df906001600160a01b031661dead83611fb7565b5050600160005550505050505050505050565b604080518082019091526001546001600160a01b039081168252600254166020820152600090815b60028110156113d0576005546000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116916309175fa7911685856002811061116e5761116e6123f3565b60200201516040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152600a6044820152606401602060405180830381865afa1580156111c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e9919061230c565b90506001600160a01b0381166111ff57506113c0565b6000819050806001600160a01b031663f6c67d8d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611242573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611266919061230c565b6001600160a01b031663fcfedfb16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c79190612409565b156112d35750506113c0565b6000816001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611313573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611337919061242b565b50509050866001600160701b0316816001600160701b0316106113bc57816001600160a01b031663f6c67d8d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611392573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b6919061230c565b95508096505b5050505b6113c981612476565b905061111a565b5050919050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611439576040517f015551dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180546001600160a01b0395861673ffffffffffffffffffffffffffffffffffffffff19918216179091556002805461ffff909416600160a01b027fffffffffffffffffffff00000000000000000000000000000000000000000000909416948616949094179290921790925560058054929093169116179055565b6000546001146114f55760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161067b565b6002600081905560015490546007546040516370a0823160e01b81523060048201526001600160a01b03938416939092169161159591849186916001600160701b03169083906370a08231906024015b602060405180830381865afa158015611562573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115869190612398565b61159091906123b1565b611fb7565b6007546040516370a0823160e01b81523060048201526115dd9183918691600160701b90046001600160701b0316906001600160a01b038416906370a0823190602401611545565b5050600160005550565b60065460009081906001600160a01b0316156116de57600660009054906101000a90046001600160a01b03166001600160a01b031663a8aa1b316040518163ffffffff1660e01b8152600401602060405180830381865afa158015611650573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611674919061230c565b9150816001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156116b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d8919061242b565b50909150505b60006116e9826110f2565b90506001600160a01b03811661171257604051639989e18760e01b815260040160405180910390fd5b6006546001600160a01b038281169116141561175a576040517febd9054000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03929092169190911790555050565b6008546000908161179d858584611db7565b6001600160a01b03861660009081526009602090815260408083208884529091529020600101549091506117d290829061233f565b95945050505050565b60008060005460011461181d5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161067b565b60026000908155338082526009602090815260408084208885529091529091205485906001600160801b0316156118d157600061185d8383600854611db7565b905080156118cb576001600160a01b03831660009081526009602090815260408083208584529091528120600101805483929061189b90849061233f565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b506118fc565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b6001546002546040516370a0823160e01b81523060048201526001600160a01b03928316929091169060009083906370a0823190602401602060405180830381865afa158015611950573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119749190612398565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156119be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e29190612398565b3360009081526009602090815260408083208e84529091529020549091506001600160801b0316891115611a295760405163bb55fd2760e01b815260040160405180910390fd5b3360009081526009602090815260408083208d8452909152812080548b9290611a5c9084906001600160801b0316612491565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508860001415611aa25760405163bb55fd2760e01b815260040160405180910390fd5b600354600081611ab2858d612357565b611abc9190612376565b9050600082611acb858e612357565b611ad59190612376565b90508b600354611ae591906123b1565b600355811580611af3575080155b15611b2a576040517f749383ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611b35878f84611fb7565b611b40868f83611fb7565b6040516370a0823160e01b81523060048201526001600160a01b038816906370a0823190602401602060405180830381865afa158015611b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba89190612398565b6040516370a0823160e01b81523060048201529095506001600160a01b038716906370a0823190602401602060405180830381865afa158015611bef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c139190612398565b9350611c1f8585611ec1565b8d6001600160a01b0316336001600160a01b03167fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d819364968484604051611c6d929190918252602082015260400190565b60405180910390a36001600055909d909c509a5050505050505050505050565b600054600114611ccc5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161067b565b60026000556001546040516370a0823160e01b8152306004820152611db0916001600160a01b0316906370a0823190602401602060405180830381865afa158015611d1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3f9190612398565b6002546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611d87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dab9190612398565b611ec1565b6001600055565b6001600160a01b03831660009081526009602090815260408083208584529091528120600201548190611dea90846123b1565b6001600160a01b0386166000908152600960209081526040808320888452909152902054909150670de0b6b3a764000090611e2f9083906001600160801b0316612357565b6117d29190612376565b60006003821115611e9a5750806000611e53600283612376565b611e5e90600161233f565b90505b81811015611e9457905080600281611e798186612376565b611e83919061233f565b611e8d9190612376565b9050611e61565b50919050565b8115611ea4575060015b919050565b6000818310611eb85781611eba565b825b9392505050565b6001600160701b03821180611edc57506001600160701b0381115b15611f13576040517f89560ca100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780546001600160701b03838116600160701b9081026001600160e01b0319909316868316179290921792839055604080518483168152929093041660208201527f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1910160405180910390a15050565b611f8c6115e7565b6006546001600160a01b0316611fb557604051639989e18760e01b815260040160405180910390fd5b565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161204191906124b9565b6000604051808303816000865af19150503d806000811461207e576040519150601f19603f3d011682016040523d82523d6000602084013e612083565b606091505b50915091508180156120ad5750805115806120ad5750808060200190518101906120ad9190612409565b61211f5760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c656400000000000000000000000000000000000000606482015260840161067b565b5050505050565b6103e860035461213691906123b1565b612148670de0b6b3a764000083612357565b6121529190612376565b60085461215f919061233f565b60085560045461217090829061233f565b60045550565b6001600160a01b038116811461218b57600080fd5b50565b600080604083850312156121a157600080fd5b82356121ac81612176565b946020939093013593505050565b600080600080608085870312156121d057600080fd5b5050823594602084013594506040840135936060013592509050565b60008060006060848603121561220157600080fd5b8335925060208401359150604084013561221a81612176565b809150509250925092565b6001600160701b038116811461218b57600080fd5b60006020828403121561224c57600080fd5b8135611eba81612225565b6000806000806080858703121561226d57600080fd5b843561227881612176565b9350602085013561228881612176565b9250604085013561ffff8116811461229f57600080fd5b915060608501356122af81612176565b939692955090935050565b6000602082840312156122cc57600080fd5b8135611eba81612176565b6000806000606084860312156122ec57600080fd5b83356122f781612176565b95602085013595506040909401359392505050565b60006020828403121561231e57600080fd5b8151611eba81612176565b634e487b7160e01b600052601160045260246000fd5b6000821982111561235257612352612329565b500190565b600081600019048311821515161561237157612371612329565b500290565b60008261239357634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156123aa57600080fd5b5051919050565b6000828210156123c3576123c3612329565b500390565b60006001600160801b038083168185168083038211156123ea576123ea612329565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561241b57600080fd5b81518015158114611eba57600080fd5b60008060006060848603121561244057600080fd5b835161244b81612225565b602085015190935061245c81612225565b604085015190925063ffffffff8116811461221a57600080fd5b600060001982141561248a5761248a612329565b5060010190565b60006001600160801b03838116908316818110156124b1576124b1612329565b039392505050565b6000825160005b818110156124da57602081860181015185830152016124c0565b818111156124e9576000828501525b50919091019291505056fea2646970667358221220ed2b296666058c99a67fe8c1e2c2ec013d6cb863394d87553af151363540861f64736f6c634300080a003360a0604052600160005534801561001557600080fd5b50336080526080516127fe61003c6000396000818161034e015261103501526127fe6000f3fe60806040523480156200001157600080fd5b50600436106200016c5760003560e01c80637ebef52911620000dd578063ddca3f43116200008b578063f5298aca116200006e578063f5298aca14620003c5578063f6c67d8d14620003f2578063fff6cae9146200040657600080fd5b8063ddca3f431462000384578063e680ea2c14620003ae57600080fd5b8063c1be667711620000c0578063c1be667714620002db578063c45a01551462000348578063d21220a7146200037057600080fd5b80637ebef52914620002ad578063bc25cf7714620002c457600080fd5b80631f9d4db2116200013b5780635247ab05116200011e5780635247ab0514620002735780635a3d5493146200028a5780636d9a640a146200029457600080fd5b80631f9d4db2146200020157806340c10f19146200025c57600080fd5b80630902f1ac14620001715780630dfe168114620001b15780630eb2906614620001de57806318160ddd14620001f7575b600080fd5b600754604080516001600160701b038084168252600160701b8404166020820152600160e01b90920463ffffffff16908201526060015b60405180910390f35b600154620001c5906001600160a01b031681565b6040516001600160a01b039091168152602001620001a8565b620001e860055481565b604051908152602001620001a8565b620001e860035481565b620002436200021236600462001f12565b6001600160a01b0391909116600090815260096020908152604080832093835292905220546001600160801b031690565b6040516001600160801b039091168152602001620001a8565b620001e86200026d36600462001f12565b62000410565b620001e86200028436600462001f12565b6200087e565b620001e860045481565b620002ab620002a536600462001f3f565b62000a1f565b005b620002ab620002be36600462001f77565b6200102a565b620002ab620002d536600462001fcb565b620010f9565b62000322620002ec36600462001f12565b60096020908152600092835260408084209091529082529020805460018201546002909201546001600160801b03909116919083565b604080516001600160801b039094168452602084019290925290820152606001620001a8565b620001c57f000000000000000000000000000000000000000000000000000000000000000081565b600254620001c5906001600160a01b031681565b6002546200039a90600160a01b900461ffff1681565b60405161ffff9091168152602001620001a8565b620001e8620003bf36600462001f12565b62001283565b620003dc620003d636600462001fe9565b620012d7565b60408051928352602083019190915201620001a8565b600654620001c5906001600160a01b031681565b620002ab62001827565b60008054600114620004565760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064015b60405180910390fd5b600260009081556001600160a01b0384168152600960209081526040808320858452909152902054839083906001600160801b0316156200051a576000620004a2838360085462001982565b9050801562000513576001600160a01b038316600090815260096020908152604080832085845290915281206001018054839290620004e390849062002035565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b5062000545565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b600080620005776007546001600160701b0380821692600160701b83049091169163ffffffff600160e01b9091041690565b506005546001546040516370a0823160e01b815230600482015293955091935060009290916001600160a01b0316906370a0823190602401602060405180830381865afa158015620005cd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005f3919062002050565b620005ff91906200206a565b6002546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156200064e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000674919062002050565b905060006200068d6001600160701b038616846200206a565b90506000620006a66001600160701b038616846200206a565b60035490915060009080620006e8576103e8620006ce620006c8858762002084565b62001a0a565b620006da91906200206a565b6103e8600355915062000741565b6200073e886001600160701b03166003548662000706919062002084565b620007129190620020bc565b886001600160701b0316600354866200072c919062002084565b620007389190620020bc565b62001a88565b91505b8162000779576040517fd226f9d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038d1660009081526009602090815260408083208f845290915281208054849290620007b79084906001600160801b0316620020d3565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555081600354620007eb919062002035565b600355620007fc86868a8a62001aa2565b806200082357600254600160a01b900461ffff16600a141562000823576200082362001c54565b60408051858152602081018590526001600160a01b038f16917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a25098505050505050505b5050600160005592915050565b60008054600114620008c05760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016200044d565b60026000908155338082526009602090815260408084208685529091529091205483906001600160801b0316156200097b57600062000903838360085462001982565b9050801562000974576001600160a01b0383166000908152600960209081526040808320858452909152812060010180548392906200094490849062002035565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b50620009a6565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b33600090815260096020908152604080832087845290915290206001015492508215620008715733600090815260096020908152604080832087845290915281206001018190556005805485929062000a019084906200206a565b909155505060015462000871906001600160a01b0316868562001cf6565b60005460011462000a605760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016200044d565b60026000558215801562000a72575081155b1562000aaa576040517f42301c2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008062000adc6007546001600160701b0380821692600160701b83049091169163ffffffff600160e01b9091041690565b5091509150816001600160701b03168510158062000b035750806001600160701b03168410155b1562000b225760405163bb55fd2760e01b815260040160405180910390fd5b60015460025460009182916001600160a01b039182169190811690871682148062000b5e5750806001600160a01b0316876001600160a01b0316145b1562000b96576040517f1e4ec46b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b881562000baa5762000baa82888b62001cf6565b871562000bbe5762000bbe81888a62001cf6565b6005546040516370a0823160e01b81523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa15801562000c06573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c2c919062002050565b62000c3891906200206a565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa15801562000c80573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ca6919062002050565b92506000905062000cc1896001600160701b0388166200206a565b841162000cd057600062000cf1565b62000ce5896001600160701b0388166200206a565b62000cf190856200206a565b9050600062000d0a896001600160701b0388166200206a565b841162000d1957600062000d3a565b62000d2e896001600160701b0388166200206a565b62000d3a90856200206a565b90508115801562000d49575080155b1562000d81576040517f098fb56100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051838152602081018390529081018b9052606081018a90526001600160a01b0389169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a360025460009062000df590600160a01b900461ffff166103e86200206a565b60025462000e0f90600160a01b900461ffff168d62002084565b62000e1b9190620020bc565b60025462000e3790600160a01b900461ffff166103e862002035565b60025462000e5190600160a01b900461ffff168662002084565b62000e5d9190620020bc565b62000e69919062002035565b90506103e881101562000ea8576040517ff570cd7700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000eb481876200206a565b955062000ece6001600160701b03808916908a1662002084565b62000eda868862002084565b101562000f13576040517fa932492f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000f2186868a8a62001aa2565b600254600160a01b900461ffff16600a141562000fcb57600654600480546007546040517fcebab53d00000000000000000000000000000000000000000000000000000000815292830191909152600160e01b900463ffffffff1660248201526001600160a01b039091169063cebab53d90604401600060405180830381600087803b15801562000fb157600080fd5b505af115801562000fc6573d6000803e3d6000fd5b505050505b600061271062000fde8361213462002084565b62000fea9190620020bc565b9050600062000ffa82846200206a565b9050620010078262001e5a565b620010168661dead8362001cf6565b505060016000555050505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146200108d576040517f015551dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180546001600160a01b0394851673ffffffffffffffffffffffffffffffffffffffff199091161790556002805461ffff909216600160a01b027fffffffffffffffffffff000000000000000000000000000000000000000000009092169290931691909117179055565b6000546001146200113a5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016200044d565b6002600081905560015490546005546007546040516370a0823160e01b81523060048201526001600160a01b039485169490931692620011f192859287926001600160701b039091169084906370a0823190602401602060405180830381865afa158015620011ad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011d3919062002050565b620011df91906200206a565b620011eb91906200206a565b62001cf6565b6007546040516370a0823160e01b8152306004820152620012799183918691600160701b90046001600160701b0316906001600160a01b038416906370a0823190602401602060405180830381865afa15801562001253573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011df919062002050565b5050600160005550565b600854600090816200129785858462001982565b6001600160a01b0386166000908152600960209081526040808320888452909152902060010154909150620012ce90829062002035565b95945050505050565b6000806000546001146200131b5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016200044d565b60026000908155338082526009602090815260408084208885529091529091205485906001600160801b031615620013d65760006200135e838360085462001982565b90508015620013cf576001600160a01b0383166000908152600960209081526040808320858452909152812060010180548392906200139f90849062002035565b90915550506008546001600160a01b03841660009081526009602090815260408083208684529091529020600201555b5062001401565b6008546001600160a01b03831660009081526009602090815260408083208584529091529020600201555b600080620014336007546001600160701b0380821692600160701b83049091169163ffffffff600160e01b9091041690565b506005546001546040516370a0823160e01b815230600482015293955091935060009290916001600160a01b0316906370a0823190602401602060405180830381865afa15801562001489573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620014af919062002050565b620014bb91906200206a565b6002546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156200150a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001530919062002050565b3360009081526009602090815260408083208e84529091529020549091506001600160801b0316891115620015785760405163bb55fd2760e01b815260040160405180910390fd5b3360009081526009602090815260408083208d8452909152812080548b9290620015ad9084906001600160801b031662002101565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508860001415620015f45760405163bb55fd2760e01b815260040160405180910390fd5b60035460008162001606858d62002084565b620016129190620020bc565b905060008262001623858e62002084565b6200162f9190620020bc565b90508b6003546200164191906200206a565b60035581158062001650575080155b1562001688576040517f749383ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154620016a1906001600160a01b03168f8462001cf6565b600254620016ba906001600160a01b03168f8362001cf6565b6005546001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801562001706573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200172c919062002050565b6200173891906200206a565b6002546040516370a0823160e01b81523060048201529196506001600160a01b0316906370a0823190602401602060405180830381865afa15801562001782573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017a8919062002050565b9350620017b88585898962001aa2565b8d6001600160a01b0316336001600160a01b03167fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496848460405162001807929190918252602082015260400190565b60405180910390a36001600055909d909c509a5050505050505050505050565b600054600114620018685760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016200044d565b60026000556005546001546040516370a0823160e01b81523060048201526200197b92916001600160a01b0316906370a0823190602401602060405180830381865afa158015620018bd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018e3919062002050565b620018ef91906200206a565b6002546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801562001938573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200195e919062002050565b6007546001600160701b0380821691600160701b90041662001aa2565b6001600055565b6001600160a01b03831660009081526009602090815260408083208584529091528120600201548190620019b790846200206a565b6001600160a01b0386166000908152600960209081526040808320888452909152902054909150670de0b6b3a764000090620019fe9083906001600160801b031662002084565b620012ce9190620020bc565b6000600382111562001a78575080600062001a27600283620020bc565b62001a3490600162002035565b90505b8181101562001a725790508060028162001a528186620020bc565b62001a5e919062002035565b62001a6a9190620020bc565b905062001a37565b50919050565b811562001a83575060015b919050565b600081831062001a99578162001a9b565b825b9392505050565b6001600160701b0384118062001abe57506001600160701b0383115b1562001af6576040517f89560ca100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062001b09640100000000426200212c565b60075490915063ffffffff600160e01b909104811682039081161580159062001b3a57506001600160701b03841615155b801562001b4f57506001600160701b03831615155b1562001ba4578063ffffffff1662001b7c8462001b6c8762001eb4565b6001600160e01b03169062001ed5565b6001600160e01b031662001b91919062002084565b60045462001ba0919062002035565b6004555b6007805463ffffffff8416600160e01b026001600160e01b036001600160701b03898116600160701b9081027fffffffff000000000000000000000000000000000000000000000000000000009095168c83161794909417918216831794859055604080519382169282169290921783529290930490911660208201527f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1910160405180910390a1505050505050565b6002546004546007546040516001600160a01b0390931692600160e01b90910463ffffffff169062001c869062001eec565b6001600160a01b039093168352602083019190915263ffffffff166040820152606001604051809103906000f08015801562001cc6573d6000803e3d6000fd5b506006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b03167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169162001d6d919062002143565b6000604051808303816000865af19150503d806000811462001dac576040519150601f19603f3d011682016040523d82523d6000602084013e62001db1565b606091505b509150915081801562001ddf57508051158062001ddf57508080602001905181019062001ddf919062002181565b62001e535760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c65640000000000000000000000000000000000000060648201526084016200044d565b5050505050565b6103e860035462001e6c91906200206a565b62001e80670de0b6b3a76400008362002084565b62001e8c9190620020bc565b60085462001e9b919062002035565b60085560055462001eae90829062002035565b60055550565b600062001ecf600160701b6001600160701b038416620021a5565b92915050565b600062001a9b6001600160701b03831684620021d7565b6105c8806200220183390190565b80356001600160a01b038116811462001a8357600080fd5b6000806040838503121562001f2657600080fd5b62001f318362001efa565b946020939093013593505050565b60008060006060848603121562001f5557600080fd5b833592506020840135915062001f6e6040850162001efa565b90509250925092565b60008060006060848603121562001f8d57600080fd5b62001f988462001efa565b925062001fa86020850162001efa565b9150604084013561ffff8116811462001fc057600080fd5b809150509250925092565b60006020828403121562001fde57600080fd5b62001a9b8262001efa565b60008060006060848603121562001fff57600080fd5b6200200a8462001efa565b95602085013595506040909401359392505050565b634e487b7160e01b600052601160045260246000fd5b600082198211156200204b576200204b6200201f565b500190565b6000602082840312156200206357600080fd5b5051919050565b6000828210156200207f576200207f6200201f565b500390565b6000816000190483118215151615620020a157620020a16200201f565b500290565b634e487b7160e01b600052601260045260246000fd5b600082620020ce57620020ce620020a6565b500490565b60006001600160801b03808316818516808303821115620020f857620020f86200201f565b01949350505050565b60006001600160801b03838116908316818110156200212457620021246200201f565b039392505050565b6000826200213e576200213e620020a6565b500690565b6000825160005b818110156200216657602081860181015185830152016200214a565b8181111562002176576000828501525b509190910192915050565b6000602082840312156200219457600080fd5b8151801515811462001a9b57600080fd5b60006001600160e01b0380831681851681830481118215151615620021ce57620021ce6200201f565b02949350505050565b60006001600160e01b0380841680620021f457620021f4620020a6565b9216919091049291505056fe608060405234801561001057600080fd5b506040516105c83803806105c883398101604081905261002f9161008b565b600080546001600160a01b039094166001600160a01b031994851617905560018054909316331783556002919091556003805463ffffffff90921663ffffffff199092169190911790556005805460ff191690911790556100e3565b6000806000606084860312156100a057600080fd5b83516001600160a01b03811681146100b757600080fd5b60208501516040860151919450925063ffffffff811681146100d857600080fd5b809150509250925092565b6104d6806100f26000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063b4d1d79511610076578063cebab53d1161005b578063cebab53d1461015b578063d21220a714610170578063fcfedfb11461018357600080fd5b8063b4d1d7951461012d578063c5700a021461013657600080fd5b80633ddac953146100a85780635a3d5493146100ce5780635e6aaf2c146100d7578063a8aa1b3114610102575b600080fd5b6100bb6100b63660046103ca565b6101a0565b6040519081526020015b60405180910390f35b6100bb60025481565b6004546100ea906001600160e01b031681565b6040516001600160e01b0390911681526020016100c5565b600154610115906001600160a01b031681565b6040516001600160a01b0390911681526020016100c5565b6100bb610e1081565b6003546101469063ffffffff1681565b60405163ffffffff90911681526020016100c5565b61016e610169366004610402565b610238565b005b600054610115906001600160a01b031681565b6005546101909060ff1681565b60405190151581526020016100c5565b600080546001600160a01b03848116911614156102005760408051602081019091526004546001600160e01b031681526101e5906101de908461030e565b5160701c90565b71ffffffffffffffffffffffffffffffffffff169050610232565b6040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b92915050565b6001546001600160a01b0316331461024f57600080fd5b60035463ffffffff908116820390610e10908216101580610272575060055460ff165b156103095760405180602001604052808263ffffffff1660025486038161029b5761029b61043b565b046001600160e01b039081169091529051600480547fffffffff00000000000000000000000000000000000000000000000000000000169190921617905560028390556003805463ffffffff191663ffffffff841617905560055460ff1615610309576005805460ff191690555b505050565b604080516020810190915260008152600082158061034b575083516001600160e01b03168361033d8183610451565b9250610349908361047e565b145b6103b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4669786564506f696e743a3a6d756c3a206f766572666c6f7700000000000000604482015260640160405180910390fd5b60408051602081019091529081529392505050565b600080604083850312156103dd57600080fd5b82356001600160a01b03811681146103f457600080fd5b946020939093013593505050565b6000806040838503121561041557600080fd5b82359150602083013563ffffffff8116811461043057600080fd5b809150509250929050565b634e487b7160e01b600052601260045260246000fd5b600081600019048311821515161561047957634e487b7160e01b600052601160045260246000fd5b500290565b60008261049b57634e487b7160e01b600052601260045260246000fd5b50049056fea26469706673582212205f6b4dad031f2b09ee010b27cf8d81fe590b4af24b73d5b60e7c163c7aeb478764736f6c634300080a0033a2646970667358221220701ca9581e1af984f165ca7011f34f579caa8cef9f23f2d2213936d8e467e3b464736f6c634300080a0033a26469706673582212201bacf5617855e13b83230eea19c90ecb28b0139049748a47fa97384dd9d4c3be64736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000040df0c3bbaae5ea3a509d8f2aa9e086776c98e6c
-----Decoded View---------------
Arg [0] : _antfarmToken (address): 0x40DF0C3BBAAE5Ea3A509d8F2aa9E086776C98E6c
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000040df0c3bbaae5ea3a509d8f2aa9e086776c98e6c
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.