Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- FeeSplitter
- Optimization enabled
- true
- Compiler version
- v0.8.17+commit.8df45f5f
- Optimization runs
- 20000
- EVM Version
- default
- Verified at
- 2023-10-20T00:10:09.300822Z
Constructor Arguments
0x000000000000000000000000bbc56bfdefb90e2f3e67e00e75bef0cd1ed2231e0000000000000000000000003123183dc942fd721899bf589d55baa39753628b00000000000000000000000098bf93ebf5c380c0e6ae8e192a7e2ae08edacc02000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d9000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27000000000000000000000000207e6b4529840a4fd518f73c68bc9c19b2a15944000000000000000000000000476559a5665f8f42402e42b04b0a4cfd6769b7b8
Arg [0] (address) : 0xbbc56bfdefb90e2f3e67e00e75bef0cd1ed2231e
Arg [1] (address) : 0x3123183dc942fd721899bf589d55baa39753628b
Arg [2] (address) : 0x98bf93ebf5c380c0e6ae8e192a7e2ae08edacc02
Arg [3] (address) : 0x165c3410fc91ef562c50559f7d2289febed552d9
Arg [4] (address) : 0xa1077a294dde1b09bb078844df40758a5d0f9a27
Arg [5] (address) : 0x207e6b4529840a4fd518f73c68bc9c19b2a15944
Arg [6] (address) : 0x476559a5665f8f42402e42b04b0a4cfd6769b7b8
Contract source code
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.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].
*/
abstract 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() {
_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 making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
// File: contracts/feesplitter/FeeSplitter.sol
pragma solidity 0.8.17;
interface IFactory {
function getPair(address tokenA, address tokenB) external view returns (address pair);
}
interface IPair {
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function token0() external view returns (address);
}
interface IWPLS {
function withdraw(uint256 amount) external;
}
interface IERC20 {
function approve(address spender, uint256 value) external returns (bool);
}
interface IMint {
function totalSupply() external view returns (uint256);
function burn(uint256 amount) external;
function balanceOf(address account) external view returns (uint256);
}
interface IRouter {
function factory() external pure returns (address);
function swapExactETHForTokens(
uint256 amountOutMin,
address[] memory path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function swapExactTokensForETH(
uint256 amountIn,
uint256 amountOutMin,
address[] memory path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
}
/**
* @title FeeSplitter Contract
* @notice This contract distributes fees generated from token transactions
* to three different addresses according to predefined percentages.
*/
contract FeeSplitter is ReentrancyGuard {
address public vulcan; // "Mintra OA Address"
address public mintStakingAddress;
address public rootAddress;
IMint private mintToken;
IWPLS private wplsToken;
IRouter private router1;
IRouter private router2;
uint256 private router1Fee = 9971; // 0.29%
uint256 private router2Fee = 9971; // 0.29%
address private factoryAddress1;
address private factoryAddress2;
uint256 public maxSlippageBasisPoints = 100; // This is 1% slippage
uint256 public plsAmountForMintBuyAndBurn = 0;
uint256 public lastTimeBuyAndBurnExecutedBlockNumber;
address[] private pathBuyAndBurn = new address[](2);
uint256 private constant THIRTY_THREE_POINT_THREE = 3330; // 33.3%
uint256 public constant BOUNTY_REWARD_BASIS_POINTS = 10; // 0.1%
event BuyBackAndBurn(
uint256 soldPlsAmount,
uint256 boughtMintAmount,
uint256 totalSupplyBefore,
uint256 totalSupplyAfter,
uint256 timestamp
);
modifier onlyVulcan() {
require(msg.sender == vulcan, "Not vulcan");
_;
}
constructor(
address _mintStakingAddress,
address _rootAddress,
address _routerAddress1,
address _routerAddress2,
address _wplsTokenAddress,
address _mintTokenAddress,
address _vulcan
) {
require (_mintStakingAddress != address(0), "_mintStakingAddress is zero");
require(_rootAddress != address(0), "_rootAddress is zero");
require(_routerAddress1 != address(0), "_routerAddress1 cannot be 0");
require(_routerAddress2 != address(0), "_routerAddress2 cannot be 0");
require(_wplsTokenAddress != address(0), "WPLS address cannot be 0");
require(_mintTokenAddress != address(0), "Mint address cannot be 0");
require(_vulcan != address(0), "Vulcan address cannot be 0");
mintStakingAddress = _mintStakingAddress;
rootAddress = _rootAddress;
router1 = IRouter(_routerAddress1);
router2 = IRouter(_routerAddress2);
factoryAddress1 = router1.factory();
factoryAddress2 = router2.factory();
vulcan = _vulcan;
wplsToken = IWPLS(_wplsTokenAddress);
mintToken = IMint(_mintTokenAddress);
pathBuyAndBurn[0] = _wplsTokenAddress;
pathBuyAndBurn[1] = _mintTokenAddress;
}
/**
* @dev Fallback function - accepts incoming PLS.
*/
receive() external payable {
}
/**
* Process the tokens and distribute the rewards. MINT tokens are burned when buybackAndBurn is executed.
*
* @param tokenAddresses[]
* @param amounts[]
*/
function flush(uint256 plsAmountToBuyAndBurnMintWith, bool buyAndBurnIsV1, address[] memory tokenAddresses, uint256[] memory amounts, bool[] memory isV1)
public nonReentrant {
// solhint-disable-next-line avoid-tx-origin
require(msg.sender == tx.origin, "Origin must be a EOA");
processErc20s(tokenAddresses, amounts, isV1);
uint256 plsAmountToDistribute = address(this).balance - plsAmountForMintBuyAndBurn;
// Distribute the rewards
if (plsAmountToDistribute > 1e18) {
(
uint256 _stakingRewardsPls, // amount of tokens for staking rewards
uint256 _buyBackAndBurnPls, // amount of tokens for buyback and burn
uint256 _rootAddressPls, // amount of tokens for root address
uint256 _bounty // amount of tokens for bounty
) = splitRewards(plsAmountToDistribute);
plsAmountForMintBuyAndBurn += _buyBackAndBurnPls;
require (plsAmountForMintBuyAndBurn >= plsAmountToBuyAndBurnMintWith, "MintBurn: PLS amount too high");
// update rewards for the staking contract
(bool successMintStaking, ) = payable(mintStakingAddress).call{value: _stakingRewardsPls}("");
require(successMintStaking, "Sending to mintStaking failed");
// transfer tokens to the root address
(bool successRootAddress, ) = payable(rootAddress).call{value: _rootAddressPls}("");
require(successRootAddress, "Sending to root address failed");
// transfer tokens for the bounty
(bool successBountyAddress, ) = payable(msg.sender).call{value: _bounty}("");
require(successBountyAddress, "Sending to bounty address failed");
// buyback and burn
if (plsAmountForMintBuyAndBurn >= 1e17) {
buybackAndBurn(plsAmountToBuyAndBurnMintWith, buyAndBurnIsV1);
}
}
}
/**
* Iterate through all the erc20's. If it's WPLS, withdraw it. If it's MINT, burn it. If it's anything else, swap it for PLS.
*
* @param tokenAddresses[]
* @param amounts[]
* @param isRouter1Array[]
*/
function processErc20s(address[] memory tokenAddresses, uint256[] memory amounts, bool[] memory isRouter1Array) internal {
address wplsTokenAddress = address(wplsToken);
for (uint256 i = 0; i < tokenAddresses.length; i++) {
uint256 amount = amounts[i];
address tokenAddress = tokenAddresses[i];
bool isRouter1 = isRouter1Array[i];
if (tokenAddress == wplsTokenAddress) {
// withdraw the PLS
wplsToken.withdraw(amount);
} else if (tokenAddress != address(mintToken)) { // Mint tokens are burned when buybackAndBurn is executed
uint256 slippageBasisPoints = calculateSlippageErc20(tokenAddress, amount, isRouter1);
require(
slippageBasisPoints <= maxSlippageBasisPoints,
"Slippage too high"
);
address[] memory path = new address[](2);
path[0] = tokenAddress;
path[1] = wplsTokenAddress;
// Execute the swap
if (isRouter1) {
// Approve the router only the amount needed
IERC20(tokenAddress).approve(address(router1), amount);
router1.swapExactTokensForETH(amount, 0, path, address(this), block.timestamp + 10);
} else {
// Approve the router only the amount needed
IERC20(tokenAddress).approve(address(router2), amount);
router2.swapExactTokensForETH(amount, 0, path, address(this), block.timestamp + 10);
}
}
}
}
/**
* @notice Calculate total available PLS balance and split it into four parts,
* stakingRewards, buybackAndBurn, rootAddress and bounty according to percentage
* @return stakingRewards The amount of PLS for staking rewards
* @return _buybackAndBurn The amount of PLS for buyback and burn
* @return rootAddressPls The amount of PLS for rootAddress
* @return bounty The amount of PLS for bounty
*/
function splitRewards(uint256 availableBalance)
internal
pure
returns (
uint256 stakingRewards,
uint256 _buybackAndBurn,
uint256 rootAddressPls,
uint256 bounty
)
{
if (availableBalance > 1e18) {
bounty = ((availableBalance * BOUNTY_REWARD_BASIS_POINTS ) / 10000);
stakingRewards = ((availableBalance * THIRTY_THREE_POINT_THREE ) / 10000);
_buybackAndBurn = ((availableBalance * THIRTY_THREE_POINT_THREE ) / 10000);
rootAddressPls = availableBalance - (bounty + stakingRewards + _buybackAndBurn);
}
return (stakingRewards, _buybackAndBurn, rootAddressPls, bounty);
}
/**
* Calculate the slippage for a given amount of ERC20Tokens
*
* @param erc20TokenAddress ERC20 Token Address
* @param amountIn Amount of ERC20 Tokens
* @param isRouter1 What router to use
* @return slippageBasisPoints Slippage in basis points
*/
function calculateSlippageErc20(address erc20TokenAddress, uint256 amountIn, bool isRouter1) public view
returns (uint256 slippageBasisPoints) {
address factoryAddress;
if (isRouter1) {
factoryAddress = factoryAddress1;
} else {
factoryAddress = factoryAddress2;
}
IPair pair = IPair(IFactory(factoryAddress).getPair(erc20TokenAddress, address(wplsToken)));
slippageBasisPoints = slippageCalculation(amountIn, pair, erc20TokenAddress, isRouter1);
return slippageBasisPoints;
}
/**
* Calculate the slippage for a given amount of PLS
*
* @param inPls Amount of PLS in
* @param isRouter1 What router to use
* @return slippageBasisPoints Slippage in basis points
*/
function calculateSlippageMintBuyAndBurn(uint256 inPls, bool isRouter1) public view
returns (uint256 slippageBasisPoints ) {
address factoryAddress;
address wplsTokenAddress = address(wplsToken);
if (isRouter1) {
factoryAddress = factoryAddress1;
} else {
factoryAddress = factoryAddress2;
}
IPair pair = IPair(IFactory(factoryAddress).getPair(address(mintToken), wplsTokenAddress));
slippageBasisPoints = slippageCalculation(inPls, pair, wplsTokenAddress, isRouter1);
return slippageBasisPoints;
}
/**
* @dev Execute the buyback and burn
*
* @param plsAmount Amount of PLS to buyback and burn
* @param isRouter1 What router to use
* @return amounts
*/
function buybackAndBurn(uint256 plsAmount, bool isRouter1) internal
returns (uint256[] memory amounts) {
// Do not allow the buyBackAndBurn function to be called more than once per block
require(
block.number != lastTimeBuyAndBurnExecutedBlockNumber,
"MintBurn: Need to wait"
);
uint256 slippageBasisPoints = calculateSlippageMintBuyAndBurn(plsAmount, isRouter1);
require(
slippageBasisPoints <= maxSlippageBasisPoints,
"MintBurn: Slippage too high"
);
if (isRouter1) {
amounts = router1.swapExactETHForTokens{
value: plsAmount
}(0, pathBuyAndBurn, address(this), block.timestamp + 10);
} else {
amounts = router2.swapExactETHForTokens{
value: plsAmount
}(0, pathBuyAndBurn, address(this), block.timestamp + 10);
}
// Adjust how much PLS is left to buy and burn
plsAmountForMintBuyAndBurn = plsAmountForMintBuyAndBurn - plsAmount;
uint256 mintBalance = mintToken.balanceOf(address(this));
uint256 mintTotalSupplyBefore = mintToken.totalSupply();
if (mintBalance > 0) {
mintToken.burn(mintBalance);
}
uint256 mintTotalSupplyAfter = mintToken.totalSupply();
// Update the last time executed block number
lastTimeBuyAndBurnExecutedBlockNumber = block.number;
emit BuyBackAndBurn(
amounts[0],
amounts[1],
mintTotalSupplyBefore,
mintTotalSupplyAfter,
block.timestamp
);
return amounts;
}
/**
* @dev Calculate the slippage for a given amount of tokens
*
* @param amountIn Amount of tokens to swap
* @param pair Pair address
* @param reserveInAddress Address of the reserve in
* @param isRouter1 What router to use
* @return slippageBasisPoints
*/
function slippageCalculation(uint256 amountIn, IPair pair, address reserveInAddress, bool isRouter1) internal view
returns (uint256 slippageBasisPoints ) {
(uint256 reserve0, uint256 reserve1, ) = pair.getReserves();
(uint256 reserveIn,) = reserveInAddress == pair.token0() ? (reserve0, reserve1) : (reserve1, reserve0);
uint256 fee = isRouter1 ? router1Fee : router2Fee;
uint256 amountToBuyWithMinusFee;
amountToBuyWithMinusFee = (amountIn * fee) / 10000;
slippageBasisPoints = (amountToBuyWithMinusFee * 10000) / reserveIn;
return slippageBasisPoints;
}
/**
* @dev Allow the changing of the max slippage bettween a bounds
* @param _maxSlippageBasisPoints slippage value in basis points
*/
function changeSlippage(uint256 _maxSlippageBasisPoints) external onlyVulcan {
require(_maxSlippageBasisPoints >= 10, "MintBurn: Min Slippage .1%");
require(_maxSlippageBasisPoints <= 1500, "MintBurn: Max Slippage 15%");
maxSlippageBasisPoints = _maxSlippageBasisPoints;
}
/**
* @dev Allow the changing of the router addresses
* @param routerAddress1 Router one address
* @param routerAddress2 Router two address
*/
function changeRouterAddresses(address routerAddress1, address routerAddress2) external onlyVulcan {
require(routerAddress1 != address(0), "Invalid address");
require(routerAddress2 != address(0), "Invalid address");
router1 = IRouter(routerAddress1);
factoryAddress1 = router1.factory();
router2 = IRouter(routerAddress2);
factoryAddress2 = router2.factory();
}
/**
* @dev Allow the changing of the router fees.
* If there is not fee for the given router pass in 1. This will only effect the slippage caculation insignificantly.
*
* @param _router1Fee Router1 fee
* @param _router2Fee Router2 fee
*/
function changeRouterFees(uint256 _router1Fee, uint256 _router2Fee) external onlyVulcan {
require(_router1Fee > 0, "_router1Fee Invalid");
require(_router2Fee > 0, "_router2Fee Invalid");
router1Fee = _router1Fee;
router2Fee = _router2Fee;
}
}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_mintStakingAddress","internalType":"address"},{"type":"address","name":"_rootAddress","internalType":"address"},{"type":"address","name":"_routerAddress1","internalType":"address"},{"type":"address","name":"_routerAddress2","internalType":"address"},{"type":"address","name":"_wplsTokenAddress","internalType":"address"},{"type":"address","name":"_mintTokenAddress","internalType":"address"},{"type":"address","name":"_vulcan","internalType":"address"}]},{"type":"event","name":"BuyBackAndBurn","inputs":[{"type":"uint256","name":"soldPlsAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"boughtMintAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalSupplyBefore","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalSupplyAfter","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"BOUNTY_REWARD_BASIS_POINTS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"slippageBasisPoints","internalType":"uint256"}],"name":"calculateSlippageErc20","inputs":[{"type":"address","name":"erc20TokenAddress","internalType":"address"},{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"bool","name":"isRouter1","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"slippageBasisPoints","internalType":"uint256"}],"name":"calculateSlippageMintBuyAndBurn","inputs":[{"type":"uint256","name":"inPls","internalType":"uint256"},{"type":"bool","name":"isRouter1","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeRouterAddresses","inputs":[{"type":"address","name":"routerAddress1","internalType":"address"},{"type":"address","name":"routerAddress2","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeRouterFees","inputs":[{"type":"uint256","name":"_router1Fee","internalType":"uint256"},{"type":"uint256","name":"_router2Fee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeSlippage","inputs":[{"type":"uint256","name":"_maxSlippageBasisPoints","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"flush","inputs":[{"type":"uint256","name":"plsAmountToBuyAndBurnMintWith","internalType":"uint256"},{"type":"bool","name":"buyAndBurnIsV1","internalType":"bool"},{"type":"address[]","name":"tokenAddresses","internalType":"address[]"},{"type":"uint256[]","name":"amounts","internalType":"uint256[]"},{"type":"bool[]","name":"isV1","internalType":"bool[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastTimeBuyAndBurnExecutedBlockNumber","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxSlippageBasisPoints","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"mintStakingAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"plsAmountForMintBuyAndBurn","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"rootAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"vulcan","inputs":[]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x6126f360088190556009556064600c556000600d556002608081815260e060405290816020016020820280368337505081516200004492600f925060200190620004fa565b503480156200005257600080fd5b506040516200298438038062002984833981016040819052620000759162000598565b60016000556001600160a01b038716620000d65760405162461bcd60e51b815260206004820152601b60248201527f5f6d696e745374616b696e6741646472657373206973207a65726f000000000060448201526064015b60405180910390fd5b6001600160a01b0386166200012e5760405162461bcd60e51b815260206004820152601460248201527f5f726f6f7441646472657373206973207a65726f0000000000000000000000006044820152606401620000cd565b6001600160a01b038516620001865760405162461bcd60e51b815260206004820152601b60248201527f5f726f7574657241646472657373312063616e6e6f74206265203000000000006044820152606401620000cd565b6001600160a01b038416620001de5760405162461bcd60e51b815260206004820152601b60248201527f5f726f7574657241646472657373322063616e6e6f74206265203000000000006044820152606401620000cd565b6001600160a01b038316620002365760405162461bcd60e51b815260206004820152601860248201527f57504c5320616464726573732063616e6e6f74206265203000000000000000006044820152606401620000cd565b6001600160a01b0382166200028e5760405162461bcd60e51b815260206004820152601860248201527f4d696e7420616464726573732063616e6e6f74206265203000000000000000006044820152606401620000cd565b6001600160a01b038116620002e65760405162461bcd60e51b815260206004820152601a60248201527f56756c63616e20616464726573732063616e6e6f7420626520300000000000006044820152606401620000cd565b600280546001600160a01b03808a166001600160a01b0319928316179092556003805489841690831617905560068054888416908316811790915560078054938816939092169290921790556040805163c45a015560e01b8152905163c45a0155916004808201926020929091908290030181865afa1580156200036e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200039491906200062d565b600a80546001600160a01b0319166001600160a01b039283161790556007546040805163c45a015560e01b81529051919092169163c45a01559160048083019260209291908290030181865afa158015620003f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200041991906200062d565b600b80546001600160a01b03199081166001600160a01b039384161790915560018054821684841617905560058054821686841617905560048054909116918416919091179055600f805484919060009062000479576200047962000652565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555081600f600181548110620004bf57620004bf62000652565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050505050505062000668565b82805482825590600052602060002090810192821562000552579160200282015b828111156200055257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200051b565b506200056092915062000564565b5090565b5b8082111562000560576000815560010162000565565b80516001600160a01b03811681146200059357600080fd5b919050565b600080600080600080600060e0888a031215620005b457600080fd5b620005bf886200057b565b9650620005cf602089016200057b565b9550620005df604089016200057b565b9450620005ef606089016200057b565b9350620005ff608089016200057b565b92506200060f60a089016200057b565b91506200061f60c089016200057b565b905092959891949750929550565b6000602082840312156200064057600080fd5b6200064b826200057b565b9392505050565b634e487b7160e01b600052603260045260246000fd5b61230c80620006786000396000f3fe6080604052600436106100d65760003560e01c8063a11e04661161007f578063bec872b011610059578063bec872b01461023a578063bf13d8051461025a578063d40c9d891461027a578063f810d0681461029a57600080fd5b8063a11e0466146101cb578063aaa2b8c8146101f8578063af6df0301461022557600080fd5b80636920c3cf116100b05780636920c3cf1461017357806371e76ec61461019557806380c53dfc146101b557600080fd5b8063065d02de146100e25780632969ca7e1461010b578063331f566e1461015d57600080fd5b366100dd57005b600080fd5b3480156100ee57600080fd5b506100f8600e5481565b6040519081526020015b60405180910390f35b34801561011757600080fd5b506001546101389073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610102565b34801561016957600080fd5b506100f8600c5481565b34801561017f57600080fd5b5061019361018e366004611d81565b6102ba565b005b3480156101a157600080fd5b506101936101b0366004611e86565b610674565b3480156101c157600080fd5b506100f8600d5481565b3480156101d757600080fd5b506002546101389073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020457600080fd5b506003546101389073ffffffffffffffffffffffffffffffffffffffff1681565b34801561023157600080fd5b506100f8600a81565b34801561024657600080fd5b50610193610255366004611ebf565b6109be565b34801561026657600080fd5b50610193610275366004611ed8565b610b1b565b34801561028657600080fd5b506100f8610295366004611efa565b610c7b565b3480156102a657600080fd5b506100f86102b5366004611f3c565b610d74565b6102c2610e90565b333214610330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4f726967696e206d757374206265206120454f4100000000000000000000000060448201526064015b60405180910390fd5b61033b838383610f03565b6000600d544761034b9190611f90565b9050670de0b6b3a76400008111156106625760008060008061036c85611461565b935093509350935082600d60008282546103869190611fa3565b9091555050600d548a11156103f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d696e744275726e3a20504c5320616d6f756e7420746f6f20686967680000006044820152606401610327565b60025460405160009173ffffffffffffffffffffffffffffffffffffffff169086908381818185875af1925050503d8060008114610451576040519150601f19603f3d011682016040523d82523d6000602084013e610456565b606091505b50509050806104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f53656e64696e6720746f206d696e745374616b696e67206661696c65640000006044820152606401610327565b60035460405160009173ffffffffffffffffffffffffffffffffffffffff169085908381818185875af1925050503d806000811461051b576040519150601f19603f3d011682016040523d82523d6000602084013e610520565b606091505b505090508061058b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53656e64696e6720746f20726f6f742061646472657373206661696c656400006044820152606401610327565b604051600090339085908381818185875af1925050503d80600081146105cd576040519150601f19603f3d011682016040523d82523d6000602084013e6105d2565b606091505b505090508061063d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53656e64696e6720746f20626f756e74792061646472657373206661696c65646044820152606401610327565b67016345785d8a0000600d541061065a576106588d8d6114f0565b505b505050505050505b5061066d6001600055565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b73ffffffffffffffffffffffffffffffffffffffff8216610772576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610327565b73ffffffffffffffffffffffffffffffffffffffff81166107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610327565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155604080517fc45a0155000000000000000000000000000000000000000000000000000000008152905163c45a0155916004808201926020929091908290030181865afa158015610886573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108aa9190611fb6565b600a805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155600780549284169290911682179055604080517fc45a0155000000000000000000000000000000000000000000000000000000008152905163c45a0155916004808201926020929091908290030181865afa158015610951573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109759190611fb6565b600b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b600a811015610aaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e744275726e3a204d696e20536c697070616765202e31250000000000006044820152606401610327565b6105dc811115610b16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e744275726e3a204d617820536c697070616765203135250000000000006044820152606401610327565b600c55565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b60008211610c06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f726f757465723146656520496e76616c6964000000000000000000000000006044820152606401610327565b60008111610c70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f726f757465723246656520496e76616c6964000000000000000000000000006044820152606401610327565b600891909155600955565b6000808215610ca35750600a5473ffffffffffffffffffffffffffffffffffffffff16610cbe565b50600b5473ffffffffffffffffffffffffffffffffffffffff165b6005546040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152918216602482015260009183169063e6a4390590604401602060405180830381865afa158015610d38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5c9190611fb6565b9050610d6a85828887611a3f565b9695505050505050565b600554600090819073ffffffffffffffffffffffffffffffffffffffff168315610db857600a5473ffffffffffffffffffffffffffffffffffffffff169150610dd4565b600b5473ffffffffffffffffffffffffffffffffffffffff1691505b600480546040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182169281019290925282811660248301526000919084169063e6a4390590604401602060405180830381865afa158015610e52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e769190611fb6565b9050610e8486828488611a3f565b93505050505b92915050565b600260005403610efc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610327565b6002600055565b60055473ffffffffffffffffffffffffffffffffffffffff1660005b845181101561066d576000848281518110610f3c57610f3c611fda565b602002602001015190506000868381518110610f5a57610f5a611fda565b602002602001015190506000858481518110610f7857610f78611fda565b602002602001015190508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361103e576005546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561102157600080fd5b505af1158015611035573d6000803e3d6000fd5b5050505061144b565b60045473ffffffffffffffffffffffffffffffffffffffff83811691161461144b57600061106d838584610c7b565b9050600c548111156110db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f536c69707061676520746f6f20686967680000000000000000000000000000006044820152606401610327565b604080516002808252606082018352600092602083019080368337019050509050838160008151811061111057611110611fda565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050868160018151811061115e5761115e611fda565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505082156112f5576006546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152602481018790529085169063095ea7b3906044016020604051808303816000875af1158015611217573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123b9190612009565b5060065473ffffffffffffffffffffffffffffffffffffffff166318cbafe5866000843061126a42600a611fa3565b6040518663ffffffff1660e01b815260040161128a959493929190612026565b6000604051808303816000875af11580156112a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526112ef91908101906120b1565b50611448565b6007546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152602481018790529085169063095ea7b3906044016020604051808303816000875af115801561136e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113929190612009565b5060075473ffffffffffffffffffffffffffffffffffffffff166318cbafe586600084306113c142600a611fa3565b6040518663ffffffff1660e01b81526004016113e1959493929190612026565b6000604051808303816000875af1158015611400573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261144691908101906120b1565b505b50505b505050808061145990612142565b915050610f1f565b600080600080670de0b6b3a76400008511156114e957612710611485600a8761217a565b61148f9190612191565b90506127106114a0610d028761217a565b6114aa9190612191565b93506127106114bb610d028761217a565b6114c59190612191565b9250826114d28583611fa3565b6114dc9190611fa3565b6114e69086611f90565b91505b9193509193565b6060600e54430361155d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d696e744275726e3a204e65656420746f2077616974000000000000000000006044820152606401610327565b60006115698484610d74565b9050600c548111156115d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4d696e744275726e3a20536c69707061676520746f6f206869676800000000006044820152606401610327565b82156116975760065473ffffffffffffffffffffffffffffffffffffffff16637ff36ab5856000600f3061160c42600a611fa3565b6040518663ffffffff1660e01b815260040161162b94939291906121cc565b60006040518083038185885af1158015611649573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261169091908101906120b1565b915061174d565b60075473ffffffffffffffffffffffffffffffffffffffff16637ff36ab5856000600f306116c642600a611fa3565b6040518663ffffffff1660e01b81526004016116e594939291906121cc565b60006040518083038185885af1158015611703573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261174a91908101906120b1565b91505b83600d5461175b9190611f90565b600d55600480546040517f70a08231000000000000000000000000000000000000000000000000000000008152309281019290925260009173ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f69190612255565b90506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188b9190612255565b9050811561191657600480546040517f42966c6800000000000000000000000000000000000000000000000000000000815291820184905273ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b1580156118fd57600080fd5b505af1158015611911573d6000803e3d6000fd5b505050505b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a99190612255565b905043600e819055507f2ea8c072b627ef4c43903880f428548c0532eae74e4f1ab05ca4c59a1a4b5266856000815181106119e6576119e6611fda565b602002602001015186600181518110611a0157611a01611fda565b602090810291909101810151604080519384529183015281018490526060810183905242608082015260a00160405180910390a15050505092915050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611a8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab39190612291565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915060008673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b499190611fb6565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614611b82578183611b85565b82825b509050600085611b9757600954611b9b565b6008545b90506000612710611bac838c61217a565b611bb69190612191565b905082611bc58261271061217a565b611bcf9190612191565b9a9950505050505050505050565b8015158114611beb57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611c6457611c64611bee565b604052919050565b600067ffffffffffffffff821115611c8657611c86611bee565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611beb57600080fd5b600082601f830112611cc357600080fd5b81356020611cd8611cd383611c6c565b611c1d565b82815260059290921b84018101918181019086841115611cf757600080fd5b8286015b84811015611d125780358352918301918301611cfb565b509695505050505050565b600082601f830112611d2e57600080fd5b81356020611d3e611cd383611c6c565b82815260059290921b84018101918181019086841115611d5d57600080fd5b8286015b84811015611d12578035611d7481611bdd565b8352918301918301611d61565b600080600080600060a08688031215611d9957600080fd5b85359450602080870135611dac81611bdd565b9450604087013567ffffffffffffffff80821115611dc957600080fd5b818901915089601f830112611ddd57600080fd5b8135611deb611cd382611c6c565b81815260059190911b8301840190848101908c831115611e0a57600080fd5b938501935b82851015611e31578435611e2281611c90565b82529385019390850190611e0f565b975050506060890135925080831115611e4957600080fd5b611e558a848b01611cb2565b94506080890135925080831115611e6b57600080fd5b5050611e7988828901611d1d565b9150509295509295909350565b60008060408385031215611e9957600080fd5b8235611ea481611c90565b91506020830135611eb481611c90565b809150509250929050565b600060208284031215611ed157600080fd5b5035919050565b60008060408385031215611eeb57600080fd5b50508035926020909101359150565b600080600060608486031215611f0f57600080fd5b8335611f1a81611c90565b9250602084013591506040840135611f3181611bdd565b809150509250925092565b60008060408385031215611f4f57600080fd5b823591506020830135611eb481611bdd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610e8a57610e8a611f61565b80820180821115610e8a57610e8a611f61565b600060208284031215611fc857600080fd5b8151611fd381611c90565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561201b57600080fd5b8151611fd381611bdd565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b8181101561208357845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101612051565b505073ffffffffffffffffffffffffffffffffffffffff969096166060850152505050608001529392505050565b600060208083850312156120c457600080fd5b825167ffffffffffffffff8111156120db57600080fd5b8301601f810185136120ec57600080fd5b80516120fa611cd382611c6c565b81815260059190911b8201830190838101908783111561211957600080fd5b928401925b828410156121375783518252928401929084019061211e565b979650505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361217357612173611f61565b5060010190565b8082028115828204841417610e8a57610e8a611f61565b6000826121c7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060808201868352602060808185015281875480845260a0860191508860005282600020935060005b8181101561222857845473ffffffffffffffffffffffffffffffffffffffff16835260019485019492840192016121f6565b505073ffffffffffffffffffffffffffffffffffffffff9690961660408501525050506060015292915050565b60006020828403121561226757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461228c57600080fd5b919050565b6000806000606084860312156122a657600080fd5b6122af8461226e565b92506122bd6020850161226e565b9150604084015163ffffffff81168114611f3157600080fdfea26469706673582212200b0afbf4c10f1b9202fb58aaa6dbfe3cad067d251d89fc1a4b47985fa97600fd64736f6c63430008110033000000000000000000000000bbc56bfdefb90e2f3e67e00e75bef0cd1ed2231e0000000000000000000000003123183dc942fd721899bf589d55baa39753628b00000000000000000000000098bf93ebf5c380c0e6ae8e192a7e2ae08edacc02000000000000000000000000165c3410fc91ef562c50559f7d2289febed552d9000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27000000000000000000000000207e6b4529840a4fd518f73c68bc9c19b2a15944000000000000000000000000476559a5665f8f42402e42b04b0a4cfd6769b7b8
Deployed ByteCode
0x6080604052600436106100d65760003560e01c8063a11e04661161007f578063bec872b011610059578063bec872b01461023a578063bf13d8051461025a578063d40c9d891461027a578063f810d0681461029a57600080fd5b8063a11e0466146101cb578063aaa2b8c8146101f8578063af6df0301461022557600080fd5b80636920c3cf116100b05780636920c3cf1461017357806371e76ec61461019557806380c53dfc146101b557600080fd5b8063065d02de146100e25780632969ca7e1461010b578063331f566e1461015d57600080fd5b366100dd57005b600080fd5b3480156100ee57600080fd5b506100f8600e5481565b6040519081526020015b60405180910390f35b34801561011757600080fd5b506001546101389073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610102565b34801561016957600080fd5b506100f8600c5481565b34801561017f57600080fd5b5061019361018e366004611d81565b6102ba565b005b3480156101a157600080fd5b506101936101b0366004611e86565b610674565b3480156101c157600080fd5b506100f8600d5481565b3480156101d757600080fd5b506002546101389073ffffffffffffffffffffffffffffffffffffffff1681565b34801561020457600080fd5b506003546101389073ffffffffffffffffffffffffffffffffffffffff1681565b34801561023157600080fd5b506100f8600a81565b34801561024657600080fd5b50610193610255366004611ebf565b6109be565b34801561026657600080fd5b50610193610275366004611ed8565b610b1b565b34801561028657600080fd5b506100f8610295366004611efa565b610c7b565b3480156102a657600080fd5b506100f86102b5366004611f3c565b610d74565b6102c2610e90565b333214610330576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4f726967696e206d757374206265206120454f4100000000000000000000000060448201526064015b60405180910390fd5b61033b838383610f03565b6000600d544761034b9190611f90565b9050670de0b6b3a76400008111156106625760008060008061036c85611461565b935093509350935082600d60008282546103869190611fa3565b9091555050600d548a11156103f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d696e744275726e3a20504c5320616d6f756e7420746f6f20686967680000006044820152606401610327565b60025460405160009173ffffffffffffffffffffffffffffffffffffffff169086908381818185875af1925050503d8060008114610451576040519150601f19603f3d011682016040523d82523d6000602084013e610456565b606091505b50509050806104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f53656e64696e6720746f206d696e745374616b696e67206661696c65640000006044820152606401610327565b60035460405160009173ffffffffffffffffffffffffffffffffffffffff169085908381818185875af1925050503d806000811461051b576040519150601f19603f3d011682016040523d82523d6000602084013e610520565b606091505b505090508061058b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f53656e64696e6720746f20726f6f742061646472657373206661696c656400006044820152606401610327565b604051600090339085908381818185875af1925050503d80600081146105cd576040519150601f19603f3d011682016040523d82523d6000602084013e6105d2565b606091505b505090508061063d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53656e64696e6720746f20626f756e74792061646472657373206661696c65646044820152606401610327565b67016345785d8a0000600d541061065a576106588d8d6114f0565b505b505050505050505b5061066d6001600055565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b73ffffffffffffffffffffffffffffffffffffffff8216610772576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610327565b73ffffffffffffffffffffffffffffffffffffffff81166107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610327565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155604080517fc45a0155000000000000000000000000000000000000000000000000000000008152905163c45a0155916004808201926020929091908290030181865afa158015610886573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108aa9190611fb6565b600a805473ffffffffffffffffffffffffffffffffffffffff9283167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155600780549284169290911682179055604080517fc45a0155000000000000000000000000000000000000000000000000000000008152905163c45a0155916004808201926020929091908290030181865afa158015610951573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109759190611fb6565b600b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b600a811015610aaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e744275726e3a204d696e20536c697070616765202e31250000000000006044820152606401610327565b6105dc811115610b16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d696e744275726e3a204d617820536c697070616765203135250000000000006044820152606401610327565b600c55565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4e6f742076756c63616e000000000000000000000000000000000000000000006044820152606401610327565b60008211610c06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f726f757465723146656520496e76616c6964000000000000000000000000006044820152606401610327565b60008111610c70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f726f757465723246656520496e76616c6964000000000000000000000000006044820152606401610327565b600891909155600955565b6000808215610ca35750600a5473ffffffffffffffffffffffffffffffffffffffff16610cbe565b50600b5473ffffffffffffffffffffffffffffffffffffffff165b6005546040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152918216602482015260009183169063e6a4390590604401602060405180830381865afa158015610d38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5c9190611fb6565b9050610d6a85828887611a3f565b9695505050505050565b600554600090819073ffffffffffffffffffffffffffffffffffffffff168315610db857600a5473ffffffffffffffffffffffffffffffffffffffff169150610dd4565b600b5473ffffffffffffffffffffffffffffffffffffffff1691505b600480546040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182169281019290925282811660248301526000919084169063e6a4390590604401602060405180830381865afa158015610e52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e769190611fb6565b9050610e8486828488611a3f565b93505050505b92915050565b600260005403610efc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610327565b6002600055565b60055473ffffffffffffffffffffffffffffffffffffffff1660005b845181101561066d576000848281518110610f3c57610f3c611fda565b602002602001015190506000868381518110610f5a57610f5a611fda565b602002602001015190506000858481518110610f7857610f78611fda565b602002602001015190508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361103e576005546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561102157600080fd5b505af1158015611035573d6000803e3d6000fd5b5050505061144b565b60045473ffffffffffffffffffffffffffffffffffffffff83811691161461144b57600061106d838584610c7b565b9050600c548111156110db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f536c69707061676520746f6f20686967680000000000000000000000000000006044820152606401610327565b604080516002808252606082018352600092602083019080368337019050509050838160008151811061111057611110611fda565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050868160018151811061115e5761115e611fda565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505082156112f5576006546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152602481018790529085169063095ea7b3906044016020604051808303816000875af1158015611217573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123b9190612009565b5060065473ffffffffffffffffffffffffffffffffffffffff166318cbafe5866000843061126a42600a611fa3565b6040518663ffffffff1660e01b815260040161128a959493929190612026565b6000604051808303816000875af11580156112a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526112ef91908101906120b1565b50611448565b6007546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152602481018790529085169063095ea7b3906044016020604051808303816000875af115801561136e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113929190612009565b5060075473ffffffffffffffffffffffffffffffffffffffff166318cbafe586600084306113c142600a611fa3565b6040518663ffffffff1660e01b81526004016113e1959493929190612026565b6000604051808303816000875af1158015611400573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261144691908101906120b1565b505b50505b505050808061145990612142565b915050610f1f565b600080600080670de0b6b3a76400008511156114e957612710611485600a8761217a565b61148f9190612191565b90506127106114a0610d028761217a565b6114aa9190612191565b93506127106114bb610d028761217a565b6114c59190612191565b9250826114d28583611fa3565b6114dc9190611fa3565b6114e69086611f90565b91505b9193509193565b6060600e54430361155d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d696e744275726e3a204e65656420746f2077616974000000000000000000006044820152606401610327565b60006115698484610d74565b9050600c548111156115d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4d696e744275726e3a20536c69707061676520746f6f206869676800000000006044820152606401610327565b82156116975760065473ffffffffffffffffffffffffffffffffffffffff16637ff36ab5856000600f3061160c42600a611fa3565b6040518663ffffffff1660e01b815260040161162b94939291906121cc565b60006040518083038185885af1158015611649573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261169091908101906120b1565b915061174d565b60075473ffffffffffffffffffffffffffffffffffffffff16637ff36ab5856000600f306116c642600a611fa3565b6040518663ffffffff1660e01b81526004016116e594939291906121cc565b60006040518083038185885af1158015611703573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261174a91908101906120b1565b91505b83600d5461175b9190611f90565b600d55600480546040517f70a08231000000000000000000000000000000000000000000000000000000008152309281019290925260009173ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa1580156117d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f69190612255565b90506000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188b9190612255565b9050811561191657600480546040517f42966c6800000000000000000000000000000000000000000000000000000000815291820184905273ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b1580156118fd57600080fd5b505af1158015611911573d6000803e3d6000fd5b505050505b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a99190612255565b905043600e819055507f2ea8c072b627ef4c43903880f428548c0532eae74e4f1ab05ca4c59a1a4b5266856000815181106119e6576119e6611fda565b602002602001015186600181518110611a0157611a01611fda565b602090810291909101810151604080519384529183015281018490526060810183905242608082015260a00160405180910390a15050505092915050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611a8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab39190612291565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915060008673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b499190611fb6565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614611b82578183611b85565b82825b509050600085611b9757600954611b9b565b6008545b90506000612710611bac838c61217a565b611bb69190612191565b905082611bc58261271061217a565b611bcf9190612191565b9a9950505050505050505050565b8015158114611beb57600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611c6457611c64611bee565b604052919050565b600067ffffffffffffffff821115611c8657611c86611bee565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611beb57600080fd5b600082601f830112611cc357600080fd5b81356020611cd8611cd383611c6c565b611c1d565b82815260059290921b84018101918181019086841115611cf757600080fd5b8286015b84811015611d125780358352918301918301611cfb565b509695505050505050565b600082601f830112611d2e57600080fd5b81356020611d3e611cd383611c6c565b82815260059290921b84018101918181019086841115611d5d57600080fd5b8286015b84811015611d12578035611d7481611bdd565b8352918301918301611d61565b600080600080600060a08688031215611d9957600080fd5b85359450602080870135611dac81611bdd565b9450604087013567ffffffffffffffff80821115611dc957600080fd5b818901915089601f830112611ddd57600080fd5b8135611deb611cd382611c6c565b81815260059190911b8301840190848101908c831115611e0a57600080fd5b938501935b82851015611e31578435611e2281611c90565b82529385019390850190611e0f565b975050506060890135925080831115611e4957600080fd5b611e558a848b01611cb2565b94506080890135925080831115611e6b57600080fd5b5050611e7988828901611d1d565b9150509295509295909350565b60008060408385031215611e9957600080fd5b8235611ea481611c90565b91506020830135611eb481611c90565b809150509250929050565b600060208284031215611ed157600080fd5b5035919050565b60008060408385031215611eeb57600080fd5b50508035926020909101359150565b600080600060608486031215611f0f57600080fd5b8335611f1a81611c90565b9250602084013591506040840135611f3181611bdd565b809150509250925092565b60008060408385031215611f4f57600080fd5b823591506020830135611eb481611bdd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610e8a57610e8a611f61565b80820180821115610e8a57610e8a611f61565b600060208284031215611fc857600080fd5b8151611fd381611c90565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561201b57600080fd5b8151611fd381611bdd565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b8181101561208357845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101612051565b505073ffffffffffffffffffffffffffffffffffffffff969096166060850152505050608001529392505050565b600060208083850312156120c457600080fd5b825167ffffffffffffffff8111156120db57600080fd5b8301601f810185136120ec57600080fd5b80516120fa611cd382611c6c565b81815260059190911b8201830190838101908783111561211957600080fd5b928401925b828410156121375783518252928401929084019061211e565b979650505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361217357612173611f61565b5060010190565b8082028115828204841417610e8a57610e8a611f61565b6000826121c7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060808201868352602060808185015281875480845260a0860191508860005282600020935060005b8181101561222857845473ffffffffffffffffffffffffffffffffffffffff16835260019485019492840192016121f6565b505073ffffffffffffffffffffffffffffffffffffffff9690961660408501525050506060015292915050565b60006020828403121561226757600080fd5b5051919050565b80516dffffffffffffffffffffffffffff8116811461228c57600080fd5b919050565b6000806000606084860312156122a657600080fd5b6122af8461226e565b92506122bd6020850161226e565b9150604084015163ffffffff81168114611f3157600080fdfea26469706673582212200b0afbf4c10f1b9202fb58aaa6dbfe3cad067d251d89fc1a4b47985fa97600fd64736f6c63430008110033