Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- LinkswapFactory
- Optimization enabled
- true
- Compiler version
- v0.6.6+commit.6c089d02
- Optimization runs
- 200
- EVM Version
- istanbul
- Verified at
- 2026-03-04T14:29:21.095255Z
Constructor Arguments
0000000000000000000000000389d755c1833c9b350d4e8b619eae16defc1cba000000000000000000000000e69a81b96fbf5cb6cae95d2ce5323eff2ba0eae4000000000000000000000000dfa5e7989c98446ffea622266e18df563e8598720000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000045d964b8000000000000000000000000000000000000000000000000000000002e90edd00000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000746a52880000000000000000000000000000000000000000000000000000000246139ca8000000000000000000000000000000000000000000000000000000000000093a800000000000000000000000000000000000000000000000000000000000278d00000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000028cb7e841ee97947a86b06fa4090c8451f64c0be
Arg [0] (address) : 0x0389d755c1833c9b350d4e8b619eae16defc1cba
Arg [1] (address) : 0xe69a81b96fbf5cb6cae95d2ce5323eff2ba0eae4
Arg [2] (address) : 0xdfa5e7989c98446ffea622266e18df563e859872
Arg [3] (uint256) : 250000000000
Arg [4] (uint256) : 300000000000
Arg [5] (uint256) : 200000000000
Arg [6] (uint256) : 100000
Arg [7] (uint256) : 500000000000
Arg [8] (uint256) : 2500000000000
Arg [9] (uint256) : 604800
Arg [10] (uint256) : 2592000
Arg [11] (uint256) : 500000
Arg [12] (address) : 0x514910771af9ca656af840dff83e8264ecf986ca
Arg [13] (address) : 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [14] (address) : 0x28cb7e841ee97947a86b06fa4090c8451f64c0be
/Users/kroll/Dev/LinkDeployment1/contracts/LinkswapFactory.sol
pragma solidity 0.6.6;
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "./interfaces/ILinkswapFactory.sol";
import "./interfaces/ILinkswapPriceOracle.sol";
import "./libraries/SafeMathLinkswap.sol";
import "./libraries/TransferHelper.sol";
import "./LinkswapPair.sol";
contract LinkswapFactory is ILinkswapFactory, ReentrancyGuard {
using SafeMathLinkswap for uint256;
address public immutable override LINK;
address public immutable override WETH;
address public immutable override YFL;
address public override governance;
address public override treasury;
address public override priceOracle;
uint256 public override linkListingFeeInUsd;
uint256 public override wethListingFeeInUsd;
uint256 public override yflListingFeeInUsd;
uint256 public override treasuryListingFeeShare = 1000000;
uint256 public override minListingLockupAmountInUsd;
uint256 public override targetListingLockupAmountInUsd;
uint256 public override minListingLockupPeriod;
uint256 public override targetListingLockupPeriod;
uint256 public override lockupAmountListingFeeDiscountShare;
uint256 public override defaultLinkTradingFeePercent = 2500; // 0.2500%
uint256 public override defaultNonLinkTradingFeePercent = 3000; // 0.3000%
uint256 public override treasuryProtocolFeeShare = 1000000; // 100%
uint256 public override protocolFeeFractionInverse; // protocol fee off initially
uint256 public override maxSlippagePercent;
uint256 public override maxSlippageBlocks = 1;
mapping(address => mapping(address => address)) public override getPair;
mapping(address => mapping(address => bool)) public override approvedPair;
address[] public override allPairs;
modifier onlyGovernance() {
require(msg.sender == governance);
_;
}
constructor(
address _governance,
address _treasury,
address _priceOracle,
uint256 _linkListingFeeInUsd,
uint256 _wethListingFeeInUsd,
uint256 _yflListingFeeInUsd,
uint256 _treasuryListingFeeShare,
uint256 _minListingLockupAmountInUsd,
uint256 _targetListingLockupAmountInUsd,
uint256 _minListingLockupPeriod,
uint256 _targetListingLockupPeriod,
uint256 _lockupAmountListingFeeDiscountShare,
address _linkToken,
address _WETH,
address _yflToken
) public {
governance = _governance;
treasury = _treasury;
priceOracle = _priceOracle;
linkListingFeeInUsd = _linkListingFeeInUsd;
wethListingFeeInUsd = _wethListingFeeInUsd;
yflListingFeeInUsd = _yflListingFeeInUsd;
treasuryListingFeeShare = _treasuryListingFeeShare;
_setTargetListingLockupAmountInUsd(_targetListingLockupAmountInUsd);
_setMinListingLockupAmountInUsd(_minListingLockupAmountInUsd);
_setTargetListingLockupPeriod(_targetListingLockupPeriod);
_setMinListingLockupPeriod(_minListingLockupPeriod);
lockupAmountListingFeeDiscountShare = _lockupAmountListingFeeDiscountShare;
LINK = _linkToken;
WETH = _WETH;
YFL = _yflToken;
}
function allPairsLength() external view override returns (uint256) {
return allPairs.length;
}
function _validatePair(address tokenA, address tokenB) private view returns (address token0, address token1) {
require(tokenA != tokenB);
(token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0));
require(getPair[token0][token1] == address(0)); // single check is sufficient
}
function _createPair(address token0, address token1) private returns (address pair) {
{
bytes memory bytecode = type(LinkswapPair).creationCode;
bytes32 salt = keccak256(abi.encodePacked(token0, token1));
assembly {
pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
}
}
LinkswapPair(pair).initialize(
token0,
token1,
token0 == address(LINK) || token1 == address(LINK)
? defaultLinkTradingFeePercent
: defaultNonLinkTradingFeePercent
);
getPair[token0][token1] = pair;
getPair[token1][token0] = pair; // populate mapping in the reverse direction
allPairs.push(pair);
emit PairCreated(token0, token1, pair, allPairs.length);
}
function approvePairViaGovernance(address tokenA, address tokenB) external override onlyGovernance nonReentrant {
(address token0, address token1) = _validatePair(tokenA, tokenB);
approvedPair[token0][token1] = true;
}
function _payListingFee(
address listingFeeToken,
uint256 lockupAmountInUsd,
uint256 lockupPeriod
) private {
require(listingFeeToken == LINK || listingFeeToken == WETH || listingFeeToken == YFL);
uint256 listingFeeTokenAmount;
if (listingFeeToken == LINK) {
listingFeeTokenAmount = ILinkswapPriceOracle(priceOracle).calculateTokenAmountFromUsdAmount(
LINK,
linkListingFeeInUsd
);
} else if (listingFeeToken == WETH) {
listingFeeTokenAmount = ILinkswapPriceOracle(priceOracle).calculateTokenAmountFromUsdAmount(
WETH,
wethListingFeeInUsd
);
} else if (listingFeeToken == YFL) {
ILinkswapPriceOracle(priceOracle).update();
listingFeeTokenAmount = ILinkswapPriceOracle(priceOracle).calculateTokenAmountFromUsdAmount(
YFL,
yflListingFeeInUsd
);
}
uint256 discount;
if (targetListingLockupAmountInUsd > minListingLockupAmountInUsd) {
discount =
lockupAmountListingFeeDiscountShare.mul(lockupAmountInUsd.sub(minListingLockupAmountInUsd)) /
(targetListingLockupAmountInUsd.sub(minListingLockupAmountInUsd));
}
if (targetListingLockupPeriod > minListingLockupPeriod) {
discount = discount.add(
(uint256(1000000).sub(lockupAmountListingFeeDiscountShare)).mul(
lockupPeriod.sub(minListingLockupPeriod)
) / (targetListingLockupPeriod.sub(minListingLockupPeriod))
);
}
uint256 discountedListingFeeTokenAmount = listingFeeTokenAmount.mul(uint256(1000000).sub(discount)) / 1000000;
TransferHelper.safeTransferFrom(
listingFeeToken,
msg.sender,
treasury,
discountedListingFeeTokenAmount.mul(treasuryListingFeeShare) / 1000000
);
TransferHelper.safeTransferFrom(
listingFeeToken,
msg.sender,
governance,
discountedListingFeeTokenAmount.mul(uint256(1000000).sub(treasuryListingFeeShare)) / 1000000
);
}
function createPair(
address newToken,
uint256 newTokenAmount,
address lockupToken, // LINK or WETH, or part of a governance-approved pair
uint256 lockupTokenAmount,
uint256 lockupPeriod,
address listingFeeToken // can be zero address if governance-approved pair
) external override nonReentrant returns (address pair) {
require(msg.sender != governance);
require(newToken != address(0) && lockupToken != address(0));
(address token0, address token1) = _validatePair(newToken, lockupToken);
if (!approvedPair[token0][token1]) {
require(lockupToken == LINK || lockupToken == WETH);
require(lockupPeriod >= minListingLockupPeriod);
uint256 lockupAmountInUsd = ILinkswapPriceOracle(priceOracle).calculateUsdAmountFromTokenAmount(
lockupToken,
lockupTokenAmount
);
require(lockupAmountInUsd >= minListingLockupAmountInUsd);
_payListingFee(listingFeeToken, lockupAmountInUsd, lockupPeriod);
}
pair = _createPair(token0, token1);
if (!approvedPair[token0][token1] && lockupTokenAmount > 0 && lockupPeriod > 0) {
TransferHelper.safeTransferFrom(newToken, msg.sender, pair, newTokenAmount);
TransferHelper.safeTransferFrom(lockupToken, msg.sender, pair, lockupTokenAmount);
uint256 liquidity = LinkswapPair(pair).mint(msg.sender);
LinkswapPair(pair).listingLock(msg.sender, lockupPeriod, liquidity);
}
}
function setPriceOracle(address _priceOracle) external override onlyGovernance {
priceOracle = _priceOracle;
}
function setTreasury(address _treasury) external override onlyGovernance {
treasury = _treasury;
}
function setGovernance(address _governance) external override onlyGovernance {
require(_governance != address(0));
governance = _governance;
}
function setTreasuryProtocolFeeShare(uint256 _treasuryProtocolFeeShare) external override onlyGovernance {
require(_treasuryProtocolFeeShare <= 1000000);
treasuryProtocolFeeShare = _treasuryProtocolFeeShare;
}
function setProtocolFeeFractionInverse(uint256 _protocolFeeFractionInverse) external override onlyGovernance {
// max 50% of trading fee (2/1 * 1000)
require(_protocolFeeFractionInverse >= 2000 || _protocolFeeFractionInverse == 0);
protocolFeeFractionInverse = _protocolFeeFractionInverse;
}
function setLinkListingFeeInUsd(uint256 _linkListingFeeInUsd) external override onlyGovernance {
linkListingFeeInUsd = _linkListingFeeInUsd;
}
function setWethListingFeeInUsd(uint256 _wethListingFeeInUsd) external override onlyGovernance {
wethListingFeeInUsd = _wethListingFeeInUsd;
}
function setYflListingFeeInUsd(uint256 _yflListingFeeInUsd) external override onlyGovernance {
yflListingFeeInUsd = _yflListingFeeInUsd;
}
function setTreasuryListingFeeShare(uint256 _treasuryListingFeeShare) external override onlyGovernance {
require(_treasuryListingFeeShare <= 1000000);
treasuryListingFeeShare = _treasuryListingFeeShare;
}
function _setMinListingLockupAmountInUsd(uint256 _minListingLockupAmountInUsd) private {
require(_minListingLockupAmountInUsd <= targetListingLockupAmountInUsd);
if (_minListingLockupAmountInUsd > 0) {
// needs to be at least 1000 due to LinkswapPair MINIMUM_LIQUIDITY subtraction
require(_minListingLockupAmountInUsd >= 1000);
}
minListingLockupAmountInUsd = _minListingLockupAmountInUsd;
}
function setMinListingLockupAmountInUsd(uint256 _minListingLockupAmountInUsd) external override onlyGovernance {
_setMinListingLockupAmountInUsd(_minListingLockupAmountInUsd);
}
function _setTargetListingLockupAmountInUsd(uint256 _targetListingLockupAmountInUsd) private {
require(_targetListingLockupAmountInUsd >= minListingLockupAmountInUsd);
targetListingLockupAmountInUsd = _targetListingLockupAmountInUsd;
}
function setTargetListingLockupAmountInUsd(uint256 _targetListingLockupAmountInUsd)
external
override
onlyGovernance
{
_setTargetListingLockupAmountInUsd(_targetListingLockupAmountInUsd);
}
function _setMinListingLockupPeriod(uint256 _minListingLockupPeriod) private {
require(_minListingLockupPeriod <= targetListingLockupPeriod);
minListingLockupPeriod = _minListingLockupPeriod;
}
function setMinListingLockupPeriod(uint256 _minListingLockupPeriod) external override onlyGovernance {
_setMinListingLockupPeriod(_minListingLockupPeriod);
}
function _setTargetListingLockupPeriod(uint256 _targetListingLockupPeriod) private {
require(_targetListingLockupPeriod >= minListingLockupPeriod);
targetListingLockupPeriod = _targetListingLockupPeriod;
}
function setTargetListingLockupPeriod(uint256 _targetListingLockupPeriod) external override onlyGovernance {
_setTargetListingLockupPeriod(_targetListingLockupPeriod);
}
function setLockupAmountListingFeeDiscountShare(uint256 _lockupAmountListingFeeDiscountShare)
external
override
onlyGovernance
{
require(_lockupAmountListingFeeDiscountShare <= 1000000);
lockupAmountListingFeeDiscountShare = _lockupAmountListingFeeDiscountShare;
}
function setDefaultLinkTradingFeePercent(uint256 _defaultLinkTradingFeePercent) external override onlyGovernance {
// max 1%
require(_defaultLinkTradingFeePercent <= 10000);
defaultLinkTradingFeePercent = _defaultLinkTradingFeePercent;
}
function setDefaultNonLinkTradingFeePercent(uint256 _defaultNonLinkTradingFeePercent)
external
override
onlyGovernance
{
// max 1%
require(_defaultNonLinkTradingFeePercent <= 10000);
defaultNonLinkTradingFeePercent = _defaultNonLinkTradingFeePercent;
}
function setMaxSlippagePercent(uint256 _maxSlippagePercent) external override onlyGovernance {
// max 100%
require(_maxSlippagePercent <= 100);
maxSlippagePercent = _maxSlippagePercent;
}
function setMaxSlippageBlocks(uint256 _maxSlippageBlocks) external override onlyGovernance {
// min 1 block, max 7 days (15s/block)
require(_maxSlippageBlocks >= 1 && _maxSlippageBlocks <= 40320);
maxSlippageBlocks = _maxSlippageBlocks;
}
}
/contracts/interfaces/ILinkswapPriceOracle.sol
pragma solidity 0.6.6;
interface ILinkswapPriceOracle {
function update() external;
// tokenAmount is to 18 dp, usdAmount is to 8 dp
// token must be LINK / WETH / YFL
function calculateTokenAmountFromUsdAmount(address token, uint256 usdAmount)
external
view
returns (uint256 tokenAmount);
// token must be LINK / WETH
function calculateUsdAmountFromTokenAmount(address token, uint256 tokenAmount)
external
view
returns (uint256 usdAmount);
}
/contracts/interfaces/ILinkswapFactory.sol
pragma solidity 0.6.6;
interface ILinkswapFactory {
event PairCreated(address indexed token0, address indexed token1, address pair, uint256 pairNum);
function LINK() external view returns (address);
function WETH() external view returns (address);
function YFL() external view returns (address);
function governance() external view returns (address);
function treasury() external view returns (address);
function priceOracle() external view returns (address);
// USD amounts should be 8 dp precision
// frontend should approve transfer of higher amount (e.g. 1.1x) due to price fluctuations
function linkListingFeeInUsd() external view returns (uint256);
function wethListingFeeInUsd() external view returns (uint256);
function yflListingFeeInUsd() external view returns (uint256);
// need to divide share by 1,000,000 e.g. 100,000 is 10%
// the rest goes to governance
function treasuryListingFeeShare() external view returns (uint256);
function minListingLockupAmountInUsd() external view returns (uint256);
// if lockup amount is set to this or more, the lockup amount proportion of listing fee discount is fully unlocked
// if less than this amount, then lockup amount proportion of listing fee discount is linearly interpolated from the distance between min and target lockup amounts e.g. 60% towards target from min means 60% of lockup amount discount
function targetListingLockupAmountInUsd() external view returns (uint256);
// in seconds since unix epoch
// min lockup period for the listing lockup amount
function minListingLockupPeriod() external view returns (uint256);
// in seconds since unix epoch
// if lockup period is set to this or longer, the lockup time proportion of listing fee discount is fully unlocked
// if less than this period, then lockup time proportion of listing fee discount is linearly interpolated from the distance between min and target lockup times e.g. 60% towards target from min means 60% of lockup time discount
function targetListingLockupPeriod() external view returns (uint256);
// need to divide share by 1,000,000 e.g. 100,000 is 10%
// rest of listing fee discount is determined by lockup period
function lockupAmountListingFeeDiscountShare() external view returns (uint256);
// need to divide fee percents by 1,000,000 e.g. 3000 is 0.3000%
function defaultLinkTradingFeePercent() external view returns (uint256);
function defaultNonLinkTradingFeePercent() external view returns (uint256);
// need to divide share by 1,000,000 e.g. 100,000 is 10%
// the rest goes to governance
function treasuryProtocolFeeShare() external view returns (uint256);
// inverse of protocol fee fraction, then multiplied by 1000.
// e.g. if protocol fee is 3/7th of trading fee, then value = 7/3 * 1000 = 2333
// set to 0 to disable protocol fee
function protocolFeeFractionInverse() external view returns (uint256);
// need to divide by 100 e.g. 50 is 50%
function maxSlippagePercent() external view returns (uint256);
// max slippage resets after this many blocks
function maxSlippageBlocks() external view returns (uint256);
function getPair(address tokenA, address tokenB) external view returns (address pair);
function approvedPair(address tokenA, address tokenB) external view returns (bool approved);
function allPairs(uint256) external view returns (address pair);
function allPairsLength() external view returns (uint256);
function approvePairViaGovernance(address tokenA, address tokenB) external;
function createPair(
address newToken,
uint256 newTokenAmount,
address lockupToken, // LINK or WETH
uint256 lockupTokenAmount,
uint256 lockupPeriod,
address listingFeeToken
) external returns (address pair);
function setPriceOracle(address) external;
function setTreasury(address) external;
function setGovernance(address) external;
function setTreasuryProtocolFeeShare(uint256) external;
function setProtocolFeeFractionInverse(uint256) external;
function setLinkListingFeeInUsd(uint256) external;
function setWethListingFeeInUsd(uint256) external;
function setYflListingFeeInUsd(uint256) external;
function setTreasuryListingFeeShare(uint256) external;
function setMinListingLockupAmountInUsd(uint256) external;
function setTargetListingLockupAmountInUsd(uint256) external;
function setMinListingLockupPeriod(uint256) external;
function setTargetListingLockupPeriod(uint256) external;
function setLockupAmountListingFeeDiscountShare(uint256) external;
function setDefaultLinkTradingFeePercent(uint256) external;
function setDefaultNonLinkTradingFeePercent(uint256) external;
function setMaxSlippagePercent(uint256) external;
function setMaxSlippageBlocks(uint256) external;
}
/contracts/libraries/SafeMathLinkswap.sol
pragma solidity 0.6.6;
// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
library SafeMathLinkswap {
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x, "ds-math-add-overflow");
}
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x, "ds-math-sub-underflow");
}
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
}
}
/contracts/interfaces/ILinkswapCallee.sol
pragma solidity 0.6.6;
interface ILinkswapCallee {
function linkswapCall(
address sender,
uint256 amount0,
uint256 amount1,
bytes calldata data
) external;
}
/contracts/interfaces/ILinkswapERC20.sol
pragma solidity 0.6.6;
interface ILinkswapERC20 {
event Approval(address indexed owner, address indexed spender, uint256 value);
event Transfer(address indexed from, address indexed to, uint256 value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure 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);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint256);
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
}
/contracts/libraries/TransferHelper.sol
pragma solidity 0.6.6;
// 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: 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: 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: TRANSFER_FROM_FAILED");
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, "TransferHelper: ETH_TRANSFER_FAILED");
}
}
/contracts/interfaces/ILinkswapPair.sol
pragma solidity 0.6.6;
import "./ILinkswapERC20.sol";
interface ILinkswapPair is ILinkswapERC20 {
event Mint(address indexed sender, uint256 amount0, uint256 amount1);
event Lock(address indexed sender, uint256 lockupPeriod, uint256 liquidityLockupAmount);
event Unlock(address indexed sender, uint256 liquidityUnlocked);
event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
event Swap(
address indexed sender,
uint256 amount0In,
uint256 amount1In,
uint256 amount0Out,
uint256 amount1Out,
address indexed to
);
event Sync(uint112 reserve0, uint112 reserve1);
function MINIMUM_LIQUIDITY() external pure returns (uint256);
function addressToLockupExpiry(address) external view returns (uint256);
function addressToLockupAmount(address) external view returns (uint256);
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves()
external
view
returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
);
function price0CumulativeLast() external view returns (uint256);
function price1CumulativeLast() external view returns (uint256);
function kLast() external view returns (uint256);
function tradingFeePercent() external view returns (uint256);
function lastSlippageBlocks() external view returns (uint256);
function priceAtLastSlippageBlocks() external view returns (uint256);
function lastSwapPrice() external view returns (uint256);
function mint(address to) external returns (uint256 liquidity);
function lock(uint256 lockupPeriod, uint256 liquidityLockupAmount) external;
function unlock() external;
function burn(address to) external returns (uint256 amount0, uint256 amount1);
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external;
function skim(address to) external;
function sync() external;
function setTradingFeePercent(uint256 _tradingFeePercent) external;
// functions only callable by LinkswapFactory
function initialize(
address _token0,
address _token1,
uint256 _tradingFeePercent
) external;
function listingLock(
address lister,
uint256 lockupPeriod,
uint256 liquidityLockupAmount
) external;
}
/contracts/libraries/UQ112x112.sol
pragma solidity 0.6.6;
// 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);
}
}
/contracts/libraries/Math.sol
pragma solidity 0.6.6;
// a library for performing various math operations
library 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;
}
// else z = 0
}
}
/contracts/LinkswapPair.sol
pragma solidity 0.6.6;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "./libraries/Math.sol";
import "./libraries/SafeMathLinkswap.sol";
import "./libraries/UQ112x112.sol";
import "./interfaces/ILinkswapCallee.sol";
import "./interfaces/ILinkswapFactory.sol";
import "./interfaces/ILinkswapPair.sol";
contract LinkswapPair is ILinkswapPair, ReentrancyGuard {
using SafeMathLinkswap for uint256;
using UQ112x112 for uint224;
string public constant override name = "LinkSwap LP Token";
string public constant override symbol = "LSLP";
uint8 public constant override decimals = 18;
uint256 public override totalSupply;
mapping(address => uint256) public override balanceOf;
mapping(address => mapping(address => uint256)) public override allowance;
bytes32 public override DOMAIN_SEPARATOR;
// keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
bytes32
public constant
override PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
mapping(address => uint256) public override nonces;
uint256 public constant override MINIMUM_LIQUIDITY = 10**3;
bytes4 private constant SELECTOR = bytes4(keccak256(bytes("transfer(address,uint256)")));
mapping(address => uint256) public override addressToLockupExpiry;
mapping(address => uint256) public override addressToLockupAmount;
address public override factory;
address public override token0;
address public override token1;
uint112 private reserve0; // uses single storage slot, accessible via getReserves
uint112 private reserve1; // uses single storage slot, accessible via getReserves
uint32 private blockTimestampLast; // uses single storage slot, accessible via getReserves
uint256 public override price0CumulativeLast;
uint256 public override price1CumulativeLast;
uint256 public override kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event
uint256 public override tradingFeePercent; // need to divide by 1,000,000, e.g. 3000 = 0.3%
uint256 public override lastSlippageBlocks;
uint256 public override priceAtLastSlippageBlocks;
uint256 public override lastSwapPrice;
modifier onlyGovernance() {
require(msg.sender == ILinkswapFactory(factory).governance(), "Pair: FORBIDDEN");
_;
}
constructor() public {
factory = msg.sender;
uint256 chainId;
assembly {
chainId := chainid()
}
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256(bytes("1")),
chainId,
address(this)
)
);
}
// called once by the factory at time of deployment
function initialize(
address _token0,
address _token1,
uint256 _tradingFeePercent
) external override {
require(msg.sender == factory, "Pair: FORBIDDEN"); // sufficient check
token0 = _token0;
token1 = _token1;
tradingFeePercent = _tradingFeePercent;
}
function _mint(address to, uint256 value) internal {
totalSupply = totalSupply.add(value);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(address(0), to, value);
}
function _burn(address from, uint256 value) internal {
balanceOf[from] = balanceOf[from].sub(value);
totalSupply = totalSupply.sub(value);
emit Transfer(from, address(0), value);
}
function _approve(
address owner,
address spender,
uint256 value
) private {
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
}
function _transfer(
address from,
address to,
uint256 value
) private {
balanceOf[from] = balanceOf[from].sub(value);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(from, to, value);
}
function approve(address spender, uint256 value) external override returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
function transfer(address to, uint256 value) external override returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
function transferFrom(
address from,
address to,
uint256 value
) external override returns (bool) {
if (allowance[from][msg.sender] != uint256(-1)) {
allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
}
_transfer(from, to, value);
return true;
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external override {
require(deadline >= block.timestamp, "Pair: EXPIRED");
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == owner, "Pair: INVALID_SIGNATURE");
_approve(owner, spender, value);
}
function getReserves()
public
view
override
returns (
uint112 _reserve0,
uint112 _reserve1,
uint32 _blockTimestampLast
)
{
_reserve0 = reserve0;
_reserve1 = reserve1;
_blockTimestampLast = blockTimestampLast;
}
function _safeTransfer(
address token,
address to,
uint256 value
) private {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), "Pair: TRANSFER_FAILED");
}
// update reserves and, on the first call per block, price accumulators
function _update(
uint256 balance0,
uint256 balance1,
uint112 _reserve0,
uint112 _reserve1
) private {
require(balance0 <= uint112(-1) && balance1 <= uint112(-1), "Pair: OVERFLOW");
uint32 blockTimestamp = uint32(block.timestamp % 2**32);
uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired
if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {
// * never overflows, and + overflow is desired
price0CumulativeLast += uint256(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;
price1CumulativeLast += uint256(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;
}
reserve0 = uint112(balance0);
reserve1 = uint112(balance1);
blockTimestampLast = blockTimestamp;
emit Sync(reserve0, reserve1);
}
function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) {
uint256 protocolFeeFractionInverse = ILinkswapFactory(factory).protocolFeeFractionInverse();
feeOn = protocolFeeFractionInverse != 0;
uint256 _kLast = kLast; // gas savings
if (feeOn) {
if (_kLast != 0) {
uint256 rootK = Math.sqrt(uint256(_reserve0).mul(_reserve1));
uint256 rootKLast = Math.sqrt(_kLast);
if (rootK > rootKLast) {
uint256 liquidity = totalSupply.mul(rootK.sub(rootKLast)).mul(1000) /
((rootK.mul(protocolFeeFractionInverse.sub(1000))).add(rootKLast.mul(1000)));
if (liquidity > 0) {
ILinkswapFactory linkswapFactory = ILinkswapFactory(factory);
uint256 treasuryProtocolFeeShare = linkswapFactory.treasuryProtocolFeeShare();
_mint(linkswapFactory.treasury(), liquidity.mul(treasuryProtocolFeeShare) / 1000000);
_mint(
linkswapFactory.governance(),
liquidity.mul(uint256(1000000).sub(treasuryProtocolFeeShare)) / 1000000
);
}
}
}
} else if (_kLast != 0) {
kLast = 0;
}
}
// this low-level function should be called from a contract which performs important safety checks
function mint(address to) public override nonReentrant returns (uint256 liquidity) {
(uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings
uint256 balance0 = IERC20(token0).balanceOf(address(this));
uint256 balance1 = IERC20(token1).balanceOf(address(this));
uint256 amount0 = balance0.sub(_reserve0);
uint256 amount1 = balance1.sub(_reserve1);
bool feeOn = _mintFee(_reserve0, _reserve1);
uint256 _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
if (_totalSupply == 0) {
liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
_mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
} else {
liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
}
require(liquidity > 0, "Pair: INSUFFICIENT_LIQUIDITY_MINTED");
_mint(to, liquidity);
_update(balance0, balance1, _reserve0, _reserve1);
if (feeOn) kLast = uint256(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
emit Mint(msg.sender, amount0, amount1);
}
function _lock(
address locker,
uint256 lockupPeriod,
uint256 liquidityLockupAmount
) private {
if (lockupPeriod == 0 && liquidityLockupAmount == 0) return;
if (addressToLockupExpiry[locker] == 0) {
// not currently locked
require(lockupPeriod > 0, "Pair: ZERO_LOCKUP_PERIOD");
require(liquidityLockupAmount > 0, "Pair: ZERO_LOCKUP_AMOUNT");
addressToLockupExpiry[locker] = block.timestamp.add(lockupPeriod);
} else {
// locking when already locked will extend lockup period
addressToLockupExpiry[locker] = addressToLockupExpiry[locker].add(lockupPeriod);
}
addressToLockupAmount[locker] = addressToLockupAmount[locker].add(liquidityLockupAmount);
_transfer(locker, address(this), liquidityLockupAmount);
emit Lock(locker, lockupPeriod, liquidityLockupAmount);
}
// called once by the factory at time of deployment
function listingLock(
address lister,
uint256 lockupPeriod,
uint256 liquidityLockupAmount
) external override {
require(msg.sender == factory, "Pair: FORBIDDEN");
_lock(lister, lockupPeriod, liquidityLockupAmount);
}
function lock(uint256 lockupPeriod, uint256 liquidityLockupAmount) external override {
_lock(msg.sender, lockupPeriod, liquidityLockupAmount);
}
function unlock() external override {
require(addressToLockupExpiry[msg.sender] <= block.timestamp, "Pair: BEFORE_EXPIRY");
_transfer(address(this), msg.sender, addressToLockupAmount[msg.sender]);
emit Unlock(msg.sender, addressToLockupAmount[msg.sender]);
addressToLockupAmount[msg.sender] = 0;
addressToLockupExpiry[msg.sender] = 0;
}
// this low-level function should be called from a contract which performs important safety checks
function burn(address to) external override nonReentrant returns (uint256 amount0, uint256 amount1) {
(uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings
address _token0 = token0; // gas savings
address _token1 = token1; // gas savings
uint256 balance0 = IERC20(_token0).balanceOf(address(this));
uint256 balance1 = IERC20(_token1).balanceOf(address(this));
uint256 liquidity = balanceOf[address(this)];
bool feeOn = _mintFee(_reserve0, _reserve1);
uint256 _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution
amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution
require(amount0 > 0 && amount1 > 0, "Pair: INSUFFICIENT_LIQUIDITY_BURNED");
_burn(address(this), liquidity);
_safeTransfer(_token0, to, amount0);
_safeTransfer(_token1, to, amount1);
balance0 = IERC20(_token0).balanceOf(address(this));
balance1 = IERC20(_token1).balanceOf(address(this));
_update(balance0, balance1, _reserve0, _reserve1);
if (feeOn) kLast = uint256(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
emit Burn(msg.sender, amount0, amount1, to);
}
// this low-level function should be called from a contract which performs important safety checks
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external override nonReentrant {
require(amount0Out > 0 || amount1Out > 0, "Pair: INSUFFICIENT_OUTPUT_AMOUNT");
(uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings
require(amount0Out < _reserve0 && amount1Out < _reserve1, "Pair: INSUFFICIENT_LIQUIDITY");
uint256 balance0;
uint256 balance1;
{
// scope for _token{0,1}, avoids stack too deep errors
address _token0 = token0;
address _token1 = token1;
require(to != _token0 && to != _token1, "Pair: INVALID_TO");
if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
if (data.length > 0) ILinkswapCallee(to).linkswapCall(msg.sender, amount0Out, amount1Out, data);
balance0 = IERC20(_token0).balanceOf(address(this));
balance1 = IERC20(_token1).balanceOf(address(this));
if (ILinkswapFactory(factory).maxSlippagePercent() > 0) {
uint256 currentPrice = balance0.mul(1e18) / balance1;
if (priceAtLastSlippageBlocks == 0) {
priceAtLastSlippageBlocks = currentPrice;
lastSlippageBlocks = block.number;
} else {
bool resetSlippage = lastSlippageBlocks.add(ILinkswapFactory(factory).maxSlippageBlocks()) <
block.number;
uint256 lastPrice = resetSlippage ? lastSwapPrice : priceAtLastSlippageBlocks;
require(
currentPrice >=
lastPrice.mul(uint256(100).sub(ILinkswapFactory(factory).maxSlippagePercent())) / 100 &&
currentPrice <=
lastPrice.mul(uint256(100).add(ILinkswapFactory(factory).maxSlippagePercent())) / 100,
"Pair: SlipLock"
);
if (resetSlippage) {
priceAtLastSlippageBlocks = currentPrice;
lastSlippageBlocks = block.number;
}
}
lastSwapPrice = currentPrice;
}
}
uint256 amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
uint256 amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
require(amount0In > 0 || amount1In > 0, "Pair: INSUFFICIENT_INPUT_AMOUNT");
{
// scope for balance{0,1}Adjusted, avoids stack too deep errors
uint256 balance0Adjusted = balance0.mul(1e6).sub(amount0In.mul(tradingFeePercent));
uint256 balance1Adjusted = balance1.mul(1e6).sub(amount1In.mul(tradingFeePercent));
require(balance0Adjusted.mul(balance1Adjusted) >= uint256(_reserve0).mul(_reserve1).mul(1e6**2), "Pair: K");
}
_update(balance0, balance1, _reserve0, _reserve1);
emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
}
// force balances to match reserves
function skim(address to) external override nonReentrant {
address _token0 = token0; // gas savings
address _token1 = token1; // gas savings
_safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0));
_safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1));
}
// force reserves to match balances
function sync() external override nonReentrant {
_update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);
}
function _setTradingFeePercent(uint256 _tradingFeePercent) private {
// max 1%
require(_tradingFeePercent <= 10000, "Pair: INVALID_TRADING_FEE_PERCENT");
tradingFeePercent = _tradingFeePercent;
}
function setTradingFeePercent(uint256 _tradingFeePercent) external override onlyGovernance {
_setTradingFeePercent(_tradingFeePercent);
}
}
/
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () internal {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
/IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
Compiler Settings
{"remappings":[],"optimizer":{"runs":200,"enabled":true},"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"istanbul","compilationTarget":{"/Users/kroll/Dev/LinkDeployment1/contracts/LinkswapFactory.sol":"LinkswapFactory"}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_governance","internalType":"address"},{"type":"address","name":"_treasury","internalType":"address"},{"type":"address","name":"_priceOracle","internalType":"address"},{"type":"uint256","name":"_linkListingFeeInUsd","internalType":"uint256"},{"type":"uint256","name":"_wethListingFeeInUsd","internalType":"uint256"},{"type":"uint256","name":"_yflListingFeeInUsd","internalType":"uint256"},{"type":"uint256","name":"_treasuryListingFeeShare","internalType":"uint256"},{"type":"uint256","name":"_minListingLockupAmountInUsd","internalType":"uint256"},{"type":"uint256","name":"_targetListingLockupAmountInUsd","internalType":"uint256"},{"type":"uint256","name":"_minListingLockupPeriod","internalType":"uint256"},{"type":"uint256","name":"_targetListingLockupPeriod","internalType":"uint256"},{"type":"uint256","name":"_lockupAmountListingFeeDiscountShare","internalType":"uint256"},{"type":"address","name":"_linkToken","internalType":"address"},{"type":"address","name":"_WETH","internalType":"address"},{"type":"address","name":"_yflToken","internalType":"address"}]},{"type":"event","name":"PairCreated","inputs":[{"type":"address","name":"token0","internalType":"address","indexed":true},{"type":"address","name":"token1","internalType":"address","indexed":true},{"type":"address","name":"pair","internalType":"address","indexed":false},{"type":"uint256","name":"pairNum","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"LINK","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"WETH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"YFL","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"allPairs","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allPairsLength","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"approvePairViaGovernance","inputs":[{"type":"address","name":"tokenA","internalType":"address"},{"type":"address","name":"tokenB","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approvedPair","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"pair","internalType":"address"}],"name":"createPair","inputs":[{"type":"address","name":"newToken","internalType":"address"},{"type":"uint256","name":"newTokenAmount","internalType":"uint256"},{"type":"address","name":"lockupToken","internalType":"address"},{"type":"uint256","name":"lockupTokenAmount","internalType":"uint256"},{"type":"uint256","name":"lockupPeriod","internalType":"uint256"},{"type":"address","name":"listingFeeToken","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"defaultLinkTradingFeePercent","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"defaultNonLinkTradingFeePercent","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getPair","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"governance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"linkListingFeeInUsd","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lockupAmountListingFeeDiscountShare","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxSlippageBlocks","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxSlippagePercent","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minListingLockupAmountInUsd","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minListingLockupPeriod","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"priceOracle","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"protocolFeeFractionInverse","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDefaultLinkTradingFeePercent","inputs":[{"type":"uint256","name":"_defaultLinkTradingFeePercent","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDefaultNonLinkTradingFeePercent","inputs":[{"type":"uint256","name":"_defaultNonLinkTradingFeePercent","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setGovernance","inputs":[{"type":"address","name":"_governance","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setLinkListingFeeInUsd","inputs":[{"type":"uint256","name":"_linkListingFeeInUsd","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setLockupAmountListingFeeDiscountShare","inputs":[{"type":"uint256","name":"_lockupAmountListingFeeDiscountShare","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxSlippageBlocks","inputs":[{"type":"uint256","name":"_maxSlippageBlocks","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxSlippagePercent","inputs":[{"type":"uint256","name":"_maxSlippagePercent","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinListingLockupAmountInUsd","inputs":[{"type":"uint256","name":"_minListingLockupAmountInUsd","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinListingLockupPeriod","inputs":[{"type":"uint256","name":"_minListingLockupPeriod","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPriceOracle","inputs":[{"type":"address","name":"_priceOracle","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setProtocolFeeFractionInverse","inputs":[{"type":"uint256","name":"_protocolFeeFractionInverse","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTargetListingLockupAmountInUsd","inputs":[{"type":"uint256","name":"_targetListingLockupAmountInUsd","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTargetListingLockupPeriod","inputs":[{"type":"uint256","name":"_targetListingLockupPeriod","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTreasury","inputs":[{"type":"address","name":"_treasury","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTreasuryListingFeeShare","inputs":[{"type":"uint256","name":"_treasuryListingFeeShare","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTreasuryProtocolFeeShare","inputs":[{"type":"uint256","name":"_treasuryProtocolFeeShare","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setWethListingFeeInUsd","inputs":[{"type":"uint256","name":"_wethListingFeeInUsd","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setYflListingFeeInUsd","inputs":[{"type":"uint256","name":"_yflListingFeeInUsd","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"targetListingLockupAmountInUsd","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"targetListingLockupPeriod","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"treasury","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"treasuryListingFeeShare","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"treasuryProtocolFeeShare","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"wethListingFeeInUsd","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"yflListingFeeInUsd","inputs":[]}]
Contract Creation Code
0x60e0604052620f42406007556109c4600d55610bb8600e55620f4240600f5560016012553480156200003057600080fd5b5060405162004bd138038062004bd183398181016040526101e08110156200005757600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919050505060016000819055508e600160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508d600260006101000a8154816001600160a01b0302191690836001600160a01b031602179055508c600360006101000a8154816001600160a01b0302191690836001600160a01b031602179055508b6004819055508a60058190555089600681905550886007819055506200019e876200021460201b60201c565b620001b2886001600160e01b036200022916565b620001c6856001600160e01b036200025516565b620001da866001600160e01b036200026a16565b600c939093556001600160601b0319606092831b811660805290821b811660a05291901b1660c052506200027f9950505050505050505050565b6008548110156200022457600080fd5b600955565b6009548111156200023957600080fd5b801562000250576103e88110156200025057600080fd5b600855565b600a548110156200026557600080fd5b600b55565b600b548111156200027a57600080fd5b600a55565b60805160601c60a05160601c60c05160601c6148db620002f660003980610a30528061109c52806112765280611332525080610aa05280610c5c528061106052806111c4528061121a5250806106b75280610c21528061102552806110dd528061113452806115ec528061162752506148db6000f3fe608060405234801561001057600080fd5b506004361061027f5760003560e01c806366bbb22e1161015c578063b6517727116100ce578063eb80d6d811610087578063eb80d6d8146105e9578063f09ce1cd14610631578063f0f4426014610639578063f2be0b0f1461065f578063f481e71b1461067c578063f55f921c146106845761027f565b8063b651772714610569578063bdc8865114610586578063c732aeff1461058e578063e112fb9714610596578063e6a439051461059e578063e9dba772146105cc5761027f565b80637c520255116101205780637c520255146104f1578063806e2f601461050e5780638814d38414610516578063a4803b3314610533578063ab033ea91461053b578063ad5c4648146105615761027f565b806366bbb22e1461043b57806368cf0e6b146104585780636c271d6d146104755780636f9107d814610492578063773d877a146104af5761027f565b806335eb9e40116101f5578063574f2ba3116101b9578063574f2ba3146103e15780635798a8bd146103e957806358f3ff1a146104065780635aa6e675146104235780635c8169571461042b57806361d027b3146104335761027f565b806335eb9e40146103865780634789b4c61461038e578063530e784f146103ab57806353e10b10146103d157806355aad536146103d95761027f565b8063205ec62e11610247578063205ec62e1461030657806324b07fbb146103235780632630c12f146103405780632a32f5d01461034857806330895627146103765780633314dd691461037e5761027f565b8063087f5602146102845780631a75a86a1461029e5780631b6b6d23146102bd5780631e3dd18b146102e15780631e421a61146102fe575b600080fd5b61028c61068c565b60408051918252519081900360200190f35b6102bb600480360360208110156102b457600080fd5b5035610692565b005b6102c56106b5565b604080516001600160a01b039092168252519081900360200190f35b6102c5600480360360208110156102f757600080fd5b50356106d9565b61028c610700565b6102bb6004803603602081101561031c57600080fd5b5035610706565b6102bb6004803603602081101561033957600080fd5b5035610726565b6102c5610752565b6102bb6004803603604081101561035e57600080fd5b506001600160a01b0381358116916020013516610761565b61028c610820565b61028c610826565b61028c61082c565b6102bb600480360360208110156103a457600080fd5b5035610832565b6102bb600480360360208110156103c157600080fd5b50356001600160a01b0316610852565b61028c61088b565b61028c610891565b61028c610897565b6102bb600480360360208110156103ff57600080fd5b503561089d565b6102bb6004803603602081101561041c57600080fd5b50356108b9565b6102c56108e5565b61028c6108f4565b6102c56108fa565b6102bb6004803603602081101561045157600080fd5b5035610909565b6102bb6004803603602081101561046e57600080fd5b5035610929565b6102bb6004803603602081101561048b57600080fd5b5035610955565b6102bb600480360360208110156104a857600080fd5b5035610971565b6104dd600480360360408110156104c557600080fd5b506001600160a01b03813581169160200135166109a9565b604080519115158252519081900360200190f35b6102bb6004803603602081101561050757600080fd5b50356109c9565b61028c6109fd565b6102bb6004803603602081101561052c57600080fd5b5035610a03565b6102c5610a2e565b6102bb6004803603602081101561055157600080fd5b50356001600160a01b0316610a52565b6102c5610a9e565b6102bb6004803603602081101561057f57600080fd5b5035610ac2565b61028c610aec565b61028c610af2565b61028c610af8565b6102c5600480360360408110156105b457600080fd5b506001600160a01b0381358116916020013516610afe565b6102bb600480360360208110156105e257600080fd5b5035610b24565b6102c5600480360360c08110156105ff57600080fd5b506001600160a01b038135811691602081013591604082013581169160608101359160808201359160a0013516610b40565b61028c610eb2565b6102bb6004803603602081101561064f57600080fd5b50356001600160a01b0316610eb8565b6102bb6004803603602081101561067557600080fd5b5035610ef1565b61028c610f1c565b61028c610f22565b600e5481565b6001546001600160a01b031633146106a957600080fd5b6106b281610f28565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b601581815481106106e657fe5b6000918252602090912001546001600160a01b0316905081565b600a5481565b6001546001600160a01b0316331461071d57600080fd5b6106b281610f3c565b6001546001600160a01b0316331461073d57600080fd5b620f424081111561074d57600080fd5b600755565b6003546001600160a01b031681565b6001546001600160a01b0316331461077857600080fd5b600260005414156107d0576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000908155806107e28484610f65565b6001600160a01b039182166000908152601460209081526040808320949093168252929092528120805460ff19166001908117909155905550505050565b60065481565b60125481565b600d5481565b6001546001600160a01b0316331461084957600080fd5b6106b281610ffb565b6001546001600160a01b0316331461086957600080fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60085481565b600f5481565b60155490565b6001546001600160a01b031633146108b457600080fd5b600455565b6001546001600160a01b031633146108d057600080fd5b620f42408111156108e057600080fd5b600f55565b6001546001600160a01b031681565b600b5481565b6002546001600160a01b031681565b6001546001600160a01b0316331461092057600080fd5b6106b28161100f565b6001546001600160a01b0316331461094057600080fd5b620f424081111561095057600080fd5b600c55565b6001546001600160a01b0316331461096c57600080fd5b600555565b6001546001600160a01b0316331461098857600080fd5b6001811015801561099b5750619d808111155b6109a457600080fd5b601255565b601460209081526000928352604080842090915290825290205460ff1681565b6001546001600160a01b031633146109e057600080fd5b6107d0811015806109ef575080155b6109f857600080fd5b601055565b60055481565b6001546001600160a01b03163314610a1a57600080fd5b612710811115610a2957600080fd5b600d55565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001546001600160a01b03163314610a6957600080fd5b6001600160a01b038116610a7c57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001546001600160a01b03163314610ad957600080fd5b6064811115610ae757600080fd5b601155565b60105481565b60045481565b60075481565b60136020908152600092835260408084209091529082529020546001600160a01b031681565b6001546001600160a01b03163314610b3b57600080fd5b600655565b600060026000541415610b9a576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556001546001600160a01b0316331415610bb757600080fd5b6001600160a01b03871615801590610bd757506001600160a01b03851615155b610be057600080fd5b600080610bed8988610f65565b6001600160a01b03808316600090815260146020908152604080832093851683529290522054919350915060ff16610d4b577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b03161480610c9057507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b0316145b610c9957600080fd5b600a54851015610ca857600080fd5b6003546040805163750c450d60e01b81526001600160a01b038a81166004830152602482018a90529151600093929092169163750c450d91604480820192602092909190829003018186803b158015610d0057600080fd5b505afa158015610d14573d6000803e3d6000fd5b505050506040513d6020811015610d2a57600080fd5b5051600854909150811015610d3e57600080fd5b610d49858288611023565b505b610d558282611544565b6001600160a01b0380841660009081526014602090815260408083209386168352929052205490935060ff16158015610d8e5750600086115b8015610d9a5750600085115b15610ea157610dab8933858b6117b9565b610db7873385896117b9565b604080516335313c2160e11b815233600482015290516000916001600160a01b03861691636a6278429160248082019260209290919082900301818787803b158015610e0257600080fd5b505af1158015610e16573d6000803e3d6000fd5b505050506040513d6020811015610e2c57600080fd5b50516040805163738a1aa960e11b8152336004820152602481018990526044810183905290519192506001600160a01b0386169163e71435529160648082019260009290919082900301818387803b158015610e8757600080fd5b505af1158015610e9b573d6000803e3d6000fd5b50505050505b505060016000559695505050505050565b600c5481565b6001546001600160a01b03163314610ecf57600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314610f0857600080fd5b612710811115610f1757600080fd5b600e55565b60115481565b60095481565b600854811015610f3757600080fd5b600955565b600954811115610f4b57600080fd5b8015610f60576103e8811015610f6057600080fd5b600855565b600080826001600160a01b0316846001600160a01b03161415610f8757600080fd5b826001600160a01b0316846001600160a01b031610610fa7578284610faa565b83835b90925090506001600160a01b038216610fc257600080fd5b6001600160a01b03828116600090815260136020908152604080832085851684529091529020541615610ff457600080fd5b9250929050565b600b5481111561100a57600080fd5b600a55565b600a5481101561101e57600080fd5b600b55565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316148061109457507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316145b806110d057507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316145b6110d957600080fd5b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031614156111c2576003546004805460408051630f2008f560e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811694820194909452602481019290925251919092169163790047a8916044808301926020929190829003018186803b15801561118f57600080fd5b505afa1580156111a3573d6000803e3d6000fd5b505050506040513d60208110156111b957600080fd5b505190506113bd565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031614156112745760035460055460408051630f2008f560e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260248201939093529051919092169163790047a8916044808301926020929190829003018186803b15801561118f57600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031614156113bd57600360009054906101000a90046001600160a01b03166001600160a01b031663a2e620456040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156112fe57600080fd5b505af1158015611312573d6000803e3d6000fd5b505060035460065460408051630f2008f560e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820193909352905191909216935063790047a892506044808301926020929190829003018186803b15801561138e57600080fd5b505afa1580156113a2573d6000803e3d6000fd5b505050506040513d60208110156113b857600080fd5b505190505b60006008546009541115611412576008546009546113e09163ffffffff61190e16565b6114076113f86008548761190e90919063ffffffff16565b600c549063ffffffff61196416565b8161140e57fe5b0490505b600a54600b54111561148c57611489611438600a54600b5461190e90919063ffffffff16565b611473611450600a548761190e90919063ffffffff16565b600c5461146790620f42409063ffffffff61190e16565b9063ffffffff61196416565b8161147a57fe5b8391900463ffffffff6119c716565b90505b6000620f42406114b26114a5828563ffffffff61190e16565b859063ffffffff61196416565b816114b957fe5b0490506114fd8633600260009054906101000a90046001600160a01b0316620f42406114f06007548761196490919063ffffffff16565b816114f757fe5b046117b9565b60015460075461153c91889133916001600160a01b031690620f4240906114f09061152f90839063ffffffff61190e16565b879063ffffffff61196416565b505050505050565b600060606040518060200161155890611a16565b6020820181038252601f19601f8201166040525090506000848460405160200180836001600160a01b03166001600160a01b031660601b8152601401826001600160a01b03166001600160a01b031660601b815260140192505050604051602081830303815290604052805190602001209050808251602084016000f592505050806001600160a01b0316631794bb3c84847f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b0316148061165b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b0316145b61166757600e5461166b565b600d545b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b1580156116d357600080fd5b505af11580156116e7573d6000803e3d6000fd5b505050506001600160a01b03838116600081815260136020818152604080842088871680865290835281852080549789166001600160a01b031998891681179091559383528185208686528352818520805488168517905560158054600181018255958190527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47590950180549097168417909655925483519283529082015281517f0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9929181900390910190a392915050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b6020831061183e5780518252601f19909201916020918201910161181f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146118a0576040519150601f19603f3d011682016040523d82523d6000602084013e6118a5565b606091505b50915091508180156118d35750805115806118d357508080602001905160208110156118d057600080fd5b50515b61153c5760405162461bcd60e51b81526004018080602001828103825260248152602001806148826024913960400191505060405180910390fd5b8082038281111561195e576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b92915050565b600081158061197f5750508082028282828161197c57fe5b04145b61195e576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b8082018281101561195e576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b612e5e80611a248339019056fe608060405234801561001057600080fd5b506001600055600880546001600160a01b031916331790556040514690806052612e0c823960408051918290036052018220828201825260118352702634b735a9bbb0b8102628102a37b5b2b760791b6020938401528151808301835260018152603160f81b908401528151808401919091527f0ca3509544dff675980d1d1ad68e7359d3dc13a567d0450acb908d532d2b0549818301527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015260808101949094523060a0808601919091528151808603909101815260c09094019052825192019190912060045550612d008061010c6000396000f3fe608060405234801561001057600080fd5b50600436106102275760003560e01c80635f2dd7a711610130578063a9059cbb116100b8578063d505accf1161007c578063d505accf1461066e578063dd62ed3e146106bf578063e3956ed0146106ed578063e7143552146106f5578063fff6cae91461072757610227565b8063a9059cbb14610604578063ba9a7a5614610630578063bc25cf7714610638578063c45a01551461065e578063d21220a71461066657610227565b80637b1a201a116100ff5780637b1a201a146105695780637ecebe001461058f57806389afcb44146105b557806395d89b41146105f4578063a69df4b5146105fc57610227565b80635f2dd7a71461050d5780636a6278421461051557806370a082311461053b5780637464fc3d1461056157610227565b806318160ddd116101b3578063313ce56711610182578063313ce567146104b15780633644e515146104cf5780634d76a106146104d75780635909c0d5146104fd5780635a3d54931461050557610227565b806318160ddd1461046357806323b872dd1461046b5780632a324027146104a157806330adf81f146104a957610227565b8063095ea7b3116101fa578063095ea7b3146103895780630c615ee9146103c95780630dfe1681146103e65780631338736f1461040a5780631794bb3c1461042d57610227565b8063022c0d9f1461022c57806302e028f3146102ba57806306fdde03146102d45780630902f1ac14610351575b600080fd5b6102b86004803603608081101561024257600080fd5b8135916020810135916001600160a01b03604083013516919081019060808101606082013564010000000081111561027957600080fd5b82018360208201111561028b57600080fd5b803590602001918460018302840111640100000000831117156102ad57600080fd5b50909250905061072f565b005b6102c2610faa565b60408051918252519081900360200190f35b6102dc610fb0565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103165781810151838201526020016102fe565b50505050905090810190601f1680156103435780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610359610fdd565b604080516001600160701b03948516815292909316602083015263ffffffff168183015290519081900360600190f35b6103b56004803603604081101561039f57600080fd5b506001600160a01b038135169060200135611007565b604080519115158252519081900360200190f35b6102b8600480360360208110156103df57600080fd5b503561101e565b6103ee6110f2565b604080516001600160a01b039092168252519081900360200190f35b6102b86004803603604081101561042057600080fd5b5080359060200135611101565b6102b86004803603606081101561044357600080fd5b506001600160a01b03813581169160208101359091169060400135611110565b6102c2611196565b6103b56004803603606081101561048157600080fd5b506001600160a01b0381358116916020810135909116906040013561119c565b6102c2611236565b6102c261123c565b6104b9611260565b6040805160ff9092168252519081900360200190f35b6102c2611265565b6102c2600480360360208110156104ed57600080fd5b50356001600160a01b031661126b565b6102c261127d565b6102c2611283565b6102c2611289565b6102c26004803603602081101561052b57600080fd5b50356001600160a01b031661128f565b6102c26004803603602081101561055157600080fd5b50356001600160a01b031661158a565b6102c261159c565b6102c26004803603602081101561057f57600080fd5b50356001600160a01b03166115a2565b6102c2600480360360208110156105a557600080fd5b50356001600160a01b03166115b4565b6105db600480360360208110156105cb57600080fd5b50356001600160a01b03166115c6565b6040805192835260208301919091528051918290030190f35b6102dc611967565b6102b8611987565b6103b56004803603604081101561061a57600080fd5b506001600160a01b038135169060200135611a60565b6102c2611a6d565b6102b86004803603602081101561064e57600080fd5b50356001600160a01b0316611a73565b6103ee611bd9565b6103ee611be8565b6102b8600480360360e081101561068457600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135611bf7565b6102c2600480360360408110156106d557600080fd5b506001600160a01b0381358116916020013516611df4565b6102c2611e11565b6102b86004803603606081101561070b57600080fd5b506001600160a01b038135169060208101359060400135611e17565b6102b8611e78565b60026000541415610775576040805162461bcd60e51b815260206004820152601f6024820152600080516020612c67833981519152604482015290519081900360640190fd5b6002600055841515806107885750600084115b6107d9576040805162461bcd60e51b815260206004820181905260248201527f506169723a20494e53554646494349454e545f4f55545055545f414d4f554e54604482015290519081900360640190fd5b6000806107e4610fdd565b5091509150816001600160701b0316871080156108095750806001600160701b031686105b61085a576040805162461bcd60e51b815260206004820152601c60248201527f506169723a20494e53554646494349454e545f4c495155494449545900000000604482015290519081900360640190fd5b600954600a5460009182916001600160a01b039182169190811690891682148015906108985750806001600160a01b0316896001600160a01b031614155b6108dc576040805162461bcd60e51b815260206004820152601060248201526f506169723a20494e56414c49445f544f60801b604482015290519081900360640190fd5b8a156108ed576108ed828a8d611fd5565b89156108fe576108fe818a8c611fd5565b86156109b957886001600160a01b0316631bd7dbe7338d8d8c8c6040518663ffffffff1660e01b815260040180866001600160a01b03166001600160a01b03168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b1580156109a057600080fd5b505af11580156109b4573d6000803e3d6000fd5b505050505b604080516370a0823160e01b815230600482015290516001600160a01b038416916370a08231916024808301926020929190829003018186803b1580156109ff57600080fd5b505afa158015610a13573d6000803e3d6000fd5b505050506040513d6020811015610a2957600080fd5b5051604080516370a0823160e01b815230600482015290519195506001600160a01b038316916370a0823191602480820192602092909190829003018186803b158015610a7557600080fd5b505afa158015610a89573d6000803e3d6000fd5b505050506040513d6020811015610a9f57600080fd5b50516008546040805163f481e71b60e01b815290519295506000926001600160a01b039092169163f481e71b91600480820192602092909190829003018186803b158015610aec57600080fd5b505afa158015610b00573d6000803e3d6000fd5b505050506040513d6020811015610b1657600080fd5b50511115610da757600083610b3986670de0b6b3a764000063ffffffff61216716565b81610b4057fe5b04905060115460001415610b5c57601181905543601055610da3565b600043610beb600860009054906101000a90046001600160a01b03166001600160a01b0316633314dd696040518163ffffffff1660e01b815260040160206040518083038186803b158015610bb057600080fd5b505afa158015610bc4573d6000803e3d6000fd5b505050506040513d6020811015610bda57600080fd5b50516010549063ffffffff6121ca16565b109050600081610bfd57601154610c01565b6012545b90506064610ca0610c93600860009054906101000a90046001600160a01b03166001600160a01b031663f481e71b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c5957600080fd5b505afa158015610c6d573d6000803e3d6000fd5b505050506040513d6020811015610c8357600080fd5b505160649063ffffffff61221916565b839063ffffffff61216716565b81610ca757fe5b048310158015610d4e57506064610d42610c93600860009054906101000a90046001600160a01b03166001600160a01b031663f481e71b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0857600080fd5b505afa158015610d1c573d6000803e3d6000fd5b505050506040513d6020811015610d3257600080fd5b505160649063ffffffff6121ca16565b81610d4957fe5b048311155b610d90576040805162461bcd60e51b815260206004820152600e60248201526d506169723a20536c69704c6f636b60901b604482015290519081900360640190fd5b8115610da0576011839055436010555b50505b6012555b5050600089856001600160701b0316038311610dc4576000610dd3565b89856001600160701b03160383035b9050600089856001600160701b0316038311610df0576000610dff565b89856001600160701b03160383035b90506000821180610e105750600081115b610e61576040805162461bcd60e51b815260206004820152601f60248201527f506169723a20494e53554646494349454e545f494e5055545f414d4f554e5400604482015290519081900360640190fd5b6000610e9a610e7b600f548561216790919063ffffffff16565b610e8e87620f424063ffffffff61216716565b9063ffffffff61221916565b90506000610eb6610e7b600f548561216790919063ffffffff16565b9050610ee964e8d4a51000610edd6001600160701b038b8116908b1663ffffffff61216716565b9063ffffffff61216716565b610ef9838363ffffffff61216716565b1015610f36576040805162461bcd60e51b8152602060048201526007602482015266506169723a204b60c81b604482015290519081900360640190fd5b5050610f4484848888612269565b60408051838152602081018390528082018d9052606081018c905290516001600160a01b038b169133917fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229181900360800190a350506001600055505050505050505050565b60115481565b604051806040016040528060118152602001702634b735a9bbb0b8102628102a37b5b2b760791b81525081565b600b546001600160701b0380821692600160701b830490911691600160e01b900463ffffffff1690565b6000611014338484612429565b5060015b92915050565b600860009054906101000a90046001600160a01b03166001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b15801561106c57600080fd5b505afa158015611080573d6000803e3d6000fd5b505050506040513d602081101561109657600080fd5b50516001600160a01b031633146110e6576040805162461bcd60e51b815260206004820152600f60248201526e2830b4b91d102327a92124a22222a760891b604482015290519081900360640190fd5b6110ef8161248b565b50565b6009546001600160a01b031681565b61110c3383836124d1565b5050565b6008546001600160a01b03163314611161576040805162461bcd60e51b815260206004820152600f60248201526e2830b4b91d102327a92124a22222a760891b604482015290519081900360640190fd5b600980546001600160a01b039485166001600160a01b031991821617909155600a805493909416921691909117909155600f55565b60015481565b6001600160a01b038316600090815260036020908152604080832033845290915281205460001914611221576001600160a01b03841660009081526003602090815260408083203384529091529020546111fc908363ffffffff61221916565b6001600160a01b03851660009081526003602090815260408083203384529091529020555b61122c8484846126b4565b5060019392505050565b600f5481565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60045481565b60066020526000908152604090205481565b600c5481565b600d5481565b60105481565b6000600260005414156112d7576040805162461bcd60e51b815260206004820152601f6024820152600080516020612c67833981519152604482015290519081900360640190fd5b60026000908155806112e7610fdd565b50600954604080516370a0823160e01b815230600482015290519395509193506000926001600160a01b03909116916370a08231916024808301926020929190829003018186803b15801561133b57600080fd5b505afa15801561134f573d6000803e3d6000fd5b505050506040513d602081101561136557600080fd5b5051600a54604080516370a0823160e01b815230600482015290519293506000926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b1580156113b857600080fd5b505afa1580156113cc573d6000803e3d6000fd5b505050506040513d60208110156113e257600080fd5b505190506000611401836001600160701b03871663ffffffff61221916565b9050600061141e836001600160701b03871663ffffffff61221916565b9050600061142c878761276e565b60015490915080611469576114556103e8610e8e611450878763ffffffff61216716565b612a6e565b985061146460006103e8612ac0565b6114b8565b6114b56001600160701b038916611486868463ffffffff61216716565b8161148d57fe5b046001600160701b0389166114a8868563ffffffff61216716565b816114af57fe5b04612b57565b98505b600089116114f75760405162461bcd60e51b8152600401808060200182810382526023815260200180612c446023913960400191505060405180910390fd5b6115018a8a612ac0565b61150d86868a8a612269565b811561153d57600b54611539906001600160701b0380821691600160701b90041663ffffffff61216716565b600e555b6040805185815260208101859052815133927f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f928290030190a25050600160005550949695505050505050565b60026020526000908152604090205481565b600e5481565b60076020526000908152604090205481565b60056020526000908152604090205481565b6000806002600054141561160f576040805162461bcd60e51b815260206004820152601f6024820152600080516020612c67833981519152604482015290519081900360640190fd5b600260009081558061161f610fdd565b50600954600a54604080516370a0823160e01b815230600482015290519496509294506001600160a01b039182169391169160009184916370a08231916024808301926020929190829003018186803b15801561167b57600080fd5b505afa15801561168f573d6000803e3d6000fd5b505050506040513d60208110156116a557600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b1580156116f357600080fd5b505afa158015611707573d6000803e3d6000fd5b505050506040513d602081101561171d57600080fd5b50513060009081526002602052604081205491925061173c888861276e565b60015490915080611753848763ffffffff61216716565b8161175a57fe5b049a508061176e848663ffffffff61216716565b8161177557fe5b04995060008b118015611788575060008a115b6117c35760405162461bcd60e51b8152600401808060200182810382526023815260200180612c876023913960400191505060405180910390fd5b6117cd3084612b6f565b6117d8878d8d611fd5565b6117e3868d8c611fd5565b604080516370a0823160e01b815230600482015290516001600160a01b038916916370a08231916024808301926020929190829003018186803b15801561182957600080fd5b505afa15801561183d573d6000803e3d6000fd5b505050506040513d602081101561185357600080fd5b5051604080516370a0823160e01b815230600482015290519196506001600160a01b038816916370a0823191602480820192602092909190829003018186803b15801561189f57600080fd5b505afa1580156118b3573d6000803e3d6000fd5b505050506040513d60208110156118c957600080fd5b505193506118d985858b8b612269565b811561190957600b54611905906001600160701b0380821691600160701b90041663ffffffff61216716565b600e555b604080518c8152602081018c905281516001600160a01b038f169233927fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496929081900390910190a35050505050505050506001600081905550915091565b6040518060400160405280600481526020016304c534c560e41b81525081565b336000908152600660205260409020544210156119e1576040805162461bcd60e51b8152602060048201526013602482015272506169723a204245464f52455f45585049525960681b604482015290519081900360640190fd5b336000818152600760205260409020546119fc9130916126b4565b3360008181526007602090815260409182902054825190815291517f6381d9813cabeb57471b5a7e05078e64845ccdb563146a6911d536f24ce960f19281900390910190a23360009081526007602090815260408083208390556006909152812055565b60006110143384846126b4565b6103e881565b60026000541415611ab9576040805162461bcd60e51b815260206004820152601f6024820152600080516020612c67833981519152604482015290519081900360640190fd5b6002600055600954600a54600b54604080516370a0823160e01b815230600482015290516001600160a01b039485169490931692611b689285928792611b63926001600160701b03169185916370a0823191602480820192602092909190829003018186803b158015611b2b57600080fd5b505afa158015611b3f573d6000803e3d6000fd5b505050506040513d6020811015611b5557600080fd5b50519063ffffffff61221916565b611fd5565b600b54604080516370a0823160e01b81523060048201529051611bcf9284928792611b6392600160701b90046001600160701b0316916001600160a01b038616916370a0823191602480820192602092909190829003018186803b158015611b2b57600080fd5b5050600160005550565b6008546001600160a01b031681565b600a546001600160a01b031681565b42841015611c3c576040805162461bcd60e51b815260206004820152600d60248201526c14185a5c8e8811561412549151609a1b604482015290519081900360640190fd5b6004546001600160a01b0380891660008181526005602090815260408083208054600180820190925582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958d166060860152608085018c905260a085019590955260c08085018b90528151808603909101815260e08501825280519083012061190160f01b6101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff89166101828501526101a284018890526101c28401879052519193926101e280820193601f1981019281900390910190855afa158015611d57573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590611d8d5750886001600160a01b0316816001600160a01b0316145b611dde576040805162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e4154555245000000000000000000604482015290519081900360640190fd5b611de9898989612429565b505050505050505050565b600360209081526000928352604080842090915290825290205481565b60125481565b6008546001600160a01b03163314611e68576040805162461bcd60e51b815260206004820152600f60248201526e2830b4b91d102327a92124a22222a760891b604482015290519081900360640190fd5b611e738383836124d1565b505050565b60026000541415611ebe576040805162461bcd60e51b815260206004820152601f6024820152600080516020612c67833981519152604482015290519081900360640190fd5b6002600055600954604080516370a0823160e01b81523060048201529051611fce926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611f0f57600080fd5b505afa158015611f23573d6000803e3d6000fd5b505050506040513d6020811015611f3957600080fd5b5051600a54604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015611f8657600080fd5b505afa158015611f9a573d6000803e3d6000fd5b505050506040513d6020811015611fb057600080fd5b5051600b546001600160701b0380821691600160701b900416612269565b6001600055565b604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b1781529251815160009460609489169392918291908083835b602083106120825780518252601f199092019160209182019101612063565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146120e4576040519150601f19603f3d011682016040523d82523d6000602084013e6120e9565b606091505b5091509150818015612117575080511580612117575080806020019051602081101561211457600080fd5b50515b612160576040805162461bcd60e51b815260206004820152601560248201527414185a5c8e881514905394d1915497d19052531151605a1b604482015290519081900360640190fd5b5050505050565b60008115806121825750508082028282828161217f57fe5b04145b611018576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b80820182811015611018576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b80820382811115611018576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b6001600160701b03841180159061228757506001600160701b038311155b6122c9576040805162461bcd60e51b815260206004820152600e60248201526d506169723a204f564552464c4f5760901b604482015290519081900360640190fd5b600b5463ffffffff42811691600160e01b900481168203908116158015906122f957506001600160701b03841615155b801561230d57506001600160701b03831615155b1561237e578063ffffffff1661233b8561232686612c0c565b6001600160e01b03169063ffffffff612c1e16565b600c80546001600160e01b03929092169290920201905563ffffffff81166123668461232687612c0c565b600d80546001600160e01b0392909216929092020190555b600b80546dffffffffffffffffffffffffffff19166001600160701b03888116919091176dffffffffffffffffffffffffffff60701b1916600160701b8883168102919091176001600160e01b0316600160e01b63ffffffff871602179283905560408051848416815291909304909116602082015281517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1929181900390910190a1505050505050565b6001600160a01b03808416600081815260036020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6127108111156124cc5760405162461bcd60e51b8152600401808060200182810382526021815260200180612caa6021913960400191505060405180910390fd5b600f55565b811580156124dd575080155b156124e757611e73565b6001600160a01b0383166000908152600660205260409020546125dc5760008211612559576040805162461bcd60e51b815260206004820152601860248201527f506169723a205a45524f5f4c4f434b55505f504552494f440000000000000000604482015290519081900360640190fd5b600081116125ae576040805162461bcd60e51b815260206004820152601860248201527f506169723a205a45524f5f4c4f434b55505f414d4f554e540000000000000000604482015290519081900360640190fd5b6125be428363ffffffff6121ca16565b6001600160a01b03841660009081526006602052604090205561261f565b6001600160a01b038316600090815260066020526040902054612605908363ffffffff6121ca16565b6001600160a01b0384166000908152600660205260409020555b6001600160a01b038316600090815260076020526040902054612648908263ffffffff6121ca16565b6001600160a01b03841660009081526007602052604090205561266c8330836126b4565b604080518381526020810183905281516001600160a01b038616927f49eaf4942f1237055eb4cfa5f31c9dfe50d5b4ade01e021f7de8be2fbbde557b928290030190a2505050565b6001600160a01b0383166000908152600260205260409020546126dd908263ffffffff61221916565b6001600160a01b038085166000908152600260205260408082209390935590841681522054612712908263ffffffff6121ca16565b6001600160a01b0380841660008181526002602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600080600860009054906101000a90046001600160a01b03166001600160a01b031663bdc886516040518163ffffffff1660e01b815260040160206040518083038186803b1580156127bf57600080fd5b505afa1580156127d3573d6000803e3d6000fd5b505050506040513d60208110156127e957600080fd5b5051600e5481158015945091925090612a5a578015612a555760006128236114506001600160701b0388811690881663ffffffff61216716565b9050600061283083612a6e565b905080821115612a5257600061287f612851836103e863ffffffff61216716565b612873612866886103e863ffffffff61221916565b869063ffffffff61216716565b9063ffffffff6121ca16565b6128a76103e8610edd612898878763ffffffff61221916565b6001549063ffffffff61216716565b816128ae57fe5b0490508015612a505760085460408051632ad56a9b60e11b815290516001600160a01b039092169160009183916355aad53691600480820192602092909190829003018186803b15801561290157600080fd5b505afa158015612915573d6000803e3d6000fd5b505050506040513d602081101561292b57600080fd5b5051604080516361d027b360e01b815290519192506129c1916001600160a01b038516916361d027b3916004808301926020929190829003018186803b15801561297457600080fd5b505afa158015612988573d6000803e3d6000fd5b505050506040513d602081101561299e57600080fd5b5051620f42406129b4868563ffffffff61216716565b816129bb57fe5b04612ac0565b612a4d826001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b1580156129fd57600080fd5b505afa158015612a11573d6000803e3d6000fd5b505050506040513d6020811015612a2757600080fd5b5051620f42406129b4612a40828663ffffffff61221916565b879063ffffffff61216716565b50505b505b50505b612a66565b8015612a66576000600e555b505092915050565b60006003821115612ab1575080600160028204015b81811015612aab57809150600281828581612a9a57fe5b040181612aa357fe5b049050612a83565b50612abb565b8115612abb575060015b919050565b600154612ad3908263ffffffff6121ca16565b6001556001600160a01b038216600090815260026020526040902054612aff908263ffffffff6121ca16565b6001600160a01b03831660008181526002602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000818310612b665781612b68565b825b9392505050565b6001600160a01b038216600090815260026020526040902054612b98908263ffffffff61221916565b6001600160a01b038316600090815260026020526040902055600154612bc4908263ffffffff61221916565b6001556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160701b0316600160701b0290565b60006001600160701b0382166001600160e01b03841681612c3b57fe5b04939250505056fe506169723a20494e53554646494349454e545f4c49515549444954595f4d494e5445445265656e7472616e637947756172643a207265656e7472616e742063616c6c00506169723a20494e53554646494349454e545f4c49515549444954595f4255524e4544506169723a20494e56414c49445f54524144494e475f4645455f50455243454e54a26469706673582212207742272246e025edf55270eafd0a67f4b43dad2a999311f80109becf08cd9fc264736f6c63430006060033454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e7472616374295472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544a2646970667358221220654280381ec72a5a6b159a63ac383be08cf4bcb8e405380c6ea8096863dee8a764736f6c634300060600330000000000000000000000000389d755c1833c9b350d4e8b619eae16defc1cba000000000000000000000000e69a81b96fbf5cb6cae95d2ce5323eff2ba0eae4000000000000000000000000dfa5e7989c98446ffea622266e18df563e8598720000000000000000000000000000000000000000000000000000003a3529440000000000000000000000000000000000000000000000000000000045d964b8000000000000000000000000000000000000000000000000000000002e90edd00000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000746a52880000000000000000000000000000000000000000000000000000000246139ca8000000000000000000000000000000000000000000000000000000000000093a800000000000000000000000000000000000000000000000000000000000278d00000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000028cb7e841ee97947a86b06fa4090c8451f64c0be
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061027f5760003560e01c806366bbb22e1161015c578063b6517727116100ce578063eb80d6d811610087578063eb80d6d8146105e9578063f09ce1cd14610631578063f0f4426014610639578063f2be0b0f1461065f578063f481e71b1461067c578063f55f921c146106845761027f565b8063b651772714610569578063bdc8865114610586578063c732aeff1461058e578063e112fb9714610596578063e6a439051461059e578063e9dba772146105cc5761027f565b80637c520255116101205780637c520255146104f1578063806e2f601461050e5780638814d38414610516578063a4803b3314610533578063ab033ea91461053b578063ad5c4648146105615761027f565b806366bbb22e1461043b57806368cf0e6b146104585780636c271d6d146104755780636f9107d814610492578063773d877a146104af5761027f565b806335eb9e40116101f5578063574f2ba3116101b9578063574f2ba3146103e15780635798a8bd146103e957806358f3ff1a146104065780635aa6e675146104235780635c8169571461042b57806361d027b3146104335761027f565b806335eb9e40146103865780634789b4c61461038e578063530e784f146103ab57806353e10b10146103d157806355aad536146103d95761027f565b8063205ec62e11610247578063205ec62e1461030657806324b07fbb146103235780632630c12f146103405780632a32f5d01461034857806330895627146103765780633314dd691461037e5761027f565b8063087f5602146102845780631a75a86a1461029e5780631b6b6d23146102bd5780631e3dd18b146102e15780631e421a61146102fe575b600080fd5b61028c61068c565b60408051918252519081900360200190f35b6102bb600480360360208110156102b457600080fd5b5035610692565b005b6102c56106b5565b604080516001600160a01b039092168252519081900360200190f35b6102c5600480360360208110156102f757600080fd5b50356106d9565b61028c610700565b6102bb6004803603602081101561031c57600080fd5b5035610706565b6102bb6004803603602081101561033957600080fd5b5035610726565b6102c5610752565b6102bb6004803603604081101561035e57600080fd5b506001600160a01b0381358116916020013516610761565b61028c610820565b61028c610826565b61028c61082c565b6102bb600480360360208110156103a457600080fd5b5035610832565b6102bb600480360360208110156103c157600080fd5b50356001600160a01b0316610852565b61028c61088b565b61028c610891565b61028c610897565b6102bb600480360360208110156103ff57600080fd5b503561089d565b6102bb6004803603602081101561041c57600080fd5b50356108b9565b6102c56108e5565b61028c6108f4565b6102c56108fa565b6102bb6004803603602081101561045157600080fd5b5035610909565b6102bb6004803603602081101561046e57600080fd5b5035610929565b6102bb6004803603602081101561048b57600080fd5b5035610955565b6102bb600480360360208110156104a857600080fd5b5035610971565b6104dd600480360360408110156104c557600080fd5b506001600160a01b03813581169160200135166109a9565b604080519115158252519081900360200190f35b6102bb6004803603602081101561050757600080fd5b50356109c9565b61028c6109fd565b6102bb6004803603602081101561052c57600080fd5b5035610a03565b6102c5610a2e565b6102bb6004803603602081101561055157600080fd5b50356001600160a01b0316610a52565b6102c5610a9e565b6102bb6004803603602081101561057f57600080fd5b5035610ac2565b61028c610aec565b61028c610af2565b61028c610af8565b6102c5600480360360408110156105b457600080fd5b506001600160a01b0381358116916020013516610afe565b6102bb600480360360208110156105e257600080fd5b5035610b24565b6102c5600480360360c08110156105ff57600080fd5b506001600160a01b038135811691602081013591604082013581169160608101359160808201359160a0013516610b40565b61028c610eb2565b6102bb6004803603602081101561064f57600080fd5b50356001600160a01b0316610eb8565b6102bb6004803603602081101561067557600080fd5b5035610ef1565b61028c610f1c565b61028c610f22565b600e5481565b6001546001600160a01b031633146106a957600080fd5b6106b281610f28565b50565b7f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca81565b601581815481106106e657fe5b6000918252602090912001546001600160a01b0316905081565b600a5481565b6001546001600160a01b0316331461071d57600080fd5b6106b281610f3c565b6001546001600160a01b0316331461073d57600080fd5b620f424081111561074d57600080fd5b600755565b6003546001600160a01b031681565b6001546001600160a01b0316331461077857600080fd5b600260005414156107d0576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000908155806107e28484610f65565b6001600160a01b039182166000908152601460209081526040808320949093168252929092528120805460ff19166001908117909155905550505050565b60065481565b60125481565b600d5481565b6001546001600160a01b0316331461084957600080fd5b6106b281610ffb565b6001546001600160a01b0316331461086957600080fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60085481565b600f5481565b60155490565b6001546001600160a01b031633146108b457600080fd5b600455565b6001546001600160a01b031633146108d057600080fd5b620f42408111156108e057600080fd5b600f55565b6001546001600160a01b031681565b600b5481565b6002546001600160a01b031681565b6001546001600160a01b0316331461092057600080fd5b6106b28161100f565b6001546001600160a01b0316331461094057600080fd5b620f424081111561095057600080fd5b600c55565b6001546001600160a01b0316331461096c57600080fd5b600555565b6001546001600160a01b0316331461098857600080fd5b6001811015801561099b5750619d808111155b6109a457600080fd5b601255565b601460209081526000928352604080842090915290825290205460ff1681565b6001546001600160a01b031633146109e057600080fd5b6107d0811015806109ef575080155b6109f857600080fd5b601055565b60055481565b6001546001600160a01b03163314610a1a57600080fd5b612710811115610a2957600080fd5b600d55565b7f00000000000000000000000028cb7e841ee97947a86b06fa4090c8451f64c0be81565b6001546001600160a01b03163314610a6957600080fd5b6001600160a01b038116610a7c57600080fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6001546001600160a01b03163314610ad957600080fd5b6064811115610ae757600080fd5b601155565b60105481565b60045481565b60075481565b60136020908152600092835260408084209091529082529020546001600160a01b031681565b6001546001600160a01b03163314610b3b57600080fd5b600655565b600060026000541415610b9a576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556001546001600160a01b0316331415610bb757600080fd5b6001600160a01b03871615801590610bd757506001600160a01b03851615155b610be057600080fd5b600080610bed8988610f65565b6001600160a01b03808316600090815260146020908152604080832093851683529290522054919350915060ff16610d4b577f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316876001600160a01b03161480610c9057507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316876001600160a01b0316145b610c9957600080fd5b600a54851015610ca857600080fd5b6003546040805163750c450d60e01b81526001600160a01b038a81166004830152602482018a90529151600093929092169163750c450d91604480820192602092909190829003018186803b158015610d0057600080fd5b505afa158015610d14573d6000803e3d6000fd5b505050506040513d6020811015610d2a57600080fd5b5051600854909150811015610d3e57600080fd5b610d49858288611023565b505b610d558282611544565b6001600160a01b0380841660009081526014602090815260408083209386168352929052205490935060ff16158015610d8e5750600086115b8015610d9a5750600085115b15610ea157610dab8933858b6117b9565b610db7873385896117b9565b604080516335313c2160e11b815233600482015290516000916001600160a01b03861691636a6278429160248082019260209290919082900301818787803b158015610e0257600080fd5b505af1158015610e16573d6000803e3d6000fd5b505050506040513d6020811015610e2c57600080fd5b50516040805163738a1aa960e11b8152336004820152602481018990526044810183905290519192506001600160a01b0386169163e71435529160648082019260009290919082900301818387803b158015610e8757600080fd5b505af1158015610e9b573d6000803e3d6000fd5b50505050505b505060016000559695505050505050565b600c5481565b6001546001600160a01b03163314610ecf57600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314610f0857600080fd5b612710811115610f1757600080fd5b600e55565b60115481565b60095481565b600854811015610f3757600080fd5b600955565b600954811115610f4b57600080fd5b8015610f60576103e8811015610f6057600080fd5b600855565b600080826001600160a01b0316846001600160a01b03161415610f8757600080fd5b826001600160a01b0316846001600160a01b031610610fa7578284610faa565b83835b90925090506001600160a01b038216610fc257600080fd5b6001600160a01b03828116600090815260136020908152604080832085851684529091529020541615610ff457600080fd5b9250929050565b600b5481111561100a57600080fd5b600a55565b600a5481101561101e57600080fd5b600b55565b7f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316836001600160a01b0316148061109457507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316836001600160a01b0316145b806110d057507f00000000000000000000000028cb7e841ee97947a86b06fa4090c8451f64c0be6001600160a01b0316836001600160a01b0316145b6110d957600080fd5b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316846001600160a01b031614156111c2576003546004805460408051630f2008f560e31b81526001600160a01b037f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca811694820194909452602481019290925251919092169163790047a8916044808301926020929190829003018186803b15801561118f57600080fd5b505afa1580156111a3573d6000803e3d6000fd5b505050506040513d60208110156111b957600080fd5b505190506113bd565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316846001600160a01b031614156112745760035460055460408051630f2008f560e31b81526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28116600483015260248201939093529051919092169163790047a8916044808301926020929190829003018186803b15801561118f57600080fd5b7f00000000000000000000000028cb7e841ee97947a86b06fa4090c8451f64c0be6001600160a01b0316846001600160a01b031614156113bd57600360009054906101000a90046001600160a01b03166001600160a01b031663a2e620456040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156112fe57600080fd5b505af1158015611312573d6000803e3d6000fd5b505060035460065460408051630f2008f560e31b81526001600160a01b037f00000000000000000000000028cb7e841ee97947a86b06fa4090c8451f64c0be811660048301526024820193909352905191909216935063790047a892506044808301926020929190829003018186803b15801561138e57600080fd5b505afa1580156113a2573d6000803e3d6000fd5b505050506040513d60208110156113b857600080fd5b505190505b60006008546009541115611412576008546009546113e09163ffffffff61190e16565b6114076113f86008548761190e90919063ffffffff16565b600c549063ffffffff61196416565b8161140e57fe5b0490505b600a54600b54111561148c57611489611438600a54600b5461190e90919063ffffffff16565b611473611450600a548761190e90919063ffffffff16565b600c5461146790620f42409063ffffffff61190e16565b9063ffffffff61196416565b8161147a57fe5b8391900463ffffffff6119c716565b90505b6000620f42406114b26114a5828563ffffffff61190e16565b859063ffffffff61196416565b816114b957fe5b0490506114fd8633600260009054906101000a90046001600160a01b0316620f42406114f06007548761196490919063ffffffff16565b816114f757fe5b046117b9565b60015460075461153c91889133916001600160a01b031690620f4240906114f09061152f90839063ffffffff61190e16565b879063ffffffff61196416565b505050505050565b600060606040518060200161155890611a16565b6020820181038252601f19601f8201166040525090506000848460405160200180836001600160a01b03166001600160a01b031660601b8152601401826001600160a01b03166001600160a01b031660601b815260140192505050604051602081830303815290604052805190602001209050808251602084016000f592505050806001600160a01b0316631794bb3c84847f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316876001600160a01b0316148061165b57507f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316866001600160a01b0316145b61166757600e5461166b565b600d545b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b1580156116d357600080fd5b505af11580156116e7573d6000803e3d6000fd5b505050506001600160a01b03838116600081815260136020818152604080842088871680865290835281852080549789166001600160a01b031998891681179091559383528185208686528352818520805488168517905560158054600181018255958190527f55f448fdea98c4d29eb340757ef0a66cd03dbb9538908a6a81d96026b71ec47590950180549097168417909655925483519283529082015281517f0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9929181900390910190a392915050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b6020831061183e5780518252601f19909201916020918201910161181f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146118a0576040519150601f19603f3d011682016040523d82523d6000602084013e6118a5565b606091505b50915091508180156118d35750805115806118d357508080602001905160208110156118d057600080fd5b50515b61153c5760405162461bcd60e51b81526004018080602001828103825260248152602001806148826024913960400191505060405180910390fd5b8082038281111561195e576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b92915050565b600081158061197f5750508082028282828161197c57fe5b04145b61195e576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b8082018281101561195e576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b612e5e80611a248339019056fe608060405234801561001057600080fd5b506001600055600880546001600160a01b031916331790556040514690806052612e0c823960408051918290036052018220828201825260118352702634b735a9bbb0b8102628102a37b5b2b760791b6020938401528151808301835260018152603160f81b908401528151808401919091527f0ca3509544dff675980d1d1ad68e7359d3dc13a567d0450acb908d532d2b0549818301527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015260808101949094523060a0808601919091528151808603909101815260c09094019052825192019190912060045550612d008061010c6000396000f3fe608060405234801561001057600080fd5b50600436106102275760003560e01c80635f2dd7a711610130578063a9059cbb116100b8578063d505accf1161007c578063d505accf1461066e578063dd62ed3e146106bf578063e3956ed0146106ed578063e7143552146106f5578063fff6cae91461072757610227565b8063a9059cbb14610604578063ba9a7a5614610630578063bc25cf7714610638578063c45a01551461065e578063d21220a71461066657610227565b80637b1a201a116100ff5780637b1a201a146105695780637ecebe001461058f57806389afcb44146105b557806395d89b41146105f4578063a69df4b5146105fc57610227565b80635f2dd7a71461050d5780636a6278421461051557806370a082311461053b5780637464fc3d1461056157610227565b806318160ddd116101b3578063313ce56711610182578063313ce567146104b15780633644e515146104cf5780634d76a106146104d75780635909c0d5146104fd5780635a3d54931461050557610227565b806318160ddd1461046357806323b872dd1461046b5780632a324027146104a157806330adf81f146104a957610227565b8063095ea7b3116101fa578063095ea7b3146103895780630c615ee9146103c95780630dfe1681146103e65780631338736f1461040a5780631794bb3c1461042d57610227565b8063022c0d9f1461022c57806302e028f3146102ba57806306fdde03146102d45780630902f1ac14610351575b600080fd5b6102b86004803603608081101561024257600080fd5b8135916020810135916001600160a01b03604083013516919081019060808101606082013564010000000081111561027957600080fd5b82018360208201111561028b57600080fd5b803590602001918460018302840111640100000000831117156102ad57600080fd5b50909250905061072f565b005b6102c2610faa565b60408051918252519081900360200190f35b6102dc610fb0565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103165781810151838201526020016102fe565b50505050905090810190601f1680156103435780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610359610fdd565b604080516001600160701b03948516815292909316602083015263ffffffff168183015290519081900360600190f35b6103b56004803603604081101561039f57600080fd5b506001600160a01b038135169060200135611007565b604080519115158252519081900360200190f35b6102b8600480360360208110156103df57600080fd5b503561101e565b6103ee6110f2565b604080516001600160a01b039092168252519081900360200190f35b6102b86004803603604081101561042057600080fd5b5080359060200135611101565b6102b86004803603606081101561044357600080fd5b506001600160a01b03813581169160208101359091169060400135611110565b6102c2611196565b6103b56004803603606081101561048157600080fd5b506001600160a01b0381358116916020810135909116906040013561119c565b6102c2611236565b6102c261123c565b6104b9611260565b6040805160ff9092168252519081900360200190f35b6102c2611265565b6102c2600480360360208110156104ed57600080fd5b50356001600160a01b031661126b565b6102c261127d565b6102c2611283565b6102c2611289565b6102c26004803603602081101561052b57600080fd5b50356001600160a01b031661128f565b6102c26004803603602081101561055157600080fd5b50356001600160a01b031661158a565b6102c261159c565b6102c26004803603602081101561057f57600080fd5b50356001600160a01b03166115a2565b6102c2600480360360208110156105a557600080fd5b50356001600160a01b03166115b4565b6105db600480360360208110156105cb57600080fd5b50356001600160a01b03166115c6565b6040805192835260208301919091528051918290030190f35b6102dc611967565b6102b8611987565b6103b56004803603604081101561061a57600080fd5b506001600160a01b038135169060200135611a60565b6102c2611a6d565b6102b86004803603602081101561064e57600080fd5b50356001600160a01b0316611a73565b6103ee611bd9565b6103ee611be8565b6102b8600480360360e081101561068457600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135611bf7565b6102c2600480360360408110156106d557600080fd5b506001600160a01b0381358116916020013516611df4565b6102c2611e11565b6102b86004803603606081101561070b57600080fd5b506001600160a01b038135169060208101359060400135611e17565b6102b8611e78565b60026000541415610775576040805162461bcd60e51b815260206004820152601f6024820152600080516020612c67833981519152604482015290519081900360640190fd5b6002600055841515806107885750600084115b6107d9576040805162461bcd60e51b815260206004820181905260248201527f506169723a20494e53554646494349454e545f4f55545055545f414d4f554e54604482015290519081900360640190fd5b6000806107e4610fdd565b5091509150816001600160701b0316871080156108095750806001600160701b031686105b61085a576040805162461bcd60e51b815260206004820152601c60248201527f506169723a20494e53554646494349454e545f4c495155494449545900000000604482015290519081900360640190fd5b600954600a5460009182916001600160a01b039182169190811690891682148015906108985750806001600160a01b0316896001600160a01b031614155b6108dc576040805162461bcd60e51b815260206004820152601060248201526f506169723a20494e56414c49445f544f60801b604482015290519081900360640190fd5b8a156108ed576108ed828a8d611fd5565b89156108fe576108fe818a8c611fd5565b86156109b957886001600160a01b0316631bd7dbe7338d8d8c8c6040518663ffffffff1660e01b815260040180866001600160a01b03166001600160a01b03168152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509650505050505050600060405180830381600087803b1580156109a057600080fd5b505af11580156109b4573d6000803e3d6000fd5b505050505b604080516370a0823160e01b815230600482015290516001600160a01b038416916370a08231916024808301926020929190829003018186803b1580156109ff57600080fd5b505afa158015610a13573d6000803e3d6000fd5b505050506040513d6020811015610a2957600080fd5b5051604080516370a0823160e01b815230600482015290519195506001600160a01b038316916370a0823191602480820192602092909190829003018186803b158015610a7557600080fd5b505afa158015610a89573d6000803e3d6000fd5b505050506040513d6020811015610a9f57600080fd5b50516008546040805163f481e71b60e01b815290519295506000926001600160a01b039092169163f481e71b91600480820192602092909190829003018186803b158015610aec57600080fd5b505afa158015610b00573d6000803e3d6000fd5b505050506040513d6020811015610b1657600080fd5b50511115610da757600083610b3986670de0b6b3a764000063ffffffff61216716565b81610b4057fe5b04905060115460001415610b5c57601181905543601055610da3565b600043610beb600860009054906101000a90046001600160a01b03166001600160a01b0316633314dd696040518163ffffffff1660e01b815260040160206040518083038186803b158015610bb057600080fd5b505afa158015610bc4573d6000803e3d6000fd5b505050506040513d6020811015610bda57600080fd5b50516010549063ffffffff6121ca16565b109050600081610bfd57601154610c01565b6012545b90506064610ca0610c93600860009054906101000a90046001600160a01b03166001600160a01b031663f481e71b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c5957600080fd5b505afa158015610c6d573d6000803e3d6000fd5b505050506040513d6020811015610c8357600080fd5b505160649063ffffffff61221916565b839063ffffffff61216716565b81610ca757fe5b048310158015610d4e57506064610d42610c93600860009054906101000a90046001600160a01b03166001600160a01b031663f481e71b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0857600080fd5b505afa158015610d1c573d6000803e3d6000fd5b505050506040513d6020811015610d3257600080fd5b505160649063ffffffff6121ca16565b81610d4957fe5b048311155b610d90576040805162461bcd60e51b815260206004820152600e60248201526d506169723a20536c69704c6f636b60901b604482015290519081900360640190fd5b8115610da0576011839055436010555b50505b6012555b5050600089856001600160701b0316038311610dc4576000610dd3565b89856001600160701b03160383035b9050600089856001600160701b0316038311610df0576000610dff565b89856001600160701b03160383035b90506000821180610e105750600081115b610e61576040805162461bcd60e51b815260206004820152601f60248201527f506169723a20494e53554646494349454e545f494e5055545f414d4f554e5400604482015290519081900360640190fd5b6000610e9a610e7b600f548561216790919063ffffffff16565b610e8e87620f424063ffffffff61216716565b9063ffffffff61221916565b90506000610eb6610e7b600f548561216790919063ffffffff16565b9050610ee964e8d4a51000610edd6001600160701b038b8116908b1663ffffffff61216716565b9063ffffffff61216716565b610ef9838363ffffffff61216716565b1015610f36576040805162461bcd60e51b8152602060048201526007602482015266506169723a204b60c81b604482015290519081900360640190fd5b5050610f4484848888612269565b60408051838152602081018390528082018d9052606081018c905290516001600160a01b038b169133917fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229181900360800190a350506001600055505050505050505050565b60115481565b604051806040016040528060118152602001702634b735a9bbb0b8102628102a37b5b2b760791b81525081565b600b546001600160701b0380821692600160701b830490911691600160e01b900463ffffffff1690565b6000611014338484612429565b5060015b92915050565b600860009054906101000a90046001600160a01b03166001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b15801561106c57600080fd5b505afa158015611080573d6000803e3d6000fd5b505050506040513d602081101561109657600080fd5b50516001600160a01b031633146110e6576040805162461bcd60e51b815260206004820152600f60248201526e2830b4b91d102327a92124a22222a760891b604482015290519081900360640190fd5b6110ef8161248b565b50565b6009546001600160a01b031681565b61110c3383836124d1565b5050565b6008546001600160a01b03163314611161576040805162461bcd60e51b815260206004820152600f60248201526e2830b4b91d102327a92124a22222a760891b604482015290519081900360640190fd5b600980546001600160a01b039485166001600160a01b031991821617909155600a805493909416921691909117909155600f55565b60015481565b6001600160a01b038316600090815260036020908152604080832033845290915281205460001914611221576001600160a01b03841660009081526003602090815260408083203384529091529020546111fc908363ffffffff61221916565b6001600160a01b03851660009081526003602090815260408083203384529091529020555b61122c8484846126b4565b5060019392505050565b600f5481565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60045481565b60066020526000908152604090205481565b600c5481565b600d5481565b60105481565b6000600260005414156112d7576040805162461bcd60e51b815260206004820152601f6024820152600080516020612c67833981519152604482015290519081900360640190fd5b60026000908155806112e7610fdd565b50600954604080516370a0823160e01b815230600482015290519395509193506000926001600160a01b03909116916370a08231916024808301926020929190829003018186803b15801561133b57600080fd5b505afa15801561134f573d6000803e3d6000fd5b505050506040513d602081101561136557600080fd5b5051600a54604080516370a0823160e01b815230600482015290519293506000926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b1580156113b857600080fd5b505afa1580156113cc573d6000803e3d6000fd5b505050506040513d60208110156113e257600080fd5b505190506000611401836001600160701b03871663ffffffff61221916565b9050600061141e836001600160701b03871663ffffffff61221916565b9050600061142c878761276e565b60015490915080611469576114556103e8610e8e611450878763ffffffff61216716565b612a6e565b985061146460006103e8612ac0565b6114b8565b6114b56001600160701b038916611486868463ffffffff61216716565b8161148d57fe5b046001600160701b0389166114a8868563ffffffff61216716565b816114af57fe5b04612b57565b98505b600089116114f75760405162461bcd60e51b8152600401808060200182810382526023815260200180612c446023913960400191505060405180910390fd5b6115018a8a612ac0565b61150d86868a8a612269565b811561153d57600b54611539906001600160701b0380821691600160701b90041663ffffffff61216716565b600e555b6040805185815260208101859052815133927f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f928290030190a25050600160005550949695505050505050565b60026020526000908152604090205481565b600e5481565b60076020526000908152604090205481565b60056020526000908152604090205481565b6000806002600054141561160f576040805162461bcd60e51b815260206004820152601f6024820152600080516020612c67833981519152604482015290519081900360640190fd5b600260009081558061161f610fdd565b50600954600a54604080516370a0823160e01b815230600482015290519496509294506001600160a01b039182169391169160009184916370a08231916024808301926020929190829003018186803b15801561167b57600080fd5b505afa15801561168f573d6000803e3d6000fd5b505050506040513d60208110156116a557600080fd5b5051604080516370a0823160e01b815230600482015290519192506000916001600160a01b038516916370a08231916024808301926020929190829003018186803b1580156116f357600080fd5b505afa158015611707573d6000803e3d6000fd5b505050506040513d602081101561171d57600080fd5b50513060009081526002602052604081205491925061173c888861276e565b60015490915080611753848763ffffffff61216716565b8161175a57fe5b049a508061176e848663ffffffff61216716565b8161177557fe5b04995060008b118015611788575060008a115b6117c35760405162461bcd60e51b8152600401808060200182810382526023815260200180612c876023913960400191505060405180910390fd5b6117cd3084612b6f565b6117d8878d8d611fd5565b6117e3868d8c611fd5565b604080516370a0823160e01b815230600482015290516001600160a01b038916916370a08231916024808301926020929190829003018186803b15801561182957600080fd5b505afa15801561183d573d6000803e3d6000fd5b505050506040513d602081101561185357600080fd5b5051604080516370a0823160e01b815230600482015290519196506001600160a01b038816916370a0823191602480820192602092909190829003018186803b15801561189f57600080fd5b505afa1580156118b3573d6000803e3d6000fd5b505050506040513d60208110156118c957600080fd5b505193506118d985858b8b612269565b811561190957600b54611905906001600160701b0380821691600160701b90041663ffffffff61216716565b600e555b604080518c8152602081018c905281516001600160a01b038f169233927fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496929081900390910190a35050505050505050506001600081905550915091565b6040518060400160405280600481526020016304c534c560e41b81525081565b336000908152600660205260409020544210156119e1576040805162461bcd60e51b8152602060048201526013602482015272506169723a204245464f52455f45585049525960681b604482015290519081900360640190fd5b336000818152600760205260409020546119fc9130916126b4565b3360008181526007602090815260409182902054825190815291517f6381d9813cabeb57471b5a7e05078e64845ccdb563146a6911d536f24ce960f19281900390910190a23360009081526007602090815260408083208390556006909152812055565b60006110143384846126b4565b6103e881565b60026000541415611ab9576040805162461bcd60e51b815260206004820152601f6024820152600080516020612c67833981519152604482015290519081900360640190fd5b6002600055600954600a54600b54604080516370a0823160e01b815230600482015290516001600160a01b039485169490931692611b689285928792611b63926001600160701b03169185916370a0823191602480820192602092909190829003018186803b158015611b2b57600080fd5b505afa158015611b3f573d6000803e3d6000fd5b505050506040513d6020811015611b5557600080fd5b50519063ffffffff61221916565b611fd5565b600b54604080516370a0823160e01b81523060048201529051611bcf9284928792611b6392600160701b90046001600160701b0316916001600160a01b038616916370a0823191602480820192602092909190829003018186803b158015611b2b57600080fd5b5050600160005550565b6008546001600160a01b031681565b600a546001600160a01b031681565b42841015611c3c576040805162461bcd60e51b815260206004820152600d60248201526c14185a5c8e8811561412549151609a1b604482015290519081900360640190fd5b6004546001600160a01b0380891660008181526005602090815260408083208054600180820190925582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958d166060860152608085018c905260a085019590955260c08085018b90528151808603909101815260e08501825280519083012061190160f01b6101008601526101028501969096526101228085019690965280518085039096018652610142840180825286519683019690962095839052610162840180825286905260ff89166101828501526101a284018890526101c28401879052519193926101e280820193601f1981019281900390910190855afa158015611d57573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590611d8d5750886001600160a01b0316816001600160a01b0316145b611dde576040805162461bcd60e51b815260206004820152601760248201527f506169723a20494e56414c49445f5349474e4154555245000000000000000000604482015290519081900360640190fd5b611de9898989612429565b505050505050505050565b600360209081526000928352604080842090915290825290205481565b60125481565b6008546001600160a01b03163314611e68576040805162461bcd60e51b815260206004820152600f60248201526e2830b4b91d102327a92124a22222a760891b604482015290519081900360640190fd5b611e738383836124d1565b505050565b60026000541415611ebe576040805162461bcd60e51b815260206004820152601f6024820152600080516020612c67833981519152604482015290519081900360640190fd5b6002600055600954604080516370a0823160e01b81523060048201529051611fce926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611f0f57600080fd5b505afa158015611f23573d6000803e3d6000fd5b505050506040513d6020811015611f3957600080fd5b5051600a54604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015611f8657600080fd5b505afa158015611f9a573d6000803e3d6000fd5b505050506040513d6020811015611fb057600080fd5b5051600b546001600160701b0380821691600160701b900416612269565b6001600055565b604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b1781529251815160009460609489169392918291908083835b602083106120825780518252601f199092019160209182019101612063565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146120e4576040519150601f19603f3d011682016040523d82523d6000602084013e6120e9565b606091505b5091509150818015612117575080511580612117575080806020019051602081101561211457600080fd5b50515b612160576040805162461bcd60e51b815260206004820152601560248201527414185a5c8e881514905394d1915497d19052531151605a1b604482015290519081900360640190fd5b5050505050565b60008115806121825750508082028282828161217f57fe5b04145b611018576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b80820182811015611018576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b80820382811115611018576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b6001600160701b03841180159061228757506001600160701b038311155b6122c9576040805162461bcd60e51b815260206004820152600e60248201526d506169723a204f564552464c4f5760901b604482015290519081900360640190fd5b600b5463ffffffff42811691600160e01b900481168203908116158015906122f957506001600160701b03841615155b801561230d57506001600160701b03831615155b1561237e578063ffffffff1661233b8561232686612c0c565b6001600160e01b03169063ffffffff612c1e16565b600c80546001600160e01b03929092169290920201905563ffffffff81166123668461232687612c0c565b600d80546001600160e01b0392909216929092020190555b600b80546dffffffffffffffffffffffffffff19166001600160701b03888116919091176dffffffffffffffffffffffffffff60701b1916600160701b8883168102919091176001600160e01b0316600160e01b63ffffffff871602179283905560408051848416815291909304909116602082015281517f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1929181900390910190a1505050505050565b6001600160a01b03808416600081815260036020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6127108111156124cc5760405162461bcd60e51b8152600401808060200182810382526021815260200180612caa6021913960400191505060405180910390fd5b600f55565b811580156124dd575080155b156124e757611e73565b6001600160a01b0383166000908152600660205260409020546125dc5760008211612559576040805162461bcd60e51b815260206004820152601860248201527f506169723a205a45524f5f4c4f434b55505f504552494f440000000000000000604482015290519081900360640190fd5b600081116125ae576040805162461bcd60e51b815260206004820152601860248201527f506169723a205a45524f5f4c4f434b55505f414d4f554e540000000000000000604482015290519081900360640190fd5b6125be428363ffffffff6121ca16565b6001600160a01b03841660009081526006602052604090205561261f565b6001600160a01b038316600090815260066020526040902054612605908363ffffffff6121ca16565b6001600160a01b0384166000908152600660205260409020555b6001600160a01b038316600090815260076020526040902054612648908263ffffffff6121ca16565b6001600160a01b03841660009081526007602052604090205561266c8330836126b4565b604080518381526020810183905281516001600160a01b038616927f49eaf4942f1237055eb4cfa5f31c9dfe50d5b4ade01e021f7de8be2fbbde557b928290030190a2505050565b6001600160a01b0383166000908152600260205260409020546126dd908263ffffffff61221916565b6001600160a01b038085166000908152600260205260408082209390935590841681522054612712908263ffffffff6121ca16565b6001600160a01b0380841660008181526002602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600080600860009054906101000a90046001600160a01b03166001600160a01b031663bdc886516040518163ffffffff1660e01b815260040160206040518083038186803b1580156127bf57600080fd5b505afa1580156127d3573d6000803e3d6000fd5b505050506040513d60208110156127e957600080fd5b5051600e5481158015945091925090612a5a578015612a555760006128236114506001600160701b0388811690881663ffffffff61216716565b9050600061283083612a6e565b905080821115612a5257600061287f612851836103e863ffffffff61216716565b612873612866886103e863ffffffff61221916565b869063ffffffff61216716565b9063ffffffff6121ca16565b6128a76103e8610edd612898878763ffffffff61221916565b6001549063ffffffff61216716565b816128ae57fe5b0490508015612a505760085460408051632ad56a9b60e11b815290516001600160a01b039092169160009183916355aad53691600480820192602092909190829003018186803b15801561290157600080fd5b505afa158015612915573d6000803e3d6000fd5b505050506040513d602081101561292b57600080fd5b5051604080516361d027b360e01b815290519192506129c1916001600160a01b038516916361d027b3916004808301926020929190829003018186803b15801561297457600080fd5b505afa158015612988573d6000803e3d6000fd5b505050506040513d602081101561299e57600080fd5b5051620f42406129b4868563ffffffff61216716565b816129bb57fe5b04612ac0565b612a4d826001600160a01b0316635aa6e6756040518163ffffffff1660e01b815260040160206040518083038186803b1580156129fd57600080fd5b505afa158015612a11573d6000803e3d6000fd5b505050506040513d6020811015612a2757600080fd5b5051620f42406129b4612a40828663ffffffff61221916565b879063ffffffff61216716565b50505b505b50505b612a66565b8015612a66576000600e555b505092915050565b60006003821115612ab1575080600160028204015b81811015612aab57809150600281828581612a9a57fe5b040181612aa357fe5b049050612a83565b50612abb565b8115612abb575060015b919050565b600154612ad3908263ffffffff6121ca16565b6001556001600160a01b038216600090815260026020526040902054612aff908263ffffffff6121ca16565b6001600160a01b03831660008181526002602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000818310612b665781612b68565b825b9392505050565b6001600160a01b038216600090815260026020526040902054612b98908263ffffffff61221916565b6001600160a01b038316600090815260026020526040902055600154612bc4908263ffffffff61221916565b6001556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160701b0316600160701b0290565b60006001600160701b0382166001600160e01b03841681612c3b57fe5b04939250505056fe506169723a20494e53554646494349454e545f4c49515549444954595f4d494e5445445265656e7472616e637947756172643a207265656e7472616e742063616c6c00506169723a20494e53554646494349454e545f4c49515549444954595f4255524e4544506169723a20494e56414c49445f54524144494e475f4645455f50455243454e54a26469706673582212207742272246e025edf55270eafd0a67f4b43dad2a999311f80109becf08cd9fc264736f6c63430006060033454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e7472616374295472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544a2646970667358221220654280381ec72a5a6b159a63ac383be08cf4bcb8e405380c6ea8096863dee8a764736f6c63430006060033