Overview
ETH Balance
ETH Value
$0.00Latest 8 from a total of 8 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Become Controlle... | 5650630 | 587 days ago | IN | 0 ETH | 0.00000155 | ||||
| Set Controller | 5606848 | 588 days ago | IN | 0 ETH | 0.00000276 | ||||
| Create Pair | 5606847 | 588 days ago | IN | 0 ETH | 0.00017545 | ||||
| Become Controlle... | 5606846 | 588 days ago | IN | 0 ETH | 0.0000016 | ||||
| Set Controller | 5604615 | 588 days ago | IN | 0 ETH | 0.00000268 | ||||
| Become Controlle... | 704739 | 824 days ago | IN | 0 ETH | 0.00007995 | ||||
| Set Controller | 675342 | 828 days ago | IN | 0 ETH | 0.00013823 | ||||
| Create Pair | 675342 | 828 days ago | IN | 0 ETH | 0.00882405 |
Latest 17 internal transactions
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 5650648 | 587 days ago | 0 ETH | ||||
| 5606847 | 588 days ago | 0 ETH | ||||
| 5606847 | 588 days ago | 0 ETH | ||||
| 5606847 | 588 days ago | 0 ETH | ||||
| 5606847 | 588 days ago | Contract Creation | 0 ETH | |||
| 5606846 | 588 days ago | 0 ETH | ||||
| 1102815 | 781 days ago | 0 ETH | ||||
| 1059510 | 784 days ago | 0 ETH | ||||
| 1059472 | 784 days ago | 0 ETH | ||||
| 1006950 | 789 days ago | 0 ETH | ||||
| 916576 | 797 days ago | 0 ETH | ||||
| 916398 | 797 days ago | 0 ETH | ||||
| 807432 | 810 days ago | 0 ETH | ||||
| 704750 | 824 days ago | 0 ETH | ||||
| 675342 | 828 days ago | 0 ETH | ||||
| 675342 | 828 days ago | Contract Creation | 0 ETH | |||
| 675342 | 828 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Factory
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.8.17;
// SPDX-License-Identifier: AGPL-3.0-only
import "./Pair.sol";
contract Factory {
address public controller;
address public pendingController;
bool public permissionless;
mapping(address => mapping(address => uint)) public getPairCount;
mapping(address => mapping(address => mapping(uint => address))) public getPair;
address[] public allPairs;
event PairCreated(address indexed token0, address indexed token1, uint id, address pair);
constructor(address _controller) {
require(_controller != address(0), "controller cannot be zero");
controller = _controller;
}
function allPairsLength() external view returns (uint) {
return allPairs.length;
}
function getInitCodeHash() external pure returns (bytes32) {
return keccak256(type(Pair).creationCode);
}
function createPair(address tokenA, address tokenB) external returns (address pair) {
require(permissionless || msg.sender == controller, "forbidden");
require(tokenA != tokenB, "identical addresses");
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0), "zero address");
uint id = ++getPairCount[token0][token1];
bytes32 salt = keccak256(abi.encodePacked(token0, token1, id));
pair = address(new Pair{salt : salt}());
Pair(pair).initialize(token0, token1);
getPair[token0][token1][id - 1] = pair;
allPairs.push(pair);
emit PairCreated(token0, token1, id, pair);
}
function setController(address _controller) external {
require(_controller != address(0), "controller cannot be zero");
require(msg.sender == controller, "forbidden");
pendingController = _controller;
}
function becomeController() external {
require(msg.sender == pendingController, "forbidden");
pendingController = address(0);
controller = msg.sender;
}
function open2public() external {
require(msg.sender == controller, "forbidden");
permissionless = true;
}
}pragma solidity 0.8.17;
// SPDX-License-Identifier: AGPL-3.0-only
import "interface/IERC20.sol";
import "interface/IFarm.sol";
import "interface/IFactory.sol";
import "./lib/ABDKMath64x64.sol";
import "./lib/SqrtMath.sol";
import "./lib/TransferHelper.sol";
/// @title Fee model for Dyson pair
contract FeeModel {
using ABDKMath64x64 for *;
uint internal constant MAX_FEE_RATIO = 2**64;
/// @dev Fee ratio of token0. Max fee ratio is MAX_FEE_RATIO
uint64 internal feeRatio0;
/// @dev Fee ratio of token1. Max fee ratio is MAX_FEE_RATIO
uint64 internal feeRatio1;
/// @dev Timestamp when fee ratio of token0 last updated
uint64 internal lastUpdateTime0;
/// @dev Timestamp when fee ratio of token1 last updated
uint64 internal lastUpdateTime1;
uint64 public halfLife = 720; // Fee /= 2 every 12 minutes
/// @dev Convenience function to get the stored fee ratio and last update time of token0 and token1
/// @return _feeRatio0 Stored fee ratio of token0
/// @return _feeRatio1 Stored fee ratio of token1
/// @return _lastUpdateTime0 Stored last update time of token0
/// @return _lastUpdateTime1 Stored last update time of token1
function _getFeeRatioStored() internal view returns (uint64 _feeRatio0, uint64 _feeRatio1, uint64 _lastUpdateTime0, uint64 _lastUpdateTime1) {
_feeRatio0 = feeRatio0;
_feeRatio1 = feeRatio1;
_lastUpdateTime0 = lastUpdateTime0;
_lastUpdateTime1 = lastUpdateTime1;
}
/// @dev Pure function to calculate new fee ratio when fee ratio increased
/// Formula shown as below with a as fee ratio before and b as fee ratio added:
/// 1 - (1 - a)(1 - b) = a + b - ab
/// new = before + added - before * added
/// @param _feeRatioBefore Fee ratio before the increase
/// @param _feeRatioAdded Fee ratio increased
/// @return _newFeeRatio New fee ratio
function _calcFeeRatioAdded(uint64 _feeRatioBefore, uint64 _feeRatioAdded) internal pure returns (uint64 _newFeeRatio) {
uint before = uint(_feeRatioBefore);
uint added = uint(_feeRatioAdded);
_newFeeRatio = uint64(before + added - before * added / MAX_FEE_RATIO);
}
/// @dev Update fee ratio and last update timestamp of token0
/// @param _feeRatioBefore Fee ratio before the increase
/// @param _feeRatioAdded Fee ratio increased
function _updateFeeRatio0(uint64 _feeRatioBefore, uint64 _feeRatioAdded) internal {
feeRatio0 = _calcFeeRatioAdded(_feeRatioBefore, _feeRatioAdded);
lastUpdateTime0 = uint64(block.timestamp);
}
/// @dev Update fee ratio and last update timestamp of token1
/// @param _feeRatioBefore Fee ratio before the increase
/// @param _feeRatioAdded Fee ratio increased
function _updateFeeRatio1(uint64 _feeRatioBefore, uint64 _feeRatioAdded) internal {
feeRatio1 = _calcFeeRatioAdded(_feeRatioBefore, _feeRatioAdded);
lastUpdateTime1 = uint64(block.timestamp);
}
/// @notice Fee ratio halve every `halfLife` seconds
/// @dev Calculate new fee ratio as time elapsed
/// newFeeRatio = oldFeeRatio / 2^(elapsedTime / halfLife)
/// @param _oldFeeRatio Fee ratio from last update
/// @param _elapsedTime Time since last update
/// @return _newFeeRatio New fee ratio
function calcNewFeeRatio(uint64 _oldFeeRatio, uint _elapsedTime) public view returns (uint64 _newFeeRatio) {
int128 t = _elapsedTime.divu(halfLife);
int128 r = (-t).exp_2();
_newFeeRatio = uint64(r.mulu(uint(_oldFeeRatio)));
}
/// @notice The fee ratios returned are the stored fee ratios with halving applied
/// @return _feeRatio0 Fee ratio of token0 after halving update
/// @return _feeRatio1 Fee ratio of token1 after halving update
function getFeeRatio() public view returns (uint64 _feeRatio0, uint64 _feeRatio1) {
uint64 _lastUpdateTime0;
uint64 _lastUpdateTime1;
(_feeRatio0, _feeRatio1, _lastUpdateTime0, _lastUpdateTime1) = _getFeeRatioStored();
_feeRatio0 = calcNewFeeRatio(_feeRatio0, block.timestamp - uint(_lastUpdateTime0));
_feeRatio1 = calcNewFeeRatio(_feeRatio1, block.timestamp - uint(_lastUpdateTime1));
}
}
/// @title Contract with basic swap logic and fee mechanism
contract Feeswap is FeeModel {
using TransferHelper for address;
address public token0;
address public token1;
/// @notice Fee recipient
address public feeTo;
/// @dev Used to keep track of fee earned to save gas by not transferring fee away everytime.
/// Need to discount this amount when calculating reserve
uint internal accumulatedFee0;
uint internal accumulatedFee1;
/// @dev Mutex to prevent re-entrancy
uint private unlocked = 1;
/// @notice User's approval nonce
mapping(address => uint256) public nonces;
event Swap(address indexed sender, bool indexed isSwap0, uint amountIn, uint amountOut, address indexed to);
event FeeCollected(uint token0Amt, uint token1Amt);
modifier lock() {
require(unlocked == 1, 'locked');
unlocked = 0;
_;
unlocked = 1;
}
function initialize(address _token0, address _token1) public virtual {
require(token0 == address(0), 'forbidden');
token0 = _token0;
token1 = _token1;
}
function getReserves() public view returns (uint reserve0, uint reserve1) {
reserve0 = IERC20(token0).balanceOf(address(this)) - accumulatedFee0;
reserve1 = IERC20(token1).balanceOf(address(this)) - accumulatedFee1;
}
/// @param input Amount of token0 to swap
/// @param minOutput Minimum amount of token1 expected to receive
/// @return fee Amount of token0 as fee
/// @return output Amount of token1 swapped
function _swap0in(uint input, uint minOutput) internal returns (uint fee, uint output) {
require(input > 0, "invalid input amount");
(uint reserve0, uint reserve1) = getReserves();
(uint64 _feeRatio0, uint64 _feeRatio1) = getFeeRatio();
fee = uint(_feeRatio0) * input / MAX_FEE_RATIO;
uint inputLessFee = input - fee;
output = inputLessFee * reserve1 / (reserve0 + inputLessFee);
require(output >= minOutput, "slippage");
uint64 feeRatioAdded = uint64(output * MAX_FEE_RATIO / reserve1);
_updateFeeRatio1(_feeRatio1, feeRatioAdded);
}
/// @param input Amount of token1 to swap
/// @param minOutput Minimum amount of token0 expected to receive
/// @return fee Amount of token1 as fee
/// @return output Amount of token0 swapped
function _swap1in(uint input, uint minOutput) internal returns (uint fee, uint output) {
require(input > 0, "invalid input amount");
(uint reserve0, uint reserve1) = getReserves();
(uint64 _feeRatio0, uint64 _feeRatio1) = getFeeRatio();
fee = uint(_feeRatio1) * input / MAX_FEE_RATIO;
uint inputLessFee = input - fee;
output = inputLessFee * reserve0 / (reserve1 + inputLessFee);
require(output >= minOutput, "slippage");
uint64 feeRatioAdded = uint64(output * MAX_FEE_RATIO / reserve0);
_updateFeeRatio0(_feeRatio0, feeRatioAdded);
}
/// @notice Perfrom swap from token0 to token1
/// Half of the swap fee goes to `feeTo` if `feeTo` is set
/// @dev Re-entrancy protected
/// @param to Address that receives swapped token1
/// @param input Amount of token0 to swap
/// @param minOutput Minimum amount of token1 expected to receive
/// @return output Amount of token1 swapped
function swap0in(address to, uint input, uint minOutput) external lock returns (uint output) {
uint fee;
(fee, output) = _swap0in(input, minOutput);
if(feeTo != address(0)) accumulatedFee0 += fee / 2;
token0.safeTransferFrom(msg.sender, address(this), input);
token1.safeTransfer(to, output);
emit Swap(msg.sender, true, input, output, to);
}
/// @notice Perfrom swap from token1 to token0
/// Half of the swap fee goes to `feeTo` if `feeTo` is set
/// @dev Re-entrancy protected
/// @param to Address that receives swapped token0
/// @param input Amount of token1 to swap
/// @param minOutput Minimum amount of token0 expected to receive
/// @return output Amount of token0 swapped
function swap1in(address to, uint input, uint minOutput) external lock returns (uint output) {
uint fee;
(fee, output) = _swap1in(input, minOutput);
if(feeTo != address(0)) accumulatedFee1 += fee / 2;
token1.safeTransferFrom(msg.sender, address(this), input);
token0.safeTransfer(to, output);
emit Swap(msg.sender, false, input, output, to);
}
function collectFee() external lock {
_collectFee();
}
function _collectFee() internal {
uint f0 = accumulatedFee0;
uint f1 = accumulatedFee1;
accumulatedFee0 = 0;
accumulatedFee1 = 0;
token0.safeTransfer(feeTo, f0);
token1.safeTransfer(feeTo, f1);
emit FeeCollected(f0, f1);
}
}
/// @title Dyson pair contract
contract Pair is Feeswap {
using SqrtMath for *;
using TransferHelper for address;
/// @dev Square root of `MAX_FEE_RATIO`
uint private constant MAX_FEE_RATIO_SQRT = 2**32;
/// @dev Beware that fee ratio and premium base unit are different
uint private constant PREMIUM_BASE_UNIT = 1e18;
/// @dev For EIP712
bytes32 public immutable DOMAIN_SEPARATOR;
bytes32 public constant APPROVE_TYPEHASH = keccak256("setApprovalForAllWithSig(address owner,address operator,bool approved,uint256 nonce,uint256 deadline)");
/// @notice A note records the amount of token0 or token1 user gets when the user redeem the note
/// and the timestamp when user can redeem.
/// The amount of token0 and token1 include the premium
struct Note {
uint token0Amt;
uint token1Amt;
uint due;
}
/// @dev Factory of this contract
address public factory;
IFarm public farm;
/// @notice Volatility which affects premium and can be set by governance, i.e. controller of factory contract
uint public basis = 0.7e18;
/// @notice Total number of notes created by user
mapping(address => uint) public noteCount;
/// @notice Notes created by user, indexed by note number
mapping(address => mapping(uint => Note)) public notes;
/// @notice Operator is the address that can withdraw note on behalf of user
mapping(address => mapping(address => bool)) public operatorApprovals;
event Deposit(address indexed user, bool indexed isToken0, uint index, uint amountIn, uint token0Amt, uint token1Amt, uint due);
event Withdraw(address indexed user, bool indexed isToken0, uint index, uint amountOut);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
constructor() {
uint chainId;
assembly {
chainId := chainid()
}
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
keccak256(bytes("Pair")),
keccak256(bytes('1')),
chainId,
address(this)
)
);
}
/// @notice Premium = volatility * sqrt(time / 365 days) * 0.4
/// @dev sqrt(time / 365 days) * 0.4 is pre-calculated to save gas.
/// Note that premium could be larger than `PREMIUM_BASE_UNIT`
/// @param time Lock time. It can be either 1 day, 3 days, 7 days or 30 days
/// @return premium Premium
function getPremium(uint time) public view returns (uint premium) {
if(time == 1 days) premium = basis * 20936956903608548 / PREMIUM_BASE_UNIT;
else if(time == 3 days) premium = basis * 36263873112929960 / PREMIUM_BASE_UNIT;
else if(time == 7 days) premium = basis * 55393981177425144 / PREMIUM_BASE_UNIT;
else if(time == 30 days) premium = basis * 114676435816199168 / PREMIUM_BASE_UNIT;
else revert("invalid time");
}
function initialize(address _token0, address _token1) public override {
super.initialize(_token0, _token1);
factory = msg.sender;
}
/// @notice `basis` can only be set by governance, i.e., controller of factory contract
function setBasis(uint _basis) external lock {
require(IFactory(factory).controller() == msg.sender, "forbidden");
basis = _basis;
}
/// @notice `halfLife` can only be set by governance, i.e., controller of factory contract
function setHalfLife(uint64 _halfLife) external lock {
require(IFactory(factory).controller() == msg.sender, "forbidden");
require( _halfLife > 0, "half life cannot be zero");
halfLife = _halfLife;
}
/// @notice `farm` can only be set by governance, i.e., controller of factory contract
function setFarm(address _farm) external lock {
require(IFactory(factory).controller() == msg.sender, "forbidden");
farm = IFarm(_farm);
}
/// @notice `feeTo` can only be set by governance, i.e., controller of factory contract
function setFeeTo(address _feeTo) external lock {
require(IFactory(factory).controller() == msg.sender, "forbidden");
if(feeTo != address(0)) _collectFee();
feeTo = _feeTo;
}
/// @notice rescue token stucked in this contract
/// @param tokenAddress Address of token to be rescued
/// @param to Address that will receive token
/// @param amount Amount of token to be rescued
function rescueERC20(address tokenAddress, address to, uint256 amount) external {
require(IFactory(factory).controller() == msg.sender, "forbidden");
require(tokenAddress != token0);
require(tokenAddress != token1);
tokenAddress.safeTransfer(to, amount);
}
function _addNote(address to, bool depositToken0, uint token0Amt, uint token1Amt, uint time, uint premium) internal {
uint index = noteCount[to]++;
Note storage note = notes[to][index];
uint inputAmt = depositToken0 ? token0Amt : token1Amt;
uint token0AmtWithPremium = token0Amt * (premium + PREMIUM_BASE_UNIT) / PREMIUM_BASE_UNIT;
uint token1AmtWithPremium = token1Amt * (premium + PREMIUM_BASE_UNIT) / PREMIUM_BASE_UNIT;
uint dueTime = block.timestamp + time;
note.token0Amt = token0AmtWithPremium;
note.token1Amt = token1AmtWithPremium;
note.due = dueTime;
emit Deposit(to, depositToken0, index, inputAmt, token0AmtWithPremium, token1AmtWithPremium, dueTime);
}
function _grantSP(address to, uint input, uint output, uint premium) internal {
if(address(farm) != address(0)) {
uint sp = (input * output).sqrt() * premium / PREMIUM_BASE_UNIT;
farm.grantSP(to, sp);
}
}
/// @notice User deposit token0. This function simulates it as `swap0in`
/// but only charges fee base on the fee computed and does not perform actual swap.
/// Half of the swap fee goes to `feeTo` if `feeTo` is set.
/// If `farm` is set, this function also computes the amount of SP for the user and calls `farm.grantSP()`.
/// The amount of SP = sqrt(input * output) * (preium / PREMIUM_BASE_UNIT)
/// @dev Re-entrancy protected
/// @param to Address that owns the note
/// @param input Amount of token0 to deposit
/// @param minOutput Minimum amount of token1 expected to receive if the swap is perfromed
/// @param time Lock time
/// @return output Amount of token1 received if the swap is performed
function deposit0(address to, uint input, uint minOutput, uint time) external lock returns (uint output) {
require(to != address(0), "to cannot be zero");
uint fee;
(fee, output) = _swap0in(input, minOutput);
uint premium = getPremium(time);
_addNote(to, true, input, output, time, premium);
if(feeTo != address(0)) accumulatedFee0 += fee / 2;
token0.safeTransferFrom(msg.sender, address(this), input);
_grantSP(to, input, output, premium);
}
/// @notice User deposit token1. This function simulates it as `swap1in`
/// but only charges fee base on the fee computed and does not perform actual swap.
/// Half of the swap fee goes to `feeTo` if `feeTo` is set.
/// If `farm` is set, this function also computes the amount of SP for the user and calls `farm.grantSP()`.
/// The amount of SP = sqrt(input * output) * (preium / PREMIUM_BASE_UNIT)
/// @dev Re-entrancy protected
/// @param to Address that owns the note
/// @param input Amount of token1 to deposit
/// @param minOutput Minimum amount of token0 expected to receive if the swap is perfromed
/// @param time Lock time
/// @return output Amount of token0 received if the swap is performed
function deposit1(address to, uint input, uint minOutput, uint time) external lock returns (uint output) {
require(to != address(0), "to cannot be zero");
uint fee;
(fee, output) = _swap1in(input, minOutput);
uint premium = getPremium(time);
_addNote(to, false, output, input, time, premium);
if(feeTo != address(0)) accumulatedFee1 += fee / 2;
token1.safeTransferFrom(msg.sender, address(this), input);
_grantSP(to, input, output, premium);
}
/// @notice When withdrawing, the token to be withdrawn is the one with less impact on the pool if withdrawn
/// Strike price: `token1Amt` / `token0Amt`
/// Market price: (reserve1 * sqrt(1 - feeRatio0)) / (reserve0 * sqrt(1 - feeRatio1))
/// If strike price > market price, withdraw token0 to user, and token1 vice versa
/// Formula to determine which token to withdraw:
/// `token0Amt` * sqrt(1 - feeRatio0) / reserve0 < `token1Amt` * sqrt(1 - feeRatio1) / reserve1
/// @dev Formula can be transformed to:
/// sqrt((1 - feeRatio0)/(1 - feeRatio1)) * `token0Amt` / reserve0 < `token1Amt` / reserve1
/// @dev Content of withdrawn note will be cleared
/// @param from Address of the user withdrawing
/// @param index Index of the note
/// @param to Address to receive the redeemed token0 or token1
/// @return token0Amt Amount of token0 withdrawn
/// @return token1Amt Amount of token1 withdrawn
function _withdraw(address from, uint index, address to) internal returns (uint token0Amt, uint token1Amt) {
Note storage note = notes[from][index];
token0Amt = note.token0Amt;
token1Amt = note.token1Amt;
uint due = note.due;
note.token0Amt = 0;
note.token1Amt = 0;
note.due = 0;
require(due > 0, "invalid note");
require(due <= block.timestamp, "early withdrawal");
(uint reserve0, uint reserve1) = getReserves();
(uint64 _feeRatio0, uint64 _feeRatio1) = getFeeRatio();
if((MAX_FEE_RATIO * (MAX_FEE_RATIO - uint(_feeRatio0)) / (MAX_FEE_RATIO - uint(_feeRatio1))).sqrt() * token0Amt / reserve0 < MAX_FEE_RATIO_SQRT * token1Amt / reserve1) {
token1Amt = 0;
token0.safeTransfer(to, token0Amt);
uint64 feeRatioAdded = uint64(token0Amt * MAX_FEE_RATIO / reserve0);
_updateFeeRatio0(_feeRatio0, feeRatioAdded);
emit Withdraw(from, true, index, token0Amt);
}
else {
token0Amt = 0;
token1.safeTransfer(to, token1Amt);
uint64 feeRatioAdded = uint64(token1Amt * MAX_FEE_RATIO / reserve1);
_updateFeeRatio1(_feeRatio1, feeRatioAdded);
emit Withdraw(from, false, index, token1Amt);
}
}
/// @notice Withdraw the note and receive either one of token0 or token1
/// @dev Re-entrancy protected
/// @param index Index of the note owned by user
/// @param to Address to receive the redeemed token0 or token1
/// @return token0Amt Amount of token0 withdrawn
/// @return token1Amt Amount of token1 withdrawn
function withdraw(uint index, address to) external lock returns (uint token0Amt, uint token1Amt) {
return _withdraw(msg.sender, index, to);
}
/// @notice Withdraw the note and receive either one of token0 or token1 if approved by user
/// @param from Address of the user withdrawing
/// @param index Index of the note
/// @param to Address to receive the redeemed token0 or token1
/// @return token0Amt Amount of token0 withdrawn
/// @return token1Amt Amount of token1 withdrawn
function withdrawFrom(address from, uint index, address to) external returns (uint token0Amt, uint token1Amt) {
require(operatorApprovals[from][msg.sender], "not operator");
return _withdraw(from, index, to);
}
function _ecrecover(bytes32 hash, bytes memory signature) internal pure returns (address) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return address(0);
} else if (v != 27 && v != 28) {
return address(0);
} else {
return ecrecover(hash, v, r, s);
}
} else {
return address(0);
}
}
/// @notice Approve operator to withdraw note on behalf of user
/// User who signs the approval signature must be the `owner`
/// @param owner Address of the user who owns the note
/// @param operator Address of the operator
/// @param approved Whether the operator is approved or not
/// @param deadline deadline of the signature
/// @param sig approval signature
function setApprovalForAllWithSig(address owner, address operator, bool approved, uint deadline, bytes calldata sig) external {
require(block.timestamp <= deadline || deadline == 0, "exceed deadline");
require(owner != address(0), "owner cannot be zero");
require(operator != address(0), "operator cannot be zero");
bytes32 structHash = keccak256(abi.encode(APPROVE_TYPEHASH, owner, operator, approved, nonces[owner]++, deadline));
bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, structHash));
require(owner == _ecrecover(digest, sig), "invalid signature");
operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/// @notice Approve operator to withdraw note on behalf of user
/// @param operator Address of the operator
/// @param approved Whether the operator is approved or not
function setApprovalForAll(address operator, bool approved) external {
require(operator != address(0), "operator cannot be zero");
operatorApprovals[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
}pragma solidity >=0.8.0;
// SPDX-License-Identifier: MIT
interface IERC20 {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
}pragma solidity >=0.8.0;
// SPDX-License-Identifier: MIT
interface IFarm {
event TransferOwnership(address newOwner);
event RateUpdated(address indexed poolId, uint rewardRate, uint weight);
event GrantSP(address indexed user, address indexed poolId, uint amountIn, uint amountOut);
event Swap(address indexed user, address indexed parent, uint amountIn, uint amountOut);
struct Pool {
uint weight;
uint rewardRate;
uint lastUpdateTime;
uint lastReserve;
address gauge;
}
function agency() external view returns (address);
function gov() external view returns (address);
function owner() external view returns (address);
function globalPool() external view returns (address);
function pools(address poolId) external view returns (uint weight, uint rewardRate, uint lastUpdateTime, uint lastReserve, address gauge);
function balanceOf(address user) external view returns (uint);
function cooldown(address user) external view returns (uint);
function transferOwnership(address _owner) external;
function rescueERC20(address tokenAddress, address to, uint256 amount) external;
function setPool(address poolId, address gauge) external;
function setPoolRewardRate(address poolId, uint rewardRate, uint weight) external;
function setGlobalRewardRate(uint rewardRate, uint weight) external;
function getCurrentPoolReserve(address poolId) view external returns (uint reserve);
function getCurrentGlobalReserve() view external returns (uint reserve);
function grantSP(address to, uint amount) external;
function swap(address user) external returns (uint amountOut);
}pragma solidity >=0.8.0;
// SPDX-License-Identifier: MIT
interface IFactory {
event PairCreated(address indexed token0, address indexed token1, uint id, address pair, uint);
event GaugeCreated(address indexed poolId, address gauge);
event BribeCreated(address indexed gauge, address bribe);
function controller() external returns (address);
function pendingController() external returns (address);
function permissionless() external returns (bool);
function getPairCount(address token0, address token1) external view returns (uint);
function getPair(address token0, address token1, uint id) external view returns (address);
function allPairs() external view returns (address[] memory);
function allPairsLength() external view returns (uint);
function getInitCodeHash() external pure returns (bytes32);
function createPair(address tokenA, address tokenB) external returns (address pair);
function createGauge(address farm, address sgov, address poolId, uint weight, uint base, uint slope) external returns (address gauge);
function createBribe(address gauge) external returns (address bribe);
function setController(address _controller) external;
function becomeController() external;
function open2public() external;
}pragma solidity 0.8.17;
// SPDX-License-Identifier: AGPL-2.0
library ABDKMath64x64 {
/*
* Minimum value signed 64.64-bit fixed point number may have.
* -2^127
*/
int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;
/*
* Maximum value signed 64.64-bit fixed point number may have.
* 2^127-1
*/
int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
/**
* Calculate x * y rounding down, where x is signed 64.64 fixed point number
* and y is unsigned 256-bit integer number. Revert on overflow.
*
* @param x signed 64.64 fixed point number
* @param y unsigned 256-bit integer number
* @return unsigned 256-bit integer number
*/
function mulu (int128 x, uint256 y) internal pure returns (uint256) {
unchecked {
if (y == 0) return 0;
require (x >= 0);
uint256 lo = (uint256 (int256 (x)) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
uint256 hi = uint256 (int256 (x)) * (y >> 128);
require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
hi <<= 64;
require (hi <=
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo);
return hi + lo;
}
}
/**
* Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
* integer numbers. Revert on overflow or when y is zero.
*
* @param x unsigned 256-bit integer number
* @param y unsigned 256-bit integer number
* @return signed 64.64-bit fixed point number
*/
function divu (uint256 x, uint256 y) internal pure returns (int128) {
unchecked {
require (y != 0);
uint128 result = divuu (x, y);
require (result <= uint128 (MAX_64x64));
return int128 (result);
}
}
/**
* Calculate binary exponent of x. Revert on overflow.
*
* @param x signed 64.64-bit fixed point number
* @return signed 64.64-bit fixed point number
*/
function exp_2 (int128 x) internal pure returns (int128) {
unchecked {
require (x < 0x400000000000000000); // Overflow
if (x < -0x400000000000000000) return 0; // Underflow
uint256 result = 0x80000000000000000000000000000000;
if (x & 0x8000000000000000 > 0)
result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;
if (x & 0x4000000000000000 > 0)
result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;
if (x & 0x2000000000000000 > 0)
result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;
if (x & 0x1000000000000000 > 0)
result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128;
if (x & 0x800000000000000 > 0)
result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;
if (x & 0x400000000000000 > 0)
result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;
if (x & 0x200000000000000 > 0)
result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;
if (x & 0x100000000000000 > 0)
result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;
if (x & 0x80000000000000 > 0)
result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;
if (x & 0x40000000000000 > 0)
result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;
if (x & 0x20000000000000 > 0)
result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;
if (x & 0x10000000000000 > 0)
result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;
if (x & 0x8000000000000 > 0)
result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;
if (x & 0x4000000000000 > 0)
result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;
if (x & 0x2000000000000 > 0)
result = result * 0x1000162E525EE054754457D5995292026 >> 128;
if (x & 0x1000000000000 > 0)
result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128;
if (x & 0x800000000000 > 0)
result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;
if (x & 0x400000000000 > 0)
result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;
if (x & 0x200000000000 > 0)
result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128;
if (x & 0x100000000000 > 0)
result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128;
if (x & 0x80000000000 > 0)
result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;
if (x & 0x40000000000 > 0)
result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;
if (x & 0x20000000000 > 0)
result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128;
if (x & 0x10000000000 > 0)
result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;
if (x & 0x8000000000 > 0)
result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;
if (x & 0x4000000000 > 0)
result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128;
if (x & 0x2000000000 > 0)
result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;
if (x & 0x1000000000 > 0)
result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;
if (x & 0x800000000 > 0)
result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;
if (x & 0x400000000 > 0)
result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;
if (x & 0x200000000 > 0)
result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;
if (x & 0x100000000 > 0)
result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128;
if (x & 0x80000000 > 0)
result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;
if (x & 0x40000000 > 0)
result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;
if (x & 0x20000000 > 0)
result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128;
if (x & 0x10000000 > 0)
result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;
if (x & 0x8000000 > 0)
result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;
if (x & 0x4000000 > 0)
result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;
if (x & 0x2000000 > 0)
result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128;
if (x & 0x1000000 > 0)
result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128;
if (x & 0x800000 > 0)
result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;
if (x & 0x400000 > 0)
result = result * 0x100000000002C5C85FDF477B662B26945 >> 128;
if (x & 0x200000 > 0)
result = result * 0x10000000000162E42FEFA3AE53369388C >> 128;
if (x & 0x100000 > 0)
result = result * 0x100000000000B17217F7D1D351A389D40 >> 128;
if (x & 0x80000 > 0)
result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;
if (x & 0x40000 > 0)
result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;
if (x & 0x20000 > 0)
result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128;
if (x & 0x10000 > 0)
result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;
if (x & 0x8000 > 0)
result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;
if (x & 0x4000 > 0)
result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128;
if (x & 0x2000 > 0)
result = result * 0x1000000000000162E42FEFA39F02B772C >> 128;
if (x & 0x1000 > 0)
result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128;
if (x & 0x800 > 0)
result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;
if (x & 0x400 > 0)
result = result * 0x100000000000002C5C85FDF473DEA871F >> 128;
if (x & 0x200 > 0)
result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128;
if (x & 0x100 > 0)
result = result * 0x100000000000000B17217F7D1CF79E949 >> 128;
if (x & 0x80 > 0)
result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128;
if (x & 0x40 > 0)
result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128;
if (x & 0x20 > 0)
result = result * 0x100000000000000162E42FEFA39EF366F >> 128;
if (x & 0x10 > 0)
result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128;
if (x & 0x8 > 0)
result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128;
if (x & 0x4 > 0)
result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128;
if (x & 0x2 > 0)
result = result * 0x1000000000000000162E42FEFA39EF358 >> 128;
if (x & 0x1 > 0)
result = result * 0x10000000000000000B17217F7D1CF79AB >> 128;
result >>= uint256 (int256 (63 - (x >> 64)));
require (result <= uint256 (int256 (MAX_64x64)));
return int128 (int256 (result));
}
}
/**
* Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
* integer numbers. Revert on overflow or when y is zero.
*
* @param x unsigned 256-bit integer number
* @param y unsigned 256-bit integer number
* @return unsigned 64.64-bit fixed point number
*/
function divuu (uint256 x, uint256 y) private pure returns (uint128) {
unchecked {
require (y != 0);
uint256 result;
if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
result = (x << 64) / y;
else {
uint256 msb = 192;
uint256 xc = x >> 192;
if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
if (xc >= 0x10000) { xc >>= 16; msb += 16; }
if (xc >= 0x100) { xc >>= 8; msb += 8; }
if (xc >= 0x10) { xc >>= 4; msb += 4; }
if (xc >= 0x4) { xc >>= 2; msb += 2; }
if (xc >= 0x2) msb += 1; // No need to shift xc anymore
result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1);
require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
uint256 hi = result * (y >> 128);
uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
uint256 xh = x >> 192;
uint256 xl = x << 64;
if (xl < lo) xh -= 1;
xl -= lo; // We rely on overflow behavior here
lo = hi << 128;
if (xl < lo) xh -= 1;
xl -= lo; // We rely on overflow behavior here
assert (xh == hi >> 128);
result += xl / y;
}
require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return uint128 (result);
}
}
}pragma solidity 0.8.17;
// SPDX-License-Identifier: AGPL-2.0
//https://github.com/Gaussian-Process/solidity-sqrt/blob/main/src/FixedPointMathLib.sol
library SqrtMath {
function sqrt(uint256 x) internal pure returns (uint256 z) {
assembly {
// This segment is to get a reasonable initial estimate for the Babylonian method.
// If the initial estimate is bad, the number of correct bits increases ~linearly
// each iteration instead of ~quadratically.
// The idea is to get z*z*y within a small factor of x.
// More iterations here gets y in a tighter range. Currently, we will have
// y in [256, 256*2^16). We ensure y>= 256 so that the relative difference
// between y and y+1 is small. If x < 256 this is not possible, but those cases
// are easy enough to verify exhaustively.
z := 181 // The 'correct' value is 1, but this saves a multiply later
let y := x
// Note that we check y>= 2^(k + 8) but shift right by k bits each branch,
// this is to ensure that if x >= 256, then y >= 256.
if iszero(lt(y, 0x10000000000000000000000000000000000)) {
y := shr(128, y)
z := shl(64, z)
}
if iszero(lt(y, 0x1000000000000000000)) {
y := shr(64, y)
z := shl(32, z)
}
if iszero(lt(y, 0x10000000000)) {
y := shr(32, y)
z := shl(16, z)
}
if iszero(lt(y, 0x1000000)) {
y := shr(16, y)
z := shl(8, z)
}
// Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8),
// and either y >= 256, or x < 256.
// Correctness can be checked exhaustively for x < 256, so we assume y >= 256.
// Then z*sqrt(y) is within sqrt(257)/sqrt(256) of x, or about 20bps.
// The estimate sqrt(x) = (181/1024) * (x+1) is off by a factor of ~2.83 both when x=1
// and when x = 256 or 1/256. In the worst case, this needs seven Babylonian iterations.
z := shr(18, mul(z, add(y, 65536))) // A multiply is saved from the initial z := 181
// Run the Babylonian method seven times. This should be enough given initial estimate.
// Possibly with a quadratic/cubic polynomial above we could get 4-6.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// See https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division.
// If x+1 is a perfect square, the Babylonian method cycles between
// floor(sqrt(x)) and ceil(sqrt(x)). This check ensures we return floor.
// The solmate implementation assigns zRoundDown := div(x, z) first, but
// since this case is rare, we choose to save gas on the assignment and
// repeat division in the rare case.
// If you don't care whether floor or ceil is returned, you can skip this.
if lt(div(x, z), z) {
z := div(x, z)
}
}
}
}pragma solidity 0.8.17;
// SPDX-License-Identifier: AGPL-2.0
library TransferHelper {
function safeApprove(address token, address to, uint 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, uint 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, uint value) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'transferHelper: transferFrom failed');
}
function safeTransferETH(address to, uint value) internal {
(bool success,) = to.call{value:value}(new bytes(0));
require(success, 'transferHelper: ETH transfer failed');
}
}{
"remappings": [
"@openzeppelin/=lib/openzeppelin-contracts/",
"interface/=src/interface/",
"util/=src/util/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"openzeppelin/=lib/openzeppelin-contracts/contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"pair","type":"address"}],"name":"PairCreated","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"becomeController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getInitCodeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"getPairCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"open2public","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pendingController","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permissionless","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50604051613e33380380613e3383398101604081905261002f916100ae565b6001600160a01b0381166100895760405162461bcd60e51b815260206004820152601960248201527f636f6e74726f6c6c65722063616e6e6f74206265207a65726f00000000000000604482015260640160405180910390fd5b600080546001600160a01b0319166001600160a01b03929092169190911790556100de565b6000602082840312156100c057600080fd5b81516001600160a01b03811681146100d757600080fd5b9392505050565b613d46806100ed6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c806392eefe9b1161007157806392eefe9b14610176578063a1256f9f14610189578063a2cab3a1146101ad578063c6c5e21c146101c0578063c9c65396146101c8578063f77c4791146101db57600080fd5b806302c54874146100b95780631bf31828146100f75780631e3dd18b146101015780635431927d1461012c578063574f2ba3146101345780635eced4801461013c575b600080fd5b6100e46100c73660046106b1565b600260209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100ff6101ee565b005b61011461010f3660046106e4565b610236565b6040516001600160a01b0390911681526020016100ee565b6100e4610260565b6004546100e4565b61011461014a3660046106fd565b60036020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b6100ff610184366004610739565b610292565b60015461019d90600160a01b900460ff1681565b60405190151581526020016100ee565b600154610114906001600160a01b031681565b6100ff610334565b6101146101d63660046106b1565b61037e565b600054610114906001600160a01b031681565b6000546001600160a01b031633146102215760405162461bcd60e51b81526004016102189061075b565b60405180910390fd5b6001805460ff60a01b1916600160a01b179055565b6004818154811061024657600080fd5b6000918252602090912001546001600160a01b0316905081565b60006040518060200161027290610688565b6020820181038252601f19601f8201166040525080519060200120905090565b6001600160a01b0381166102e85760405162461bcd60e51b815260206004820152601960248201527f636f6e74726f6c6c65722063616e6e6f74206265207a65726f000000000000006044820152606401610218565b6000546001600160a01b031633146103125760405162461bcd60e51b81526004016102189061075b565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b0316331461035e5760405162461bcd60e51b81526004016102189061075b565b600180546001600160a01b03199081169091556000805490911633179055565b600154600090600160a01b900460ff16806103a357506000546001600160a01b031633145b6103bf5760405162461bcd60e51b81526004016102189061075b565b816001600160a01b0316836001600160a01b0316036104165760405162461bcd60e51b81526020600482015260136024820152726964656e746963616c2061646472657373657360681b6044820152606401610218565b600080836001600160a01b0316856001600160a01b03161061043957838561043c565b84845b90925090506001600160a01b0382166104865760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b6044820152606401610218565b6001600160a01b0380831660009081526002602090815260408083209385168352929052908120805482906104ba90610794565b91829055506040516bffffffffffffffffffffffff19606086811b8216602084015285901b166034820152604881018290529091506000906068016040516020818303038152906040528051906020012090508060405161051a90610688565b8190604051809103906000f590508015801561053a573d6000803e3d6000fd5b5060405163485cc95560e01b81526001600160a01b03868116600483015285811660248301529196509086169063485cc95590604401600060405180830381600087803b15801561058a57600080fd5b505af115801561059e573d6000803e3d6000fd5b505050506001600160a01b038481166000908152600360209081526040808320938716835292905290812086916105d66001866107ad565b81526020808201929092526040908101600090812080546001600160a01b039586166001600160a01b0319918216179091556004805460018101825592527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b90910180548a8616921682179055815186815292830152858316928716917fc3168168beb4136b347bbd2afd38adb2282984cdfba1e15b86d35942f015f4ca910160405180910390a35050505092915050565b61354a806107c783390190565b80356001600160a01b03811681146106ac57600080fd5b919050565b600080604083850312156106c457600080fd5b6106cd83610695565b91506106db60208401610695565b90509250929050565b6000602082840312156106f657600080fd5b5035919050565b60008060006060848603121561071257600080fd5b61071b84610695565b925061072960208501610695565b9150604084013590509250925092565b60006020828403121561074b57600080fd5b61075482610695565b9392505050565b6020808252600990820152683337b93134b23232b760b91b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000600182016107a6576107a661077e565b5060010190565b818103818111156107c0576107c061077e565b9291505056fe60a0604052600180546001600160401b0319166102d01781556006556709b6e64a8ec60000600a5534801561003357600080fd5b5060408051808201825260048152632830b4b960e11b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527feb97ef53980152ad9ea08faf89a3bce92c73647576c726a0fba9da4e28269ade818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152466080808301919091523060a0808401919091528451808403909101815260c0909201909352805191012090819052613427610123600039600081816102fa0152610d7e01526134276000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80637ecebe001161010f578063d4d5d32a116100a2578063e146141c11610071578063e146141c14610517578063e162402f1461052a578063f385cecb1461053d578063f46901ed1461054657600080fd5b8063d4d5d32a14610487578063d4f26c511461048f578063dc950d36146104a2578063e0b117ff146104c257600080fd5b8063b2118a8d116100de578063b2118a8d14610427578063c45a01551461043a578063c9f10f8c1461044d578063d21220a71461047457600080fd5b80637ecebe00146103ce5780637f568f18146103ee578063a22cb46514610401578063a9d9db4d1461041457600080fd5b80633644e5151161018757806359362b881161015657806359362b8814610355578063666093341461037d5780637b7e9fac146103a85780637bc90d1c146103bb57600080fd5b80633644e515146102f557806336e9332d1461031c578063485cc9551461032f57806353d56bf51461034257600080fd5b80630dfe1681116101c35780630dfe1681146102925780631bf1fffb146102ac57806322ff2a8e146102cd57806330d6618e146102e257600080fd5b8062f714ce146101f4578063017e7e58146102215780630902f1ac1461024c5780630d95e05414610254575b600080fd5b610207610202366004612f5d565b610559565b604080519283526020830191909152015b60405180910390f35b600354610234906001600160a01b031681565b6040516001600160a01b039091168152602001610218565b6102076105a7565b610282610262366004612f8d565b600d60209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610218565b60015461023490600160401b90046001600160a01b031681565b6102bf6102ba366004612fbb565b6106b2565b604051908152602001610218565b6102e06102db366004612feb565b6107a1565b005b6102bf6102f0366004613006565b6108f3565b6102bf7f000000000000000000000000000000000000000000000000000000000000000081565b600954610234906001600160a01b031681565b6102e061033d366004612f8d565b6109f8565b6102bf610350366004613041565b610a18565b61035d610b13565b604080516001600160401b03938416815292909116602083015201610218565b61039061038b366004613076565b610b8d565b6040516001600160401b039091168152602001610218565b6102e06103b63660046130ae565b610be3565b600154610390906001600160401b031681565b6102bf6103dc366004613160565b60076020526000908152604090205481565b6102e06103fc366004612fbb565b610ecf565b6102e061040f36600461317d565b610fac565b6102bf610422366004613041565b611068565b6102e06104353660046131ab565b611152565b600854610234906001600160a01b031681565b6102bf7fd7db667cdba90ca333b850481afd8f802dc1081fc1d7ee77ee75ae69468a0b1781565b600254610234906001600160a01b031681565b6102e061123d565b6102e061049d366004613160565b611273565b6102bf6104b0366004613160565b600b6020526000908152604090205481565b6104fc6104d03660046131ec565b600c60209081526000928352604080842090915290825290208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610218565b6102bf610525366004613006565b61136d565b61020761053836600461320a565b61145e565b6102bf600a5481565b6102e0610554366004613160565b6114d9565b6000806006546001146105875760405162461bcd60e51b815260040161057e9061324c565b60405180910390fd5b60006006556105973385856115ec565b6001600655909590945092505050565b600480546001546040516370a0823160e01b81523093810193909352600092839291600160401b90046001600160a01b0316906370a0823190602401602060405180830381865afa158015610600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610624919061326c565b61062e919061329b565b6005546002546040516370a0823160e01b815230600482015292945090916001600160a01b03909116906370a0823190602401602060405180830381865afa15801561067e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a2919061326c565b6106ac919061329b565b90509091565b60008162015180036106ec57670de0b6b3a7640000600a54664a620d26ead0e46106dc91906132ae565b6106e691906132db565b92915050565b816203f4800361071457670de0b6b3a7640000600a546680d5cceb1376a86106dc91906132ae565b8162093a800361073c57670de0b6b3a7640000600a5466c4cc884ac66cf86106dc91906132ae565b8162278d000361076557670de0b6b3a7640000600a54670197699c5ceeb4006106dc91906132ae565b60405162461bcd60e51b815260206004820152600c60248201526b696e76616c69642074696d6560a01b604482015260640161057e565b919050565b6006546001146107c35760405162461bcd60e51b815260040161057e9061324c565b6000600681905550336001600160a01b0316600860009054906101000a90046001600160a01b03166001600160a01b031663f77c47916040518163ffffffff1660e01b81526004016020604051808303816000875af115801561082a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084e91906132fd565b6001600160a01b0316146108745760405162461bcd60e51b815260040161057e9061331a565b6000816001600160401b0316116108cd5760405162461bcd60e51b815260206004820152601860248201527f68616c66206c6966652063616e6e6f74206265207a65726f0000000000000000604482015260640161057e565b6001805467ffffffffffffffff19166001600160401b0392909216919091178155600655565b60006006546001146109175760405162461bcd60e51b815260040161057e9061324c565b60006006556001600160a01b0385166109665760405162461bcd60e51b8152602060048201526011602482015270746f2063616e6e6f74206265207a65726f60781b604482015260640161057e565b6000610972858561187d565b925090506000610981846106b2565b9050610992876000858988866119a7565b6003546001600160a01b0316156109c5576109ae6002836132db565b600560008282546109bf919061333d565b90915550505b6002546109dd906001600160a01b0316333089611ae7565b6109e987878584611c17565b50506001600655949350505050565b610a028282611cc5565b5050600880546001600160a01b03191633179055565b6000600654600114610a3c5760405162461bcd60e51b815260040161057e9061324c565b60006006819055610a4d848461187d565b6003549093509091506001600160a01b031615610a8657610a6f6002826132db565b60056000828254610a80919061333d565b90915550505b600254610a9e906001600160a01b0316333087611ae7565b600154610abc90600160401b90046001600160a01b03168684611d36565b60408051858152602081018490526001600160a01b0387169160009133917f66251e495e6e69e208ab08e2bc259dbe2ef482a8c4a93b8984b03a1eb27e1b9e91015b60405180910390a45060016006559392505050565b600080600080610b4b6000546001600160401b0380821692600160401b8304821692600160801b8104831692600160c01b9091041690565b92965090945092509050610b6c8461038b6001600160401b0385164261329b565b9350610b858361038b6001600160401b0384164261329b565b925050509091565b6001546000908190610ba99084906001600160401b0316611e51565b90506000610bc1610bb983613350565b600f0b611e92565b9050610bda600f82900b6001600160401b038716612950565b95945050505050565b8242111580610bf0575082155b610c2e5760405162461bcd60e51b815260206004820152600f60248201526e65786365656420646561646c696e6560881b604482015260640161057e565b6001600160a01b038616610c7b5760405162461bcd60e51b81526020600482015260146024820152736f776e65722063616e6e6f74206265207a65726f60601b604482015260640161057e565b6001600160a01b038516610ccb5760405162461bcd60e51b81526020600482015260176024820152766f70657261746f722063616e6e6f74206265207a65726f60481b604482015260640161057e565b6001600160a01b038616600090815260076020526040812080547fd7db667cdba90ca333b850481afd8f802dc1081fc1d7ee77ee75ae69468a0b17918991899189919086610d1883613376565b909155506040805160208101969096526001600160a01b03948516908601529290911660608401521515608083015260a082015260c0810185905260e00160408051601f1981840301815290829052805160209182012061190160f01b918301919091527f00000000000000000000000000000000000000000000000000000000000000006022830152604282018190529150600090606201604051602081830303815290604052805190602001209050610e098185858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129bb92505050565b6001600160a01b0316886001600160a01b031614610e5d5760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b604482015260640161057e565b6001600160a01b038881166000818152600d60209081526040808320948c1680845294825291829020805460ff19168b151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050505050505050565b600654600114610ef15760405162461bcd60e51b815260040161057e9061324c565b6000600681905550336001600160a01b0316600860009054906101000a90046001600160a01b03166001600160a01b031663f77c47916040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610f58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7c91906132fd565b6001600160a01b031614610fa25760405162461bcd60e51b815260040161057e9061331a565b600a556001600655565b6001600160a01b038216610ffc5760405162461bcd60e51b81526020600482015260176024820152766f70657261746f722063616e6e6f74206265207a65726f60481b604482015260640161057e565b336000818152600d602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600060065460011461108c5760405162461bcd60e51b815260040161057e9061324c565b6000600681905561109d8484612aa4565b6003549093509091506001600160a01b0316156110d6576110bf6002826132db565b600460008282546110d0919061333d565b90915550505b6001546110f590600160401b90046001600160a01b0316333087611ae7565b60025461110c906001600160a01b03168684611d36565b60408051858152602081018490526001600160a01b0387169160019133917f66251e495e6e69e208ab08e2bc259dbe2ef482a8c4a93b8984b03a1eb27e1b9e9101610afe565b6008546040805163f77c479160e01b8152905133926001600160a01b03169163f77c479191600480830192602092919082900301816000875af115801561119d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c191906132fd565b6001600160a01b0316146111e75760405162461bcd60e51b815260040161057e9061331a565b6001546001600160a01b03600160401b90910481169084160361120957600080fd5b6002546001600160a01b039081169084160361122457600080fd5b6112386001600160a01b0384168383611d36565b505050565b60065460011461125f5760405162461bcd60e51b815260040161057e9061324c565b600060065561126c612bc1565b6001600655565b6006546001146112955760405162461bcd60e51b815260040161057e9061324c565b6000600681905550336001600160a01b0316600860009054906101000a90046001600160a01b03166001600160a01b031663f77c47916040518163ffffffff1660e01b81526004016020604051808303816000875af11580156112fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132091906132fd565b6001600160a01b0316146113465760405162461bcd60e51b815260040161057e9061331a565b600980546001600160a01b0319166001600160a01b03929092169190911790556001600655565b60006006546001146113915760405162461bcd60e51b815260040161057e9061324c565b60006006556001600160a01b0385166113e05760405162461bcd60e51b8152602060048201526011602482015270746f2063616e6e6f74206265207a65726f60781b604482015260640161057e565b60006113ec8585612aa4565b9250905060006113fb846106b2565b905061140c876001888688866119a7565b6003546001600160a01b03161561143f576114286002836132db565b60046000828254611439919061333d565b90915550505b6001546109dd90600160401b90046001600160a01b0316333089611ae7565b6001600160a01b0383166000908152600d60209081526040808320338452909152812054819060ff166114c25760405162461bcd60e51b815260206004820152600c60248201526b3737ba1037b832b930ba37b960a11b604482015260640161057e565b6114cd8585856115ec565b91509150935093915050565b6006546001146114fb5760405162461bcd60e51b815260040161057e9061324c565b6000600681905550336001600160a01b0316600860009054906101000a90046001600160a01b03166001600160a01b031663f77c47916040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611562573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158691906132fd565b6001600160a01b0316146115ac5760405162461bcd60e51b815260040161057e9061331a565b6003546001600160a01b0316156115c5576115c5612bc1565b600380546001600160a01b0319166001600160a01b03929092169190911790556001600655565b6001600160a01b0383166000908152600c6020908152604080832085845290915281208054600182018054600284018054868655928690559490945590929190806116685760405162461bcd60e51b815260206004820152600c60248201526b696e76616c6964206e6f746560a01b604482015260640161057e565b428111156116ab5760405162461bcd60e51b815260206004820152601060248201526f19585c9b1e481dda5d1a191c985dd85b60821b604482015260640161057e565b6000806116b66105a7565b915091506000806116c5610b13565b9092509050826116da886401000000006132ae565b6116e491906132db565b84896117346117006001600160401b038616600160401b61329b565b6117176001600160401b038816600160401b61329b565b61172590600160401b6132ae565b61172f91906132db565b612c53565b61173e91906132ae565b61174891906132db565b10156117e4576001546000975061177090600160401b90046001600160a01b03168a8a611d36565b600084611781600160401b8b6132ae565b61178b91906132db565b90506117978382612cfb565b604080518c8152602081018b90526001916001600160a01b038f16917f8595f614655883bce3496fde65b1ff62bb8b336cc93d72a91cd2f61f1566872f910160405180910390a35061186f565b600254600098506117ff906001600160a01b03168a89611d36565b600083611810600160401b8a6132ae565b61181a91906132db565b90506118268282612d48565b604080518c8152602081018a90526000916001600160a01b038f16917f8595f614655883bce3496fde65b1ff62bb8b336cc93d72a91cd2f61f1566872f910160405180910390a3505b505050505050935093915050565b600080600084116118c75760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a59081a5b9c1d5d08185b5bdd5b9d60621b604482015260640161057e565b6000806118d26105a7565b915091506000806118e1610b13565b9092509050600160401b6118fe896001600160401b0384166132ae565b61190891906132db565b95506000611916878a61329b565b9050611922818561333d565b61192c86836132ae565b61193691906132db565b9550878610156119735760405162461bcd60e51b8152602060048201526008602482015267736c69707061676560c01b604482015260640161057e565b600085611984600160401b896132ae565b61198e91906132db565b905061199a8482612cfb565b5050505050509250929050565b6001600160a01b0386166000908152600b60205260408120805490826119cc83613376565b909155506001600160a01b0388166000908152600c60209081526040808320848452909152812091925087611a015785611a03565b865b90506000670de0b6b3a7640000611a1a818761333d565b611a24908a6132ae565b611a2e91906132db565b90506000670de0b6b3a7640000611a45818861333d565b611a4f908a6132ae565b611a5991906132db565b90506000611a67884261333d565b8386556001860183905560028601819055604080518881526020810187905290810185905260608101849052608081018290529091508b1515906001600160a01b038e16907f1a03e701f999967b189f59a5e5d6ddefdc9b644975d45bcf544d8755719a0bd79060a00160405180910390a3505050505050505050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691611b4b919061338f565b6000604051808303816000865af19150503d8060008114611b88576040519150601f19603f3d011682016040523d82523d6000602084013e611b8d565b606091505b5091509150818015611bb7575080511580611bb7575080806020019051810190611bb791906133be565b611c0f5760405162461bcd60e51b815260206004820152602360248201527f7472616e7366657248656c7065723a207472616e7366657246726f6d206661696044820152621b195960ea1b606482015260840161057e565b505050505050565b6009546001600160a01b031615611cbf576000670de0b6b3a764000082611c4161172f86886132ae565b611c4b91906132ae565b611c5591906132db565b6009546040516352edeea160e01b81526001600160a01b038881166004830152602482018490529293509116906352edeea190604401600060405180830381600087803b158015611ca557600080fd5b505af1158015611cb9573d6000803e3d6000fd5b50505050505b50505050565b600154600160401b90046001600160a01b031615611cf55760405162461bcd60e51b815260040161057e9061331a565b6001805468010000000000000000600160e01b031916600160401b6001600160a01b0394851602179055600280546001600160a01b03191691909216179055565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691611d92919061338f565b6000604051808303816000865af19150503d8060008114611dcf576040519150601f19603f3d011682016040523d82523d6000602084013e611dd4565b606091505b5091509150818015611dfe575080511580611dfe575080806020019051810190611dfe91906133be565b611e4a5760405162461bcd60e51b815260206004820152601f60248201527f7472616e7366657248656c7065723a207472616e73666572206661696c656400604482015260640161057e565b5050505050565b600081600003611e6057600080fd5b6000611e6c8484612da3565b905060016001607f1b036001600160801b0382161115611e8b57600080fd5b9392505050565b60006840000000000000000082600f0b12611eac57600080fd5b683fffffffffffffffff1982600f0b1215611ec957506000919050565b6001607f1b60006780000000000000008416600f0b1315611efb5770016a09e667f3bcc908b2fb1366ea957d3e0260801c5b60008367400000000000000016600f0b1315611f28577001306fe0a31b7152de8d5a46305c85edec0260801c5b60008367200000000000000016600f0b1315611f55577001172b83c7d517adcdf7c8c50eb14a791f0260801c5b60008367100000000000000016600f0b1315611f825770010b5586cf9890f6298b92b71842a983630260801c5b60008367080000000000000016600f0b1315611faf577001059b0d31585743ae7c548eb68ca417fd0260801c5b60008367040000000000000016600f0b1315611fdc57700102c9a3e778060ee6f7caca4f7a29bde80260801c5b60008367020000000000000016600f0b13156120095770010163da9fb33356d84a66ae336dcdfa3f0260801c5b60008367010000000000000016600f0b131561203657700100b1afa5abcbed6129ab13ec11dc95430260801c5b600083668000000000000016600f0b13156120625770010058c86da1c09ea1ff19d294cf2f679b0260801c5b600083664000000000000016600f0b131561208e577001002c605e2e8cec506d21bfc89a23a00f0260801c5b600083662000000000000016600f0b13156120ba57700100162f3904051fa128bca9c55c31e5df0260801c5b600083661000000000000016600f0b13156120e6577001000b175effdc76ba38e31671ca9397250260801c5b600083660800000000000016600f0b131561211257700100058ba01fb9f96d6cacd4b180917c3d0260801c5b600083660400000000000016600f0b131561213e5770010002c5cc37da9491d0985c348c68e7b30260801c5b600083660200000000000016600f0b131561216a577001000162e525ee054754457d59952920260260801c5b600083660100000000000016600f0b13156121965770010000b17255775c040618bf4a4ade83fc0260801c5b6000836580000000000016600f0b13156121c1577001000058b91b5bc9ae2eed81e9b7d4cfab0260801c5b6000836540000000000016600f0b13156121ec57700100002c5c89d5ec6ca4d7c8acc017b7c90260801c5b6000836520000000000016600f0b13156122175770010000162e43f4f831060e02d839a9d16d0260801c5b6000836510000000000016600f0b131561224257700100000b1721bcfc99d9f890ea069117630260801c5b6000836508000000000016600f0b131561226d5770010000058b90cf1e6d97f9ca14dbcc16280260801c5b6000836504000000000016600f0b1315612298577001000002c5c863b73f016468f6bac5ca2b0260801c5b6000836502000000000016600f0b13156122c357700100000162e430e5a18f6119e3c02282a50260801c5b6000836501000000000016600f0b13156122ee577001000000b1721835514b86e6d96efd1bfe0260801c5b60008364800000000016600f0b131561231857700100000058b90c0b48c6be5df846c5b2ef0260801c5b60008364400000000016600f0b13156123425770010000002c5c8601cc6b9e94213c72737a0260801c5b60008364200000000016600f0b131561236c577001000000162e42fff037df38aa2b219f060260801c5b60008364100000000016600f0b13156123965770010000000b17217fba9c739aa5819f44f90260801c5b60008364080000000016600f0b13156123c0577001000000058b90bfcdee5acd3c1cedc8230260801c5b60008364040000000016600f0b13156123ea57700100000002c5c85fe31f35a6a30da1be500260801c5b60008364020000000016600f0b13156124145770010000000162e42ff0999ce3541b9fffcf0260801c5b60008364010000000016600f0b131561243e57700100000000b17217f80f4ef5aadda455540260801c5b600083638000000016600f0b13156124675770010000000058b90bfbf8479bd5a81b51ad0260801c5b600083634000000016600f0b1315612490577001000000002c5c85fdf84bd62ae30a74cc0260801c5b600083632000000016600f0b13156124b957700100000000162e42fefb2fed257559bdaa0260801c5b600083631000000016600f0b13156124e2577001000000000b17217f7d5a7716bba4a9ae0260801c5b600083630800000016600f0b131561250b57700100000000058b90bfbe9ddbac5e109cce0260801c5b600083630400000016600f0b13156125345770010000000002c5c85fdf4b15de6f17eb0d0260801c5b600083630200000016600f0b131561255d577001000000000162e42fefa494f1478fde050260801c5b600083630100000016600f0b13156125865770010000000000b17217f7d20cf927c8e94c0260801c5b6000836280000016600f0b13156125ae577001000000000058b90bfbe8f71cb4e4b33d0260801c5b6000836240000016600f0b13156125d657700100000000002c5c85fdf477b662b269450260801c5b6000836220000016600f0b13156125fe5770010000000000162e42fefa3ae53369388c0260801c5b6000836210000016600f0b131561262657700100000000000b17217f7d1d351a389d400260801c5b6000836208000016600f0b131561264e5770010000000000058b90bfbe8e8b2d3d4ede0260801c5b6000836204000016600f0b1315612676577001000000000002c5c85fdf4741bea6e77e0260801c5b6000836202000016600f0b131561269e57700100000000000162e42fefa39fe95583c20260801c5b6000836201000016600f0b13156126c6577001000000000000b17217f7d1cfb72b45e10260801c5b60008361800016600f0b13156126ed57700100000000000058b90bfbe8e7cc35c3f00260801c5b60008361400016600f0b13156127145770010000000000002c5c85fdf473e242ea380260801c5b60008361200016600f0b131561273b577001000000000000162e42fefa39f02b772c0260801c5b60008361100016600f0b13156127625770010000000000000b17217f7d1cf7d83c1a0260801c5b60008361080016600f0b1315612789577001000000000000058b90bfbe8e7bdcbe2e0260801c5b60008361040016600f0b13156127b057700100000000000002c5c85fdf473dea871f0260801c5b60008361020016600f0b13156127d75770010000000000000162e42fefa39ef44d910260801c5b60008361010016600f0b13156127fe57700100000000000000b17217f7d1cf79e9490260801c5b600083608016600f0b13156128245770010000000000000058b90bfbe8e7bce5440260801c5b600083604016600f0b131561284a577001000000000000002c5c85fdf473de6eca0260801c5b600083602016600f0b131561287057700100000000000000162e42fefa39ef366f0260801c5b600083601016600f0b1315612896577001000000000000000b17217f7d1cf79afa0260801c5b600083600816600f0b13156128bc57700100000000000000058b90bfbe8e7bcd6d0260801c5b600083600416600f0b13156128e25770010000000000000002c5c85fdf473de6b20260801c5b600083600216600f0b1315612908577001000000000000000162e42fefa39ef3580260801c5b600083600116600f0b131561292e5770010000000000000000b17217f7d1cf79ab0260801c5b600f83810b60401d603f03900b1c60016001607f1b038111156106e657600080fd5b600081600003612962575060006106e6565b600083600f0b121561297357600080fd5b600f83900b6001600160801b038316810260401c90608084901c026001600160c01b038111156129a257600080fd5b60401b81198111156129b357600080fd5b019392505050565b60008151604103612a9c5760208201516040830151606084015160001a7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115612a0c57600093505050506106e6565b8060ff16601b14158015612a2457508060ff16601c14155b15612a3557600093505050506106e6565b60408051600081526020810180835288905260ff831691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015612a88573d6000803e3d6000fd5b5050506020604051035193505050506106e6565b5060006106e6565b60008060008411612aee5760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a59081a5b9c1d5d08185b5bdd5b9d60621b604482015260640161057e565b600080612af96105a7565b91509150600080612b08610b13565b9092509050600160401b612b25896001600160401b0385166132ae565b612b2f91906132db565b95506000612b3d878a61329b565b9050612b49818661333d565b612b5385836132ae565b612b5d91906132db565b955087861015612b9a5760405162461bcd60e51b8152602060048201526008602482015267736c69707061676560c01b604482015260640161057e565b600084612bab600160401b896132ae565b612bb591906132db565b905061199a8382612d48565b6004805460058054600093849055929055600354600154919291612bf9916001600160a01b03600160401b9092048216911684611d36565b600354600254612c16916001600160a01b03918216911683611d36565b60408051838152602081018390527faf7c505ee772ec188af7067e1f73db08ab028e3d564273442b907742b9c41fa0910160405180910390a15050565b60b581600160881b8110612c6c5760409190911b9060801c5b69010000000000000000008110612c885760209190911b9060401c5b650100000000008110612ca05760109190911b9060201c5b63010000008110612cb65760089190911b9060101c5b62010000010260121c80820401600190811c80830401811c80830401811c80830401811c80830401811c80830401811c80830401901c80820481111561079c57900490565b612d058282612f08565b60008054426001600160401b03908116600160801b0277ffffffffffffffff0000000000000000ffffffffffffffff199092169316929092179190911790555050565b612d528282612f08565b6000805477ffffffffffffffff0000000000000000ffffffffffffffff16600160401b6001600160401b03938416026001600160c01b031617600160c01b4293909316929092029190911790555050565b600081600003612db257600080fd5b60006001600160c01b038411612ddd5782604085901b81612dd557612dd56132c5565b049050612ef4565b60c084811c6401000000008110612df6576020918201911c5b620100008110612e08576010918201911c5b6101008110612e19576008918201911c5b60108110612e29576004918201911c5b60048110612e39576002918201911c5b60028110612e48576001820191505b60bf820360018603901c6001018260ff0387901b81612e6957612e696132c5565b0492506001600160801b03831115612e8057600080fd5b608085901c83026001600160801b038616840260c088901c604089901b82811015612eac576001820391505b608084901b92900382811015612ec3576001820391505b829003608084901c8214612ed957612ed96133db565b888181612ee857612ee86132c5565b04870196505050505050505b6001600160801b03811115611e8b57600080fd5b60006001600160401b03808416908316600160401b612f2782846132ae565b612f3191906132db565b612f3b828461333d565b610bda919061329b565b6001600160a01b0381168114612f5a57600080fd5b50565b60008060408385031215612f7057600080fd5b823591506020830135612f8281612f45565b809150509250929050565b60008060408385031215612fa057600080fd5b8235612fab81612f45565b91506020830135612f8281612f45565b600060208284031215612fcd57600080fd5b5035919050565b80356001600160401b038116811461079c57600080fd5b600060208284031215612ffd57600080fd5b611e8b82612fd4565b6000806000806080858703121561301c57600080fd5b843561302781612f45565b966020860135965060408601359560600135945092505050565b60008060006060848603121561305657600080fd5b833561306181612f45565b95602085013595506040909401359392505050565b6000806040838503121561308957600080fd5b61309283612fd4565b946020939093013593505050565b8015158114612f5a57600080fd5b60008060008060008060a087890312156130c757600080fd5b86356130d281612f45565b955060208701356130e281612f45565b945060408701356130f2816130a0565b93506060870135925060808701356001600160401b038082111561311557600080fd5b818901915089601f83011261312957600080fd5b81358181111561313857600080fd5b8a602082850101111561314a57600080fd5b6020830194508093505050509295509295509295565b60006020828403121561317257600080fd5b8135611e8b81612f45565b6000806040838503121561319057600080fd5b823561319b81612f45565b91506020830135612f82816130a0565b6000806000606084860312156131c057600080fd5b83356131cb81612f45565b925060208401356131db81612f45565b929592945050506040919091013590565b600080604083850312156131ff57600080fd5b823561309281612f45565b60008060006060848603121561321f57600080fd5b833561322a81612f45565b925060208401359150604084013561324181612f45565b809150509250925092565b6020808252600690820152651b1bd8dad95960d21b604082015260600190565b60006020828403121561327e57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b818103818111156106e6576106e6613285565b80820281158282048414176106e6576106e6613285565b634e487b7160e01b600052601260045260246000fd5b6000826132f857634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561330f57600080fd5b8151611e8b81612f45565b6020808252600990820152683337b93134b23232b760b91b604082015260600190565b808201808211156106e6576106e6613285565b600081600f0b60016001607f1b0319810361336d5761336d613285565b60000392915050565b60006001820161338857613388613285565b5060010190565b6000825160005b818110156133b05760208186018101518583015201613396565b506000920191825250919050565b6000602082840312156133d057600080fd5b8151611e8b816130a0565b634e487b7160e01b600052600160045260246000fdfea26469706673582212208113f0fd5bbe3e437f724f732fbfb0bfd92673f1eef81207adb1c0d8c55fc76964736f6c63430008110033a26469706673582212204f88580ee3d7627cfdb048d254107c8ae7655968a14edb7967e58f66987380ee64736f6c634300081100330000000000000000000000006791ae3dd42abf0e4ae72a0a5a41c458fb4706ac
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100b45760003560e01c806392eefe9b1161007157806392eefe9b14610176578063a1256f9f14610189578063a2cab3a1146101ad578063c6c5e21c146101c0578063c9c65396146101c8578063f77c4791146101db57600080fd5b806302c54874146100b95780631bf31828146100f75780631e3dd18b146101015780635431927d1461012c578063574f2ba3146101345780635eced4801461013c575b600080fd5b6100e46100c73660046106b1565b600260209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100ff6101ee565b005b61011461010f3660046106e4565b610236565b6040516001600160a01b0390911681526020016100ee565b6100e4610260565b6004546100e4565b61011461014a3660046106fd565b60036020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b6100ff610184366004610739565b610292565b60015461019d90600160a01b900460ff1681565b60405190151581526020016100ee565b600154610114906001600160a01b031681565b6100ff610334565b6101146101d63660046106b1565b61037e565b600054610114906001600160a01b031681565b6000546001600160a01b031633146102215760405162461bcd60e51b81526004016102189061075b565b60405180910390fd5b6001805460ff60a01b1916600160a01b179055565b6004818154811061024657600080fd5b6000918252602090912001546001600160a01b0316905081565b60006040518060200161027290610688565b6020820181038252601f19601f8201166040525080519060200120905090565b6001600160a01b0381166102e85760405162461bcd60e51b815260206004820152601960248201527f636f6e74726f6c6c65722063616e6e6f74206265207a65726f000000000000006044820152606401610218565b6000546001600160a01b031633146103125760405162461bcd60e51b81526004016102189061075b565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b0316331461035e5760405162461bcd60e51b81526004016102189061075b565b600180546001600160a01b03199081169091556000805490911633179055565b600154600090600160a01b900460ff16806103a357506000546001600160a01b031633145b6103bf5760405162461bcd60e51b81526004016102189061075b565b816001600160a01b0316836001600160a01b0316036104165760405162461bcd60e51b81526020600482015260136024820152726964656e746963616c2061646472657373657360681b6044820152606401610218565b600080836001600160a01b0316856001600160a01b03161061043957838561043c565b84845b90925090506001600160a01b0382166104865760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b6044820152606401610218565b6001600160a01b0380831660009081526002602090815260408083209385168352929052908120805482906104ba90610794565b91829055506040516bffffffffffffffffffffffff19606086811b8216602084015285901b166034820152604881018290529091506000906068016040516020818303038152906040528051906020012090508060405161051a90610688565b8190604051809103906000f590508015801561053a573d6000803e3d6000fd5b5060405163485cc95560e01b81526001600160a01b03868116600483015285811660248301529196509086169063485cc95590604401600060405180830381600087803b15801561058a57600080fd5b505af115801561059e573d6000803e3d6000fd5b505050506001600160a01b038481166000908152600360209081526040808320938716835292905290812086916105d66001866107ad565b81526020808201929092526040908101600090812080546001600160a01b039586166001600160a01b0319918216179091556004805460018101825592527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b90910180548a8616921682179055815186815292830152858316928716917fc3168168beb4136b347bbd2afd38adb2282984cdfba1e15b86d35942f015f4ca910160405180910390a35050505092915050565b61354a806107c783390190565b80356001600160a01b03811681146106ac57600080fd5b919050565b600080604083850312156106c457600080fd5b6106cd83610695565b91506106db60208401610695565b90509250929050565b6000602082840312156106f657600080fd5b5035919050565b60008060006060848603121561071257600080fd5b61071b84610695565b925061072960208501610695565b9150604084013590509250925092565b60006020828403121561074b57600080fd5b61075482610695565b9392505050565b6020808252600990820152683337b93134b23232b760b91b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000600182016107a6576107a661077e565b5060010190565b818103818111156107c0576107c061077e565b9291505056fe60a0604052600180546001600160401b0319166102d01781556006556709b6e64a8ec60000600a5534801561003357600080fd5b5060408051808201825260048152632830b4b960e11b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527feb97ef53980152ad9ea08faf89a3bce92c73647576c726a0fba9da4e28269ade818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152466080808301919091523060a0808401919091528451808403909101815260c0909201909352805191012090819052613427610123600039600081816102fa0152610d7e01526134276000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80637ecebe001161010f578063d4d5d32a116100a2578063e146141c11610071578063e146141c14610517578063e162402f1461052a578063f385cecb1461053d578063f46901ed1461054657600080fd5b8063d4d5d32a14610487578063d4f26c511461048f578063dc950d36146104a2578063e0b117ff146104c257600080fd5b8063b2118a8d116100de578063b2118a8d14610427578063c45a01551461043a578063c9f10f8c1461044d578063d21220a71461047457600080fd5b80637ecebe00146103ce5780637f568f18146103ee578063a22cb46514610401578063a9d9db4d1461041457600080fd5b80633644e5151161018757806359362b881161015657806359362b8814610355578063666093341461037d5780637b7e9fac146103a85780637bc90d1c146103bb57600080fd5b80633644e515146102f557806336e9332d1461031c578063485cc9551461032f57806353d56bf51461034257600080fd5b80630dfe1681116101c35780630dfe1681146102925780631bf1fffb146102ac57806322ff2a8e146102cd57806330d6618e146102e257600080fd5b8062f714ce146101f4578063017e7e58146102215780630902f1ac1461024c5780630d95e05414610254575b600080fd5b610207610202366004612f5d565b610559565b604080519283526020830191909152015b60405180910390f35b600354610234906001600160a01b031681565b6040516001600160a01b039091168152602001610218565b6102076105a7565b610282610262366004612f8d565b600d60209081526000928352604080842090915290825290205460ff1681565b6040519015158152602001610218565b60015461023490600160401b90046001600160a01b031681565b6102bf6102ba366004612fbb565b6106b2565b604051908152602001610218565b6102e06102db366004612feb565b6107a1565b005b6102bf6102f0366004613006565b6108f3565b6102bf7f000000000000000000000000000000000000000000000000000000000000000081565b600954610234906001600160a01b031681565b6102e061033d366004612f8d565b6109f8565b6102bf610350366004613041565b610a18565b61035d610b13565b604080516001600160401b03938416815292909116602083015201610218565b61039061038b366004613076565b610b8d565b6040516001600160401b039091168152602001610218565b6102e06103b63660046130ae565b610be3565b600154610390906001600160401b031681565b6102bf6103dc366004613160565b60076020526000908152604090205481565b6102e06103fc366004612fbb565b610ecf565b6102e061040f36600461317d565b610fac565b6102bf610422366004613041565b611068565b6102e06104353660046131ab565b611152565b600854610234906001600160a01b031681565b6102bf7fd7db667cdba90ca333b850481afd8f802dc1081fc1d7ee77ee75ae69468a0b1781565b600254610234906001600160a01b031681565b6102e061123d565b6102e061049d366004613160565b611273565b6102bf6104b0366004613160565b600b6020526000908152604090205481565b6104fc6104d03660046131ec565b600c60209081526000928352604080842090915290825290208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610218565b6102bf610525366004613006565b61136d565b61020761053836600461320a565b61145e565b6102bf600a5481565b6102e0610554366004613160565b6114d9565b6000806006546001146105875760405162461bcd60e51b815260040161057e9061324c565b60405180910390fd5b60006006556105973385856115ec565b6001600655909590945092505050565b600480546001546040516370a0823160e01b81523093810193909352600092839291600160401b90046001600160a01b0316906370a0823190602401602060405180830381865afa158015610600573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610624919061326c565b61062e919061329b565b6005546002546040516370a0823160e01b815230600482015292945090916001600160a01b03909116906370a0823190602401602060405180830381865afa15801561067e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a2919061326c565b6106ac919061329b565b90509091565b60008162015180036106ec57670de0b6b3a7640000600a54664a620d26ead0e46106dc91906132ae565b6106e691906132db565b92915050565b816203f4800361071457670de0b6b3a7640000600a546680d5cceb1376a86106dc91906132ae565b8162093a800361073c57670de0b6b3a7640000600a5466c4cc884ac66cf86106dc91906132ae565b8162278d000361076557670de0b6b3a7640000600a54670197699c5ceeb4006106dc91906132ae565b60405162461bcd60e51b815260206004820152600c60248201526b696e76616c69642074696d6560a01b604482015260640161057e565b919050565b6006546001146107c35760405162461bcd60e51b815260040161057e9061324c565b6000600681905550336001600160a01b0316600860009054906101000a90046001600160a01b03166001600160a01b031663f77c47916040518163ffffffff1660e01b81526004016020604051808303816000875af115801561082a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084e91906132fd565b6001600160a01b0316146108745760405162461bcd60e51b815260040161057e9061331a565b6000816001600160401b0316116108cd5760405162461bcd60e51b815260206004820152601860248201527f68616c66206c6966652063616e6e6f74206265207a65726f0000000000000000604482015260640161057e565b6001805467ffffffffffffffff19166001600160401b0392909216919091178155600655565b60006006546001146109175760405162461bcd60e51b815260040161057e9061324c565b60006006556001600160a01b0385166109665760405162461bcd60e51b8152602060048201526011602482015270746f2063616e6e6f74206265207a65726f60781b604482015260640161057e565b6000610972858561187d565b925090506000610981846106b2565b9050610992876000858988866119a7565b6003546001600160a01b0316156109c5576109ae6002836132db565b600560008282546109bf919061333d565b90915550505b6002546109dd906001600160a01b0316333089611ae7565b6109e987878584611c17565b50506001600655949350505050565b610a028282611cc5565b5050600880546001600160a01b03191633179055565b6000600654600114610a3c5760405162461bcd60e51b815260040161057e9061324c565b60006006819055610a4d848461187d565b6003549093509091506001600160a01b031615610a8657610a6f6002826132db565b60056000828254610a80919061333d565b90915550505b600254610a9e906001600160a01b0316333087611ae7565b600154610abc90600160401b90046001600160a01b03168684611d36565b60408051858152602081018490526001600160a01b0387169160009133917f66251e495e6e69e208ab08e2bc259dbe2ef482a8c4a93b8984b03a1eb27e1b9e91015b60405180910390a45060016006559392505050565b600080600080610b4b6000546001600160401b0380821692600160401b8304821692600160801b8104831692600160c01b9091041690565b92965090945092509050610b6c8461038b6001600160401b0385164261329b565b9350610b858361038b6001600160401b0384164261329b565b925050509091565b6001546000908190610ba99084906001600160401b0316611e51565b90506000610bc1610bb983613350565b600f0b611e92565b9050610bda600f82900b6001600160401b038716612950565b95945050505050565b8242111580610bf0575082155b610c2e5760405162461bcd60e51b815260206004820152600f60248201526e65786365656420646561646c696e6560881b604482015260640161057e565b6001600160a01b038616610c7b5760405162461bcd60e51b81526020600482015260146024820152736f776e65722063616e6e6f74206265207a65726f60601b604482015260640161057e565b6001600160a01b038516610ccb5760405162461bcd60e51b81526020600482015260176024820152766f70657261746f722063616e6e6f74206265207a65726f60481b604482015260640161057e565b6001600160a01b038616600090815260076020526040812080547fd7db667cdba90ca333b850481afd8f802dc1081fc1d7ee77ee75ae69468a0b17918991899189919086610d1883613376565b909155506040805160208101969096526001600160a01b03948516908601529290911660608401521515608083015260a082015260c0810185905260e00160408051601f1981840301815290829052805160209182012061190160f01b918301919091527f00000000000000000000000000000000000000000000000000000000000000006022830152604282018190529150600090606201604051602081830303815290604052805190602001209050610e098185858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129bb92505050565b6001600160a01b0316886001600160a01b031614610e5d5760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b604482015260640161057e565b6001600160a01b038881166000818152600d60209081526040808320948c1680845294825291829020805460ff19168b151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050505050505050565b600654600114610ef15760405162461bcd60e51b815260040161057e9061324c565b6000600681905550336001600160a01b0316600860009054906101000a90046001600160a01b03166001600160a01b031663f77c47916040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610f58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7c91906132fd565b6001600160a01b031614610fa25760405162461bcd60e51b815260040161057e9061331a565b600a556001600655565b6001600160a01b038216610ffc5760405162461bcd60e51b81526020600482015260176024820152766f70657261746f722063616e6e6f74206265207a65726f60481b604482015260640161057e565b336000818152600d602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600060065460011461108c5760405162461bcd60e51b815260040161057e9061324c565b6000600681905561109d8484612aa4565b6003549093509091506001600160a01b0316156110d6576110bf6002826132db565b600460008282546110d0919061333d565b90915550505b6001546110f590600160401b90046001600160a01b0316333087611ae7565b60025461110c906001600160a01b03168684611d36565b60408051858152602081018490526001600160a01b0387169160019133917f66251e495e6e69e208ab08e2bc259dbe2ef482a8c4a93b8984b03a1eb27e1b9e9101610afe565b6008546040805163f77c479160e01b8152905133926001600160a01b03169163f77c479191600480830192602092919082900301816000875af115801561119d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c191906132fd565b6001600160a01b0316146111e75760405162461bcd60e51b815260040161057e9061331a565b6001546001600160a01b03600160401b90910481169084160361120957600080fd5b6002546001600160a01b039081169084160361122457600080fd5b6112386001600160a01b0384168383611d36565b505050565b60065460011461125f5760405162461bcd60e51b815260040161057e9061324c565b600060065561126c612bc1565b6001600655565b6006546001146112955760405162461bcd60e51b815260040161057e9061324c565b6000600681905550336001600160a01b0316600860009054906101000a90046001600160a01b03166001600160a01b031663f77c47916040518163ffffffff1660e01b81526004016020604051808303816000875af11580156112fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132091906132fd565b6001600160a01b0316146113465760405162461bcd60e51b815260040161057e9061331a565b600980546001600160a01b0319166001600160a01b03929092169190911790556001600655565b60006006546001146113915760405162461bcd60e51b815260040161057e9061324c565b60006006556001600160a01b0385166113e05760405162461bcd60e51b8152602060048201526011602482015270746f2063616e6e6f74206265207a65726f60781b604482015260640161057e565b60006113ec8585612aa4565b9250905060006113fb846106b2565b905061140c876001888688866119a7565b6003546001600160a01b03161561143f576114286002836132db565b60046000828254611439919061333d565b90915550505b6001546109dd90600160401b90046001600160a01b0316333089611ae7565b6001600160a01b0383166000908152600d60209081526040808320338452909152812054819060ff166114c25760405162461bcd60e51b815260206004820152600c60248201526b3737ba1037b832b930ba37b960a11b604482015260640161057e565b6114cd8585856115ec565b91509150935093915050565b6006546001146114fb5760405162461bcd60e51b815260040161057e9061324c565b6000600681905550336001600160a01b0316600860009054906101000a90046001600160a01b03166001600160a01b031663f77c47916040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611562573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158691906132fd565b6001600160a01b0316146115ac5760405162461bcd60e51b815260040161057e9061331a565b6003546001600160a01b0316156115c5576115c5612bc1565b600380546001600160a01b0319166001600160a01b03929092169190911790556001600655565b6001600160a01b0383166000908152600c6020908152604080832085845290915281208054600182018054600284018054868655928690559490945590929190806116685760405162461bcd60e51b815260206004820152600c60248201526b696e76616c6964206e6f746560a01b604482015260640161057e565b428111156116ab5760405162461bcd60e51b815260206004820152601060248201526f19585c9b1e481dda5d1a191c985dd85b60821b604482015260640161057e565b6000806116b66105a7565b915091506000806116c5610b13565b9092509050826116da886401000000006132ae565b6116e491906132db565b84896117346117006001600160401b038616600160401b61329b565b6117176001600160401b038816600160401b61329b565b61172590600160401b6132ae565b61172f91906132db565b612c53565b61173e91906132ae565b61174891906132db565b10156117e4576001546000975061177090600160401b90046001600160a01b03168a8a611d36565b600084611781600160401b8b6132ae565b61178b91906132db565b90506117978382612cfb565b604080518c8152602081018b90526001916001600160a01b038f16917f8595f614655883bce3496fde65b1ff62bb8b336cc93d72a91cd2f61f1566872f910160405180910390a35061186f565b600254600098506117ff906001600160a01b03168a89611d36565b600083611810600160401b8a6132ae565b61181a91906132db565b90506118268282612d48565b604080518c8152602081018a90526000916001600160a01b038f16917f8595f614655883bce3496fde65b1ff62bb8b336cc93d72a91cd2f61f1566872f910160405180910390a3505b505050505050935093915050565b600080600084116118c75760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a59081a5b9c1d5d08185b5bdd5b9d60621b604482015260640161057e565b6000806118d26105a7565b915091506000806118e1610b13565b9092509050600160401b6118fe896001600160401b0384166132ae565b61190891906132db565b95506000611916878a61329b565b9050611922818561333d565b61192c86836132ae565b61193691906132db565b9550878610156119735760405162461bcd60e51b8152602060048201526008602482015267736c69707061676560c01b604482015260640161057e565b600085611984600160401b896132ae565b61198e91906132db565b905061199a8482612cfb565b5050505050509250929050565b6001600160a01b0386166000908152600b60205260408120805490826119cc83613376565b909155506001600160a01b0388166000908152600c60209081526040808320848452909152812091925087611a015785611a03565b865b90506000670de0b6b3a7640000611a1a818761333d565b611a24908a6132ae565b611a2e91906132db565b90506000670de0b6b3a7640000611a45818861333d565b611a4f908a6132ae565b611a5991906132db565b90506000611a67884261333d565b8386556001860183905560028601819055604080518881526020810187905290810185905260608101849052608081018290529091508b1515906001600160a01b038e16907f1a03e701f999967b189f59a5e5d6ddefdc9b644975d45bcf544d8755719a0bd79060a00160405180910390a3505050505050505050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691611b4b919061338f565b6000604051808303816000865af19150503d8060008114611b88576040519150601f19603f3d011682016040523d82523d6000602084013e611b8d565b606091505b5091509150818015611bb7575080511580611bb7575080806020019051810190611bb791906133be565b611c0f5760405162461bcd60e51b815260206004820152602360248201527f7472616e7366657248656c7065723a207472616e7366657246726f6d206661696044820152621b195960ea1b606482015260840161057e565b505050505050565b6009546001600160a01b031615611cbf576000670de0b6b3a764000082611c4161172f86886132ae565b611c4b91906132ae565b611c5591906132db565b6009546040516352edeea160e01b81526001600160a01b038881166004830152602482018490529293509116906352edeea190604401600060405180830381600087803b158015611ca557600080fd5b505af1158015611cb9573d6000803e3d6000fd5b50505050505b50505050565b600154600160401b90046001600160a01b031615611cf55760405162461bcd60e51b815260040161057e9061331a565b6001805468010000000000000000600160e01b031916600160401b6001600160a01b0394851602179055600280546001600160a01b03191691909216179055565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691611d92919061338f565b6000604051808303816000865af19150503d8060008114611dcf576040519150601f19603f3d011682016040523d82523d6000602084013e611dd4565b606091505b5091509150818015611dfe575080511580611dfe575080806020019051810190611dfe91906133be565b611e4a5760405162461bcd60e51b815260206004820152601f60248201527f7472616e7366657248656c7065723a207472616e73666572206661696c656400604482015260640161057e565b5050505050565b600081600003611e6057600080fd5b6000611e6c8484612da3565b905060016001607f1b036001600160801b0382161115611e8b57600080fd5b9392505050565b60006840000000000000000082600f0b12611eac57600080fd5b683fffffffffffffffff1982600f0b1215611ec957506000919050565b6001607f1b60006780000000000000008416600f0b1315611efb5770016a09e667f3bcc908b2fb1366ea957d3e0260801c5b60008367400000000000000016600f0b1315611f28577001306fe0a31b7152de8d5a46305c85edec0260801c5b60008367200000000000000016600f0b1315611f55577001172b83c7d517adcdf7c8c50eb14a791f0260801c5b60008367100000000000000016600f0b1315611f825770010b5586cf9890f6298b92b71842a983630260801c5b60008367080000000000000016600f0b1315611faf577001059b0d31585743ae7c548eb68ca417fd0260801c5b60008367040000000000000016600f0b1315611fdc57700102c9a3e778060ee6f7caca4f7a29bde80260801c5b60008367020000000000000016600f0b13156120095770010163da9fb33356d84a66ae336dcdfa3f0260801c5b60008367010000000000000016600f0b131561203657700100b1afa5abcbed6129ab13ec11dc95430260801c5b600083668000000000000016600f0b13156120625770010058c86da1c09ea1ff19d294cf2f679b0260801c5b600083664000000000000016600f0b131561208e577001002c605e2e8cec506d21bfc89a23a00f0260801c5b600083662000000000000016600f0b13156120ba57700100162f3904051fa128bca9c55c31e5df0260801c5b600083661000000000000016600f0b13156120e6577001000b175effdc76ba38e31671ca9397250260801c5b600083660800000000000016600f0b131561211257700100058ba01fb9f96d6cacd4b180917c3d0260801c5b600083660400000000000016600f0b131561213e5770010002c5cc37da9491d0985c348c68e7b30260801c5b600083660200000000000016600f0b131561216a577001000162e525ee054754457d59952920260260801c5b600083660100000000000016600f0b13156121965770010000b17255775c040618bf4a4ade83fc0260801c5b6000836580000000000016600f0b13156121c1577001000058b91b5bc9ae2eed81e9b7d4cfab0260801c5b6000836540000000000016600f0b13156121ec57700100002c5c89d5ec6ca4d7c8acc017b7c90260801c5b6000836520000000000016600f0b13156122175770010000162e43f4f831060e02d839a9d16d0260801c5b6000836510000000000016600f0b131561224257700100000b1721bcfc99d9f890ea069117630260801c5b6000836508000000000016600f0b131561226d5770010000058b90cf1e6d97f9ca14dbcc16280260801c5b6000836504000000000016600f0b1315612298577001000002c5c863b73f016468f6bac5ca2b0260801c5b6000836502000000000016600f0b13156122c357700100000162e430e5a18f6119e3c02282a50260801c5b6000836501000000000016600f0b13156122ee577001000000b1721835514b86e6d96efd1bfe0260801c5b60008364800000000016600f0b131561231857700100000058b90c0b48c6be5df846c5b2ef0260801c5b60008364400000000016600f0b13156123425770010000002c5c8601cc6b9e94213c72737a0260801c5b60008364200000000016600f0b131561236c577001000000162e42fff037df38aa2b219f060260801c5b60008364100000000016600f0b13156123965770010000000b17217fba9c739aa5819f44f90260801c5b60008364080000000016600f0b13156123c0577001000000058b90bfcdee5acd3c1cedc8230260801c5b60008364040000000016600f0b13156123ea57700100000002c5c85fe31f35a6a30da1be500260801c5b60008364020000000016600f0b13156124145770010000000162e42ff0999ce3541b9fffcf0260801c5b60008364010000000016600f0b131561243e57700100000000b17217f80f4ef5aadda455540260801c5b600083638000000016600f0b13156124675770010000000058b90bfbf8479bd5a81b51ad0260801c5b600083634000000016600f0b1315612490577001000000002c5c85fdf84bd62ae30a74cc0260801c5b600083632000000016600f0b13156124b957700100000000162e42fefb2fed257559bdaa0260801c5b600083631000000016600f0b13156124e2577001000000000b17217f7d5a7716bba4a9ae0260801c5b600083630800000016600f0b131561250b57700100000000058b90bfbe9ddbac5e109cce0260801c5b600083630400000016600f0b13156125345770010000000002c5c85fdf4b15de6f17eb0d0260801c5b600083630200000016600f0b131561255d577001000000000162e42fefa494f1478fde050260801c5b600083630100000016600f0b13156125865770010000000000b17217f7d20cf927c8e94c0260801c5b6000836280000016600f0b13156125ae577001000000000058b90bfbe8f71cb4e4b33d0260801c5b6000836240000016600f0b13156125d657700100000000002c5c85fdf477b662b269450260801c5b6000836220000016600f0b13156125fe5770010000000000162e42fefa3ae53369388c0260801c5b6000836210000016600f0b131561262657700100000000000b17217f7d1d351a389d400260801c5b6000836208000016600f0b131561264e5770010000000000058b90bfbe8e8b2d3d4ede0260801c5b6000836204000016600f0b1315612676577001000000000002c5c85fdf4741bea6e77e0260801c5b6000836202000016600f0b131561269e57700100000000000162e42fefa39fe95583c20260801c5b6000836201000016600f0b13156126c6577001000000000000b17217f7d1cfb72b45e10260801c5b60008361800016600f0b13156126ed57700100000000000058b90bfbe8e7cc35c3f00260801c5b60008361400016600f0b13156127145770010000000000002c5c85fdf473e242ea380260801c5b60008361200016600f0b131561273b577001000000000000162e42fefa39f02b772c0260801c5b60008361100016600f0b13156127625770010000000000000b17217f7d1cf7d83c1a0260801c5b60008361080016600f0b1315612789577001000000000000058b90bfbe8e7bdcbe2e0260801c5b60008361040016600f0b13156127b057700100000000000002c5c85fdf473dea871f0260801c5b60008361020016600f0b13156127d75770010000000000000162e42fefa39ef44d910260801c5b60008361010016600f0b13156127fe57700100000000000000b17217f7d1cf79e9490260801c5b600083608016600f0b13156128245770010000000000000058b90bfbe8e7bce5440260801c5b600083604016600f0b131561284a577001000000000000002c5c85fdf473de6eca0260801c5b600083602016600f0b131561287057700100000000000000162e42fefa39ef366f0260801c5b600083601016600f0b1315612896577001000000000000000b17217f7d1cf79afa0260801c5b600083600816600f0b13156128bc57700100000000000000058b90bfbe8e7bcd6d0260801c5b600083600416600f0b13156128e25770010000000000000002c5c85fdf473de6b20260801c5b600083600216600f0b1315612908577001000000000000000162e42fefa39ef3580260801c5b600083600116600f0b131561292e5770010000000000000000b17217f7d1cf79ab0260801c5b600f83810b60401d603f03900b1c60016001607f1b038111156106e657600080fd5b600081600003612962575060006106e6565b600083600f0b121561297357600080fd5b600f83900b6001600160801b038316810260401c90608084901c026001600160c01b038111156129a257600080fd5b60401b81198111156129b357600080fd5b019392505050565b60008151604103612a9c5760208201516040830151606084015160001a7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115612a0c57600093505050506106e6565b8060ff16601b14158015612a2457508060ff16601c14155b15612a3557600093505050506106e6565b60408051600081526020810180835288905260ff831691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015612a88573d6000803e3d6000fd5b5050506020604051035193505050506106e6565b5060006106e6565b60008060008411612aee5760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a59081a5b9c1d5d08185b5bdd5b9d60621b604482015260640161057e565b600080612af96105a7565b91509150600080612b08610b13565b9092509050600160401b612b25896001600160401b0385166132ae565b612b2f91906132db565b95506000612b3d878a61329b565b9050612b49818661333d565b612b5385836132ae565b612b5d91906132db565b955087861015612b9a5760405162461bcd60e51b8152602060048201526008602482015267736c69707061676560c01b604482015260640161057e565b600084612bab600160401b896132ae565b612bb591906132db565b905061199a8382612d48565b6004805460058054600093849055929055600354600154919291612bf9916001600160a01b03600160401b9092048216911684611d36565b600354600254612c16916001600160a01b03918216911683611d36565b60408051838152602081018390527faf7c505ee772ec188af7067e1f73db08ab028e3d564273442b907742b9c41fa0910160405180910390a15050565b60b581600160881b8110612c6c5760409190911b9060801c5b69010000000000000000008110612c885760209190911b9060401c5b650100000000008110612ca05760109190911b9060201c5b63010000008110612cb65760089190911b9060101c5b62010000010260121c80820401600190811c80830401811c80830401811c80830401811c80830401811c80830401811c80830401901c80820481111561079c57900490565b612d058282612f08565b60008054426001600160401b03908116600160801b0277ffffffffffffffff0000000000000000ffffffffffffffff199092169316929092179190911790555050565b612d528282612f08565b6000805477ffffffffffffffff0000000000000000ffffffffffffffff16600160401b6001600160401b03938416026001600160c01b031617600160c01b4293909316929092029190911790555050565b600081600003612db257600080fd5b60006001600160c01b038411612ddd5782604085901b81612dd557612dd56132c5565b049050612ef4565b60c084811c6401000000008110612df6576020918201911c5b620100008110612e08576010918201911c5b6101008110612e19576008918201911c5b60108110612e29576004918201911c5b60048110612e39576002918201911c5b60028110612e48576001820191505b60bf820360018603901c6001018260ff0387901b81612e6957612e696132c5565b0492506001600160801b03831115612e8057600080fd5b608085901c83026001600160801b038616840260c088901c604089901b82811015612eac576001820391505b608084901b92900382811015612ec3576001820391505b829003608084901c8214612ed957612ed96133db565b888181612ee857612ee86132c5565b04870196505050505050505b6001600160801b03811115611e8b57600080fd5b60006001600160401b03808416908316600160401b612f2782846132ae565b612f3191906132db565b612f3b828461333d565b610bda919061329b565b6001600160a01b0381168114612f5a57600080fd5b50565b60008060408385031215612f7057600080fd5b823591506020830135612f8281612f45565b809150509250929050565b60008060408385031215612fa057600080fd5b8235612fab81612f45565b91506020830135612f8281612f45565b600060208284031215612fcd57600080fd5b5035919050565b80356001600160401b038116811461079c57600080fd5b600060208284031215612ffd57600080fd5b611e8b82612fd4565b6000806000806080858703121561301c57600080fd5b843561302781612f45565b966020860135965060408601359560600135945092505050565b60008060006060848603121561305657600080fd5b833561306181612f45565b95602085013595506040909401359392505050565b6000806040838503121561308957600080fd5b61309283612fd4565b946020939093013593505050565b8015158114612f5a57600080fd5b60008060008060008060a087890312156130c757600080fd5b86356130d281612f45565b955060208701356130e281612f45565b945060408701356130f2816130a0565b93506060870135925060808701356001600160401b038082111561311557600080fd5b818901915089601f83011261312957600080fd5b81358181111561313857600080fd5b8a602082850101111561314a57600080fd5b6020830194508093505050509295509295509295565b60006020828403121561317257600080fd5b8135611e8b81612f45565b6000806040838503121561319057600080fd5b823561319b81612f45565b91506020830135612f82816130a0565b6000806000606084860312156131c057600080fd5b83356131cb81612f45565b925060208401356131db81612f45565b929592945050506040919091013590565b600080604083850312156131ff57600080fd5b823561309281612f45565b60008060006060848603121561321f57600080fd5b833561322a81612f45565b925060208401359150604084013561324181612f45565b809150509250925092565b6020808252600690820152651b1bd8dad95960d21b604082015260600190565b60006020828403121561327e57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b818103818111156106e6576106e6613285565b80820281158282048414176106e6576106e6613285565b634e487b7160e01b600052601260045260246000fd5b6000826132f857634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561330f57600080fd5b8151611e8b81612f45565b6020808252600990820152683337b93134b23232b760b91b604082015260600190565b808201808211156106e6576106e6613285565b600081600f0b60016001607f1b0319810361336d5761336d613285565b60000392915050565b60006001820161338857613388613285565b5060010190565b6000825160005b818110156133b05760208186018101518583015201613396565b506000920191825250919050565b6000602082840312156133d057600080fd5b8151611e8b816130a0565b634e487b7160e01b600052600160045260246000fdfea26469706673582212208113f0fd5bbe3e437f724f732fbfb0bfd92673f1eef81207adb1c0d8c55fc76964736f6c63430008110033a26469706673582212204f88580ee3d7627cfdb048d254107c8ae7655968a14edb7967e58f66987380ee64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006791ae3dd42abf0e4ae72a0a5a41c458fb4706ac
-----Decoded View---------------
Arg [0] : _controller (address): 0x6791ae3Dd42ABF0E4Ae72a0a5A41C458fB4706aC
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000006791ae3dd42abf0e4ae72a0a5a41c458fb4706ac
Loading...
Loading
Loading...
Loading
OVERVIEW
PairFactory is the contract that deploys DysonPair. Unlike Uniswap, Dyson allows multiple Pair instances for a trading pair of two tokens. Factory also serves as a beacon providing the current controller address for all pairs.Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.