Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Synthesis
- Optimization enabled
- true
- Compiler version
- v0.8.7+commit.e28d00a7
- Optimization runs
- 2000
- EVM Version
- default
- Verified at
- 2025-07-16T06:31:58.217610Z
contracts/synth-core/Synthesis.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "@uniswap/lib/contracts/libraries/TransferHelper.sol";
import "./interfaces/IBridge.sol";
import "./interfaces/ISyntFabric.sol";
import "../utils/RelayRecipientUpgradeable.sol";
import "./metarouter/interfaces/IMetaRouter.sol";
/**
* @title A contract that burns (unsynthesizes) tokens
* @dev All function calls are currently implemented without side effects
*/
contract Synthesis is RelayRecipientUpgradeable {
/// ** PUBLIC states **
uint256 public requestCount;
bool public paused;
address public bridge;
address public fabric;
mapping(bytes32 => SynthesizeState) public synthesizeStates;
mapping(bytes32 => TxState) public requests;
mapping(address => uint256) public tokenThreshold;
IMetaRouter public metaRouter;
/// ** STRUCTS **
enum RequestState {
Default,
Sent,
Reverted
}
enum SynthesizeState {
Default,
Synthesized,
RevertRequest
}
struct TxState {
address recipient;
address chain2address;
uint256 amount;
address token;
address stoken;
RequestState state;
}
/// ** EVENTS **
event BurnRequest(
bytes32 id,
address indexed from,
uint256 indexed chainID,
address indexed revertableAddress,
address to,
uint256 amount,
address token
);
event RevertSynthesizeRequest(bytes32 indexed id, address indexed to);
event ClientIdLog(bytes32 requestId, bytes32 indexed clientId);
event SynthesizeCompleted(
bytes32 indexed id,
address indexed to,
bytes32 indexed crossChainID,
uint256 amount,
uint256 bridgingFee,
address token
);
event RevertBurnCompleted(
bytes32 indexed id,
address indexed to,
uint256 amount,
uint256 bridgingFee,
address token
);
event Paused(address account);
event Unpaused(address account);
event SetTokenThreshold(address token, uint256 threshold);
event SetMetaRouter(address metaRouter);
event SetFabric(address fabric);
/// ** MODIFIERs **
modifier onlyBridge() {
require(bridge == msg.sender, "Symb: caller is not the bridge");
_;
}
modifier whenNotPaused() {
require(!paused, "Symb: paused");
_;
}
/// ** INITIALIZER **
/**
* init
*/
function initialize(
address _bridge,
address _trustedForwarder,
IMetaRouter _metaRouter
)
public
virtual
initializer
{
__RelayRecipient_init(_trustedForwarder);
bridge = _bridge;
metaRouter = _metaRouter;
}
/// ** EXTERNAL PURE functions **
/**
* @notice Returns version
*/
function versionRecipient() external pure returns (string memory) {
return "2.0.1";
}
/// ** EXTERNAL functions **
/**
* @notice Synthesis contract subcall with synthesis Parameters
* @dev Can called only by bridge after initiation on a second chain
* @param _stableBridgingFee Bridging fee
* @param _externalID the synthesize transaction that was received from the event when it was originally called burn on the Synthesize contract
* @param _tokenReal The address of the token that the user wants to synthesize
* @param _chainID Chain id of the network where synthesization will take place
* @param _amount Number of tokens to synthesize
* @param _to The address to which the user wants to receive the synth asset on another network
*/
function mintSyntheticToken(
uint256 _stableBridgingFee,
bytes32 _externalID,
bytes32 _crossChainID,
address _tokenReal,
uint256 _chainID,
uint256 _amount,
address _to
) external onlyBridge whenNotPaused {
require(
synthesizeStates[_externalID] == SynthesizeState.Default,
"Symb: revertSynthesizedRequest called or tokens have been already synthesized"
);
synthesizeStates[_externalID] = SynthesizeState.Synthesized;
address syntReprAddr = ISyntFabric(fabric).getSyntRepresentation(_tokenReal, _chainID);
require(syntReprAddr != address(0), "Symb: There is no synt representation for this token");
ISyntFabric(fabric).synthesize(
_to,
_amount - _stableBridgingFee,
syntReprAddr
);
ISyntFabric(fabric).synthesize(
bridge,
_stableBridgingFee,
syntReprAddr
);
emit SynthesizeCompleted(_externalID, _to, _crossChainID, _amount - _stableBridgingFee, _stableBridgingFee, _tokenReal);
}
/**
* @notice Mint token assets and call second swap and final call
* @dev Can called only by bridge after initiation on a second chain
* @param _metaMintTransaction metaMint offchain transaction data
*/
function metaMintSyntheticToken(
MetaRouteStructs.MetaMintTransaction memory _metaMintTransaction
) external onlyBridge whenNotPaused {
require(
synthesizeStates[_metaMintTransaction.externalID] ==
SynthesizeState.Default,
"Symb: revertSynthesizedRequest called or tokens have been already synthesized"
);
synthesizeStates[_metaMintTransaction.externalID] = SynthesizeState
.Synthesized;
address syntReprAddr = ISyntFabric(fabric).getSyntRepresentation(
_metaMintTransaction.tokenReal,
_metaMintTransaction.chainID
);
require(syntReprAddr != address(0), "Symb: There is no synt representation for this token");
ISyntFabric(fabric).synthesize(
address(this),
_metaMintTransaction.amount - _metaMintTransaction.stableBridgingFee,
syntReprAddr
);
ISyntFabric(fabric).synthesize(
bridge,
_metaMintTransaction.stableBridgingFee,
syntReprAddr
);
_metaMintTransaction.amount = _metaMintTransaction.amount - _metaMintTransaction.stableBridgingFee;
if (_metaMintTransaction.swapTokens.length == 0) {
TransferHelper.safeTransfer(
syntReprAddr,
_metaMintTransaction.to,
_metaMintTransaction.amount
);
return;
}
// transfer ERC20 tokens to MetaRouter
TransferHelper.safeTransfer(
_metaMintTransaction.swapTokens[0],
address(metaRouter),
_metaMintTransaction.amount
);
// metaRouter swap
metaRouter.metaMintSwap(_metaMintTransaction);
// emitting event in the end because crossChainID is patched in metaMintSwap
emit SynthesizeCompleted(
_metaMintTransaction.externalID,
_metaMintTransaction.to,
_metaMintTransaction.crossChainID,
_metaMintTransaction.amount,
_metaMintTransaction.stableBridgingFee,
_metaMintTransaction.tokenReal
);
}
/**
* @notice Revert synthesize() operation
* @dev Can called only by bridge after initiation on a second chain
* @dev Further, this transaction also enters the relay network and is called on the other side under the method "revertSynthesize"
* @param _stableBridgingFee Bridging fee on another network
* @param _internalID the synthesize transaction that was received from the event when it was originally called synthesize on the Portal contract
* @param _receiveSide Synthesis address on another network
* @param _oppositeBridge Bridge address on another network
* @param _chainID Chain id of the network
*/
function revertSynthesizeRequest(
uint256 _stableBridgingFee,
bytes32 _internalID,
address _receiveSide,
address _oppositeBridge,
uint256 _chainID,
bytes32 _clientID
) external whenNotPaused {
bytes32 externalID = keccak256(abi.encodePacked(_internalID, address(this), _msgSender(), block.chainid));
require(
synthesizeStates[externalID] != SynthesizeState.Synthesized,
"Symb: synthetic tokens already minted"
);
synthesizeStates[externalID] = SynthesizeState.RevertRequest; // close
{
bytes memory out = abi.encodeWithSelector(
bytes4(keccak256(bytes("revertSynthesize(uint256,bytes32)"))),
_stableBridgingFee,
externalID
);
IBridge(bridge).transmitRequestV2(
out,
_receiveSide,
_oppositeBridge,
_chainID
);
}
emit RevertSynthesizeRequest(_internalID, _msgSender());
emit ClientIdLog(_internalID, _clientID);
}
function revertSynthesizeRequestByBridge(
uint256 _stableBridgingFee,
bytes32 _internalID,
address _receiveSide,
address _oppositeBridge,
uint256 _chainID,
address _sender,
bytes32 _clientID
) external whenNotPaused onlyBridge{
bytes32 externalID = keccak256(abi.encodePacked(_internalID, address(this), _sender, block.chainid));
require(
synthesizeStates[externalID] != SynthesizeState.Synthesized,
"Symb: synthetic tokens already minted"
);
synthesizeStates[externalID] = SynthesizeState.RevertRequest; // close
{
bytes memory out = abi.encodeWithSelector(
bytes4(keccak256(bytes("revertSynthesize(uint256,bytes32)"))),
_stableBridgingFee,
externalID
);
IBridge(bridge).transmitRequestV2(
out,
_receiveSide,
_oppositeBridge,
_chainID
);
}
emit ClientIdLog(_internalID, _clientID);
emit RevertSynthesizeRequest(_internalID, _sender);
}
/**
* @notice Sends burn request
* @dev sToken -> Token on a second chain
* @param _stableBridgingFee Bridging fee on another network
* @param _stoken The address of the token that the user wants to burn
* @param _amount Number of tokens to burn
* @param _chain2address The address to which the user wants to receive tokens
* @param _receiveSide Synthesis address on another network
* @param _oppositeBridge Bridge address on another network
* @param _revertableAddress An address on another network that allows the user to revert a stuck request
* @param _chainID Chain id of the network where burning will take place
*/
function burnSyntheticToken(
uint256 _stableBridgingFee,
address _stoken,
uint256 _amount,
address _chain2address,
address _receiveSide,
address _oppositeBridge,
address _revertableAddress,
uint256 _chainID,
bytes32 _clientID
) external whenNotPaused returns (bytes32 internalID) {
require(_amount >= tokenThreshold[_stoken], "Symb: amount under threshold");
ISyntFabric(fabric).unsynthesize(_msgSender(), _amount, _stoken);
if (_revertableAddress == address(0)) {
_revertableAddress = _chain2address;
}
{
address rtoken = ISyntFabric(fabric).getRealRepresentation(_stoken);
require(rtoken != address(0), "Symb: incorrect synt");
internalID = keccak256(
abi.encodePacked(this, requestCount, block.chainid)
);
bytes32 externalID = keccak256(abi.encodePacked(internalID, _receiveSide, _revertableAddress, _chainID));
bytes memory out = abi.encodeWithSelector(
bytes4(
keccak256(
bytes("unsynthesize(uint256,bytes32,bytes32,address,uint256,address)")
)
),
_stableBridgingFee,
externalID,
internalID,
rtoken,
_amount,
_chain2address
);
requests[externalID] = TxState({
recipient: _msgSender(),
chain2address: _chain2address,
token: rtoken,
stoken: _stoken,
amount: _amount,
state: RequestState.Sent
});
requestCount++;
IBridge(bridge).transmitRequestV2(
out,
_receiveSide,
_oppositeBridge,
_chainID
);
}
emit BurnRequest(internalID, _msgSender(), _chainID, _revertableAddress, _chain2address, _amount, _stoken);
emit ClientIdLog(internalID, _clientID);
}
/**
* @notice Sends metaBurn request
* @dev sToken -> Token -> finalToken on a second chain
* @param _metaBurnTransaction metaBurn transaction data
*/
function metaBurnSyntheticToken(
MetaRouteStructs.MetaBurnTransaction memory _metaBurnTransaction
) external whenNotPaused returns (bytes32 internalID) {
require(_metaBurnTransaction.amount >= tokenThreshold[_metaBurnTransaction.sToken], "Symb: amount under threshold");
ISyntFabric(fabric).unsynthesize(
_msgSender(),
_metaBurnTransaction.amount,
_metaBurnTransaction.sToken
);
if (_metaBurnTransaction.revertableAddress == address(0)) {
_metaBurnTransaction.revertableAddress = _metaBurnTransaction.chain2address;
}
{
address rtoken = ISyntFabric(fabric).getRealRepresentation(
_metaBurnTransaction.sToken
);
require(rtoken != address(0), "Symb: incorrect synt");
internalID = keccak256(
abi.encodePacked(this, requestCount, block.chainid)
);
if (_metaBurnTransaction.crossChainID == "") {
_metaBurnTransaction.crossChainID = internalID;
}
bytes32 externalID = keccak256(abi.encodePacked(internalID, _metaBurnTransaction.receiveSide, _metaBurnTransaction.revertableAddress, _metaBurnTransaction.chainID)); // external ID
bytes memory out = abi.encodeWithSelector(
bytes4(
keccak256(
bytes(
"metaUnsynthesize(uint256,bytes32,bytes32,address,uint256,address,address,bytes,uint256)"
)
)
),
_metaBurnTransaction.stableBridgingFee,
_metaBurnTransaction.crossChainID,
externalID,
_metaBurnTransaction.chain2address,
_metaBurnTransaction.amount,
rtoken,
_metaBurnTransaction.finalReceiveSide,
_metaBurnTransaction.finalCallData,
_metaBurnTransaction.finalOffset
);
requests[externalID] = TxState({
recipient: _metaBurnTransaction.syntCaller,
chain2address: _metaBurnTransaction.chain2address,
token: rtoken,
stoken: _metaBurnTransaction.sToken,
amount: _metaBurnTransaction.amount,
state: RequestState.Sent
});
requestCount++;
IBridge(bridge).transmitRequestV2(
out,
_metaBurnTransaction.receiveSide,
_metaBurnTransaction.oppositeBridge,
_metaBurnTransaction.chainID
);
}
emit BurnRequest(
internalID,
_metaBurnTransaction.syntCaller,
_metaBurnTransaction.chainID,
_metaBurnTransaction.revertableAddress,
_metaBurnTransaction.chain2address,
_metaBurnTransaction.amount,
_metaBurnTransaction.sToken
);
emit ClientIdLog(internalID, _metaBurnTransaction.clientID);
}
/**
* @notice Emergency unburn
* @dev Can called only by bridge after initiation on a second chain
* @param _stableBridgingFee Bridging fee
* @param _externalID the synthesize transaction that was received from the event when it was originally called burn on the Synthesize contract
*/
function revertBurn(uint256 _stableBridgingFee, bytes32 _externalID) external onlyBridge whenNotPaused {
TxState storage txState = requests[_externalID];
require(
txState.state == RequestState.Sent,
"Symb: state not open or tx does not exist"
);
txState.state = RequestState.Reverted;
// close
ISyntFabric(fabric).synthesize(
txState.recipient,
txState.amount - _stableBridgingFee,
txState.stoken
);
ISyntFabric(fabric).synthesize(
bridge,
_stableBridgingFee,
txState.stoken
);
emit RevertBurnCompleted(
_externalID,
txState.recipient,
txState.amount - _stableBridgingFee,
_stableBridgingFee,
txState.stoken
);
}
function revertBurnAndBurn(uint256 _stableBridgingFee, bytes32 _externalID, address _receiveSide, address _oppositeBridge, uint256 _chainID, address _revertableAddress) external onlyBridge whenNotPaused {
TxState storage txState = requests[_externalID];
require(
txState.state == RequestState.Sent,
"Symb: state not open or tx does not exist"
);
txState.state = RequestState.Reverted;
// close
ISyntFabric(fabric).synthesize(
bridge,
_stableBridgingFee,
txState.stoken
);
uint256 amount = txState.amount - _stableBridgingFee;
emit RevertBurnCompleted(
_externalID,
txState.recipient,
amount,
_stableBridgingFee,
txState.stoken
);
if (_revertableAddress == address(0)) {
_revertableAddress = txState.chain2address;
}
address rtoken = ISyntFabric(fabric).getRealRepresentation(txState.stoken);
bytes32 internalID = keccak256(
abi.encodePacked(this, requestCount, block.chainid)
);
bytes32 externalID = keccak256(abi.encodePacked(internalID, _receiveSide, _revertableAddress, _chainID));
bytes memory out = abi.encodeWithSelector(
bytes4(
keccak256(
bytes("unsynthesize(uint256,bytes32,address,uint256,address)")
)
),
_stableBridgingFee,
externalID,
rtoken,
amount,
txState.chain2address
);
requests[externalID] = TxState({
recipient: _msgSender(),
chain2address: txState.chain2address,
token: rtoken,
stoken: txState.stoken,
amount: amount,
state: RequestState.Sent
});
requestCount++;
IBridge(bridge).transmitRequestV2(
out,
_receiveSide,
_oppositeBridge,
_chainID
);
emit BurnRequest(internalID, _msgSender(), _chainID, _revertableAddress, txState.chain2address, amount, txState.stoken);
}
function revertMetaBurn(
uint256 _stableBridgingFee,
bytes32 _externalID,
address _router,
bytes calldata _swapCalldata,
address _synthesis,
address _burnToken,
bytes calldata _burnCalldata
) external onlyBridge whenNotPaused {
TxState storage txState = requests[_externalID];
require(
txState.state == RequestState.Sent,
"Symb: state not open or tx does not exist"
);
txState.state = RequestState.Reverted;
// close
ISyntFabric(fabric).synthesize(
txState.recipient,
txState.amount - _stableBridgingFee,
txState.stoken
);
ISyntFabric(fabric).synthesize(
bridge,
_stableBridgingFee,
txState.stoken
);
IMetaRouter(metaRouter).returnSwap(txState.stoken, txState.amount - _stableBridgingFee, _router, _swapCalldata, _burnToken, _synthesis, _burnCalldata);
emit RevertBurnCompleted(
_externalID,
txState.recipient,
txState.amount - _stableBridgingFee,
_stableBridgingFee,
txState.stoken
);
}
/// ** ONLYOWNER functions **
/**
* @notice Set paused flag to true
*/
function pause() external onlyOwner {
paused = true;
emit Paused(_msgSender());
}
/**
* @notice Set paused flag to false
*/
function unpause() external onlyOwner {
paused = false;
emit Unpaused(_msgSender());
}
/**
* @notice Sets minimal price for token
* @param _token Address of token to set threshold
* @param _threshold threshold to set
*/
function setTokenThreshold(address _token, uint256 _threshold) external onlyOwner {
tokenThreshold[_token] = _threshold;
emit SetTokenThreshold(_token, _threshold);
}
/**
* @notice Sets MetaRouter address
* @param _metaRouter Address of metaRouter
*/
function setMetaRouter(IMetaRouter _metaRouter) external onlyOwner {
require(address(_metaRouter) != address(0), "Symb: metaRouter cannot be zero address");
metaRouter = _metaRouter;
emit SetMetaRouter(address(_metaRouter));
}
/**
* @notice Sets Fabric address
* @param _fabric Address of fabric
*/
function setFabric(address _fabric) external onlyOwner {
require(fabric == address(0x0), "Symb: Fabric already set");
fabric = _fabric;
emit SetFabric(_fabric);
}
}
contracts/synth-core/interfaces/IBridge.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
interface IBridge {
function transmitRequestV2(
bytes memory _callData,
address _receiveSide,
address _oppositeBridge,
uint256 _chainId
) external;
function receiveRequestV2(
bytes memory _callData,
address _receiveSide
) external;
}
contracts/synth-core/interfaces/ISyntFabric.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
interface ISyntFabric {
function getRealRepresentation(address _syntTokenAdr)
external
view
returns (address);
function getSyntRepresentation(address _realTokenAdr, uint256 _chainID)
external
view
returns (address);
function synthesize(
address _to,
uint256 _amount,
address _stoken
) external;
function unsynthesize(
address _to,
uint256 _amount,
address _stoken
) external;
}
contracts/synth-core/metarouter/MetaRouteStructs.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
library MetaRouteStructs {
struct MetaBurnTransaction {
uint256 stableBridgingFee;
uint256 amount;
bytes32 crossChainID;
address syntCaller;
address finalReceiveSide;
address sToken;
bytes finalCallData;
uint256 finalOffset;
address chain2address;
address receiveSide;
address oppositeBridge;
address revertableAddress;
uint256 chainID;
bytes32 clientID;
}
struct MetaMintTransaction {
uint256 stableBridgingFee;
uint256 amount;
bytes32 crossChainID;
bytes32 externalID;
address tokenReal;
uint256 chainID;
address to;
address[] swapTokens;
address secondDexRouter;
bytes secondSwapCalldata;
address finalReceiveSide;
bytes finalCalldata;
uint256 finalOffset;
}
struct MetaRouteTransaction {
bytes firstSwapCalldata;
bytes secondSwapCalldata;
address[] approvedTokens;
address firstDexRouter;
address secondDexRouter;
uint256 amount;
bool nativeIn;
address relayRecipient;
bytes otherSideCalldata;
}
struct MetaSynthesizeTransaction {
uint256 stableBridgingFee;
uint256 amount;
address rtoken;
address chain2address;
address receiveSide;
address oppositeBridge;
address syntCaller;
uint256 chainID;
address[] swapTokens;
address secondDexRouter;
bytes secondSwapCalldata;
address finalReceiveSide;
bytes finalCalldata;
uint256 finalOffset;
address revertableAddress;
bytes32 clientID;
}
struct MetaRevertTransaction {
uint256 stableBridgingFee;
bytes32 internalID;
address receiveSide;
address managerChainBridge;
address sourceChainBridge;
uint256 managerChainId;
uint256 sourceChainId;
address router;
bytes swapCalldata;
address sourceChainSynthesis;
address burnToken;
bytes burnCalldata;
bytes32 clientID;
}
}
@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Context_init_unchained();
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
uint256[49] private __gap;
}
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)
pragma solidity ^0.8.0;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the
* initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() initializer {}
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
// If the contract is initializing we ignore whether _initialized is set in order to support multiple
// inheritance patterns, but we only do this in the context of a constructor, because in other contexts the
// contract may have been reentered.
require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} modifier, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
function _isConstructor() private view returns (bool) {
return !AddressUpgradeable.isContract(address(this));
}
}
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
__Context_init_unchained();
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
uint256[50] private __gap;
}
@uniswap/lib/contracts/libraries/TransferHelper.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.6.0;
// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
function safeApprove(
address token,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('approve(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper::safeApprove: approve failed'
);
}
function safeTransfer(
address token,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper::safeTransfer: transfer failed'
);
}
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper::transferFrom: transferFrom failed'
);
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, 'TransferHelper::safeTransferETH: ETH transfer failed');
}
}
contracts/synth-core/metarouter/interfaces/IMetaRouter.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "../MetaRouteStructs.sol";
interface IMetaRouter {
function metaRoute(
MetaRouteStructs.MetaRouteTransaction calldata _metarouteTransaction
) external payable;
function externalCall(
address _token,
uint256 _amount,
address _receiveSide,
bytes calldata _calldata,
uint256 _offset,
address _revertableAddress
) external;
function returnSwap(
address _token,
uint256 _amount,
address _router,
bytes calldata _swapCalldata,
address _burnToken,
address _synthesis,
bytes calldata _burnCalldata
) external;
function metaMintSwap(
MetaRouteStructs.MetaMintTransaction calldata _metaMintTransaction
) external;
}
contracts/utils/RelayRecipientUpgradeable.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
abstract contract RelayRecipientUpgradeable is OwnableUpgradeable {
address private _trustedForwarder;
function __RelayRecipient_init(address trustedForwarder)
internal
onlyInitializing
{
__Ownable_init();
_trustedForwarder = trustedForwarder;
}
function isTrustedForwarder(address forwarder)
public
view
virtual
returns (bool)
{
return forwarder == _trustedForwarder;
}
function _msgSender()
internal
view
virtual
override
returns (address sender)
{
if (isTrustedForwarder(msg.sender)) {
// The assembly code is more direct than the Solidity version using `abi.decode`.
assembly {
sender := shr(96, calldataload(sub(calldatasize(), 20)))
}
} else {
return super._msgSender();
}
}
function _msgData()
internal
view
virtual
override
returns (bytes calldata)
{
if (isTrustedForwarder(msg.sender)) {
return msg.data[:msg.data.length - 20];
} else {
return super._msgData();
}
}
}
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":2000,"enabled":true},"libraries":{}}
Contract ABI
[{"type":"event","name":"BurnRequest","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":false},{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"uint256","name":"chainID","internalType":"uint256","indexed":true},{"type":"address","name":"revertableAddress","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"address","name":"token","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"ClientIdLog","inputs":[{"type":"bytes32","name":"requestId","internalType":"bytes32","indexed":false},{"type":"bytes32","name":"clientId","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"RevertBurnCompleted","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"bridgingFee","internalType":"uint256","indexed":false},{"type":"address","name":"token","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"RevertSynthesizeRequest","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"SetFabric","inputs":[{"type":"address","name":"fabric","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"SetMetaRouter","inputs":[{"type":"address","name":"metaRouter","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"SetTokenThreshold","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"threshold","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SynthesizeCompleted","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"bytes32","name":"crossChainID","internalType":"bytes32","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"bridgingFee","internalType":"uint256","indexed":false},{"type":"address","name":"token","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"bridge","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"internalID","internalType":"bytes32"}],"name":"burnSyntheticToken","inputs":[{"type":"uint256","name":"_stableBridgingFee","internalType":"uint256"},{"type":"address","name":"_stoken","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_chain2address","internalType":"address"},{"type":"address","name":"_receiveSide","internalType":"address"},{"type":"address","name":"_oppositeBridge","internalType":"address"},{"type":"address","name":"_revertableAddress","internalType":"address"},{"type":"uint256","name":"_chainID","internalType":"uint256"},{"type":"bytes32","name":"_clientID","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"fabric","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_bridge","internalType":"address"},{"type":"address","name":"_trustedForwarder","internalType":"address"},{"type":"address","name":"_metaRouter","internalType":"contract IMetaRouter"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isTrustedForwarder","inputs":[{"type":"address","name":"forwarder","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"internalID","internalType":"bytes32"}],"name":"metaBurnSyntheticToken","inputs":[{"type":"tuple","name":"_metaBurnTransaction","internalType":"struct MetaRouteStructs.MetaBurnTransaction","components":[{"type":"uint256","name":"stableBridgingFee","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bytes32","name":"crossChainID","internalType":"bytes32"},{"type":"address","name":"syntCaller","internalType":"address"},{"type":"address","name":"finalReceiveSide","internalType":"address"},{"type":"address","name":"sToken","internalType":"address"},{"type":"bytes","name":"finalCallData","internalType":"bytes"},{"type":"uint256","name":"finalOffset","internalType":"uint256"},{"type":"address","name":"chain2address","internalType":"address"},{"type":"address","name":"receiveSide","internalType":"address"},{"type":"address","name":"oppositeBridge","internalType":"address"},{"type":"address","name":"revertableAddress","internalType":"address"},{"type":"uint256","name":"chainID","internalType":"uint256"},{"type":"bytes32","name":"clientID","internalType":"bytes32"}]}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"metaMintSyntheticToken","inputs":[{"type":"tuple","name":"_metaMintTransaction","internalType":"struct MetaRouteStructs.MetaMintTransaction","components":[{"type":"uint256","name":"stableBridgingFee","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bytes32","name":"crossChainID","internalType":"bytes32"},{"type":"bytes32","name":"externalID","internalType":"bytes32"},{"type":"address","name":"tokenReal","internalType":"address"},{"type":"uint256","name":"chainID","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"address[]","name":"swapTokens","internalType":"address[]"},{"type":"address","name":"secondDexRouter","internalType":"address"},{"type":"bytes","name":"secondSwapCalldata","internalType":"bytes"},{"type":"address","name":"finalReceiveSide","internalType":"address"},{"type":"bytes","name":"finalCalldata","internalType":"bytes"},{"type":"uint256","name":"finalOffset","internalType":"uint256"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IMetaRouter"}],"name":"metaRouter","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintSyntheticToken","inputs":[{"type":"uint256","name":"_stableBridgingFee","internalType":"uint256"},{"type":"bytes32","name":"_externalID","internalType":"bytes32"},{"type":"bytes32","name":"_crossChainID","internalType":"bytes32"},{"type":"address","name":"_tokenReal","internalType":"address"},{"type":"uint256","name":"_chainID","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_to","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"requestCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"recipient","internalType":"address"},{"type":"address","name":"chain2address","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"address","name":"token","internalType":"address"},{"type":"address","name":"stoken","internalType":"address"},{"type":"uint8","name":"state","internalType":"enum Synthesis.RequestState"}],"name":"requests","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revertBurn","inputs":[{"type":"uint256","name":"_stableBridgingFee","internalType":"uint256"},{"type":"bytes32","name":"_externalID","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revertBurnAndBurn","inputs":[{"type":"uint256","name":"_stableBridgingFee","internalType":"uint256"},{"type":"bytes32","name":"_externalID","internalType":"bytes32"},{"type":"address","name":"_receiveSide","internalType":"address"},{"type":"address","name":"_oppositeBridge","internalType":"address"},{"type":"uint256","name":"_chainID","internalType":"uint256"},{"type":"address","name":"_revertableAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revertMetaBurn","inputs":[{"type":"uint256","name":"_stableBridgingFee","internalType":"uint256"},{"type":"bytes32","name":"_externalID","internalType":"bytes32"},{"type":"address","name":"_router","internalType":"address"},{"type":"bytes","name":"_swapCalldata","internalType":"bytes"},{"type":"address","name":"_synthesis","internalType":"address"},{"type":"address","name":"_burnToken","internalType":"address"},{"type":"bytes","name":"_burnCalldata","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revertSynthesizeRequest","inputs":[{"type":"uint256","name":"_stableBridgingFee","internalType":"uint256"},{"type":"bytes32","name":"_internalID","internalType":"bytes32"},{"type":"address","name":"_receiveSide","internalType":"address"},{"type":"address","name":"_oppositeBridge","internalType":"address"},{"type":"uint256","name":"_chainID","internalType":"uint256"},{"type":"bytes32","name":"_clientID","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revertSynthesizeRequestByBridge","inputs":[{"type":"uint256","name":"_stableBridgingFee","internalType":"uint256"},{"type":"bytes32","name":"_internalID","internalType":"bytes32"},{"type":"address","name":"_receiveSide","internalType":"address"},{"type":"address","name":"_oppositeBridge","internalType":"address"},{"type":"uint256","name":"_chainID","internalType":"uint256"},{"type":"address","name":"_sender","internalType":"address"},{"type":"bytes32","name":"_clientID","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFabric","inputs":[{"type":"address","name":"_fabric","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMetaRouter","inputs":[{"type":"address","name":"_metaRouter","internalType":"contract IMetaRouter"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTokenThreshold","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_threshold","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"enum Synthesis.SynthesizeState"}],"name":"synthesizeStates","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"tokenThreshold","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"versionRecipient","inputs":[]}]
Contract Creation Code
0x608060405234801561001057600080fd5b5061464f806100206000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80639d866985116100f9578063dbec15bb11610097578063e78cea9211610071578063e78cea921461045b578063eadd5c3414610473578063f2fde38b14610486578063f70519ae1461049957600080fd5b8063dbec15bb14610422578063dd8c903914610435578063e66bb5501461044857600080fd5b8063c29a91bc116100d3578063c29a91bc146103b9578063c4a588f8146103cc578063cbef5f2c146103df578063d23fd796146103f257600080fd5b80639d86698514610329578063a83e754b14610393578063c0c53b8b146103a657600080fd5b80635d176f2f116101665780637819d8af116101405780637819d8af146102ea5780638456cb59146102fd5780638bb39802146103055780638da5cb5b1461031857600080fd5b80635d176f2f1461029757806368775278146102c2578063715018a6146102e257600080fd5b8063572b6c05116101a2578063572b6c051461022e57806359514893146102605780635badbe4c146102735780635c975abb1461028a57600080fd5b80630f5b2f68146101c95780633f4ba83a146101de578063486ff0cd146101e6575b600080fd5b6101dc6101d7366004613e72565b6104ac565b005b6101dc6107b2565b604080518082018252600581527f322e302e31000000000000000000000000000000000000000000000000000000602082015290516102259190614219565b60405180910390f35b61025061023c3660046139ea565b6065546001600160a01b0391821691161490565b6040519015158152602001610225565b6101dc61026e366004613e0b565b61087b565b61027c60665481565b604051908152602001610225565b6067546102509060ff1681565b6068546102aa906001600160a01b031681565b6040516001600160a01b039091168152602001610225565b61027c6102d03660046139ea565b606b6020526000908152604090205481565b6101dc610ee0565b6101dc6102f8366004613f40565b610f65565b6101dc611366565b6101dc610313366004613a76565b611415565b6033546001600160a01b03166102aa565b610381610337366004613ac4565b606a60205260009081526040902080546001820154600283015460038401546004909401546001600160a01b0393841694928416939192821691811690600160a01b900460ff1686565b60405161022596959493929190614121565b6101dc6103a1366004614001565b6114e6565b6101dc6103b4366004613a2b565b6118db565b6101dc6103c7366004613c10565b611a4c565b6101dc6103da366004613ee4565b611f6c565b61027c6103ed366004613d51565b61221a565b610415610400366004613ac4565b60696020526000908152604090205460ff1681565b6040516102259190614206565b606c546102aa906001600160a01b031681565b6101dc6104433660046139ea565b6127aa565b61027c610456366004613add565b6128de565b6067546102aa9061010090046001600160a01b031681565b6101dc6104813660046139ea565b612f34565b6101dc6104943660046139ea565b613084565b6101dc6104a7366004613de9565b613182565b60675460ff16156104f35760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064015b60405180910390fd5b60675461010090046001600160a01b031633146105525760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60408051602081018890526bffffffffffffffffffffffff1930606090811b8216938301939093529184901b909116605482015246606882015260009060880160408051601f1981840301815291905280516020909101209050600160008281526069602052604090205460ff1660028111156105d1576105d16144ba565b14156106455760405162461bcd60e51b815260206004820152602560248201527f53796d623a2073796e74686574696320746f6b656e7320616c7265616479206d60448201527f696e74656400000000000000000000000000000000000000000000000000000060648201526084016104ea565b6000818152606960209081526040808320805460ff19166002179055805160608101909152602180825290916145f9908301398051602090910120604051602481018b90526044810184905260640160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092526067549151633675e4e160e11b81529092506001600160a01b036101009092049190911690636cebc9c2906107059084908b908b908b906004016141d0565b600060405180830381600087803b15801561071f57600080fd5b505af1158015610733573d6000803e3d6000fd5b5050505050817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f58860405161076a91815260200190565b60405180910390a26040516001600160a01b0384169088907f9bc8099e19706f253ae634ef1a5fb6ef84b4748c2183472905b9b2511cfa861790600090a35050505050505050565b6107ba613490565b6001600160a01b03166107d56033546001600160a01b031690565b6001600160a01b03161461082b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6067805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61085e613490565b6040516001600160a01b03909116815260200160405180910390a1565b60675461010090046001600160a01b031633146108da5760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60675460ff161561091c5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b6000858152606a6020526040902060016004820154600160a01b900460ff16600281111561094c5761094c6144ba565b146109bf5760405162461bcd60e51b815260206004820152602960248201527f53796d623a207374617465206e6f74206f70656e206f7220747820646f65732060448201527f6e6f74206578697374000000000000000000000000000000000000000000000060648201526084016104ea565b60048181018054740200000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff8216179091556068546067546040516339240a7f60e21b81526001600160a01b03610100909204821694810194909452602484018b90529182166044840152169063e49029fc90606401600060405180830381600087803b158015610a6157600080fd5b505af1158015610a75573d6000803e3d6000fd5b505050506000878260020154610a8b9190614428565b8254600484015460408051848152602081018d90526001600160a01b0392831681830152905193945091169189917fb6f5f7b98cc78a8031c967af163a8c197f470a35df1e326a9038859679e6a184919081900360600190a36001600160a01b038316610b035760018201546001600160a01b031692505b60685460048381015460405163161acb4760e01b81526001600160a01b0391821692810192909252600092169063161acb479060240160206040518083038186803b158015610b5157600080fd5b505afa158015610b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b899190613a0e565b6066546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015290915060009060740160408051601f1981840301815282825280516020918201209083018190526bffffffffffffffffffffffff1960608c811b8216938501939093529188901b9091166054830152606882018890529150600090608801604051602081830303815290604052805190602001209050600060405180606001604052806035815260200161456d6035913980516020909101206001870154604051602481018f9052604481018590526001600160a01b0380881660648301526084820189905290911660a482015260c40160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252815160c08101909252915080610ccc613490565b6001600160a01b0390811682526001808a01548216602084015260408301899052878216606084015260048a0154909116608083015260a0909101526000838152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180548516918616919091179055608085015160048301805494851691909516908117855560a0860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b908490811115610dd857610dd86144ba565b0217905550506066805491506000610def8361446b565b9091555050606754604051633675e4e160e11b81526101009091046001600160a01b031690636cebc9c290610e2e9084908e908e908e906004016141d0565b600060405180830381600087803b158015610e4857600080fd5b505af1158015610e5c573d6000803e3d6000fd5b50505050866001600160a01b031688610e73613490565b600189015460048a0154604080518981526001600160a01b0393841660208201529081018b905290821660608201529116907f5f00e8f0d61ff1190912879949026c85a81f3f96038c7f4cd868bdfe882e0eeb9060800160405180910390a4505050505050505050505050565b610ee8613490565b6001600160a01b0316610f036033546001600160a01b031690565b6001600160a01b031614610f595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b610f6360006134d6565b565b60675461010090046001600160a01b03163314610fc45760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60675460ff16156110065760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b6000888152606a6020526040902060016004820154600160a01b900460ff166002811115611036576110366144ba565b146110a95760405162461bcd60e51b815260206004820152602960248201527f53796d623a207374617465206e6f74206f70656e206f7220747820646f65732060448201527f6e6f74206578697374000000000000000000000000000000000000000000000060648201526084016104ea565b6004810180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674020000000000000000000000000000000000000000179055606854815460028301546001600160a01b039283169263e49029fc921690611113908e90614428565b60048581015460405160e086901b6001600160e01b03191681526001600160a01b0394851692810192909252602482019290925291166044820152606401600060405180830381600087803b15801561116b57600080fd5b505af115801561117f573d6000803e3d6000fd5b50505050606860009054906101000a90046001600160a01b03166001600160a01b031663e49029fc606760019054906101000a90046001600160a01b03168c8460040160009054906101000a90046001600160a01b03166040518463ffffffff1660e01b8152600401611212939291906001600160a01b0393841681526020810192909252909116604082015260600190565b600060405180830381600087803b15801561122c57600080fd5b505af1158015611240573d6000803e3d6000fd5b5050606c54600484015460028501546001600160a01b03928316945063732cffe99350911690611271908e90614428565b8b8b8b8a8c8b8b6040518a63ffffffff1660e01b815260040161129c9998979695949392919061416a565b600060405180830381600087803b1580156112b657600080fd5b505af11580156112ca573d6000803e3d6000fd5b5050825460028401546001600160a01b0390911692508b91507fb6f5f7b98cc78a8031c967af163a8c197f470a35df1e326a9038859679e6a18490611310908e90614428565b8d8560040160009054906101000a90046001600160a01b03166040516113529392919092835260208301919091526001600160a01b0316604082015260600190565b60405180910390a350505050505050505050565b61136e613490565b6001600160a01b03166113896033546001600160a01b031690565b6001600160a01b0316146113df5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6067805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861085e613490565b61141d613490565b6001600160a01b03166114386033546001600160a01b031690565b6001600160a01b03161461148e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6001600160a01b0382166000818152606b6020908152604091829020849055815192835282018390527fa6742efd4f410d6fd9688a6cf6a15b6d51121097a263056a3576baaacdc4a9ae910160405180910390a15050565b60675461010090046001600160a01b031633146115455760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60675460ff16156115875760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b60008681526069602052604081205460ff1660028111156115aa576115aa6144ba565b146116435760405162461bcd60e51b815260206004820152604d60248201527f53796d623a2072657665727453796e74686573697a656452657175657374206360448201527f616c6c6564206f7220746f6b656e732068617665206265656e20616c7265616460648201527f792073796e74686573697a656400000000000000000000000000000000000000608482015260a4016104ea565b600086815260696020526040808220805460ff1916600117905560685490517f506890a00000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790529091169063506890a09060440160206040518083038186803b1580156116c157600080fd5b505afa1580156116d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f99190613a0e565b90506001600160a01b0381166117775760405162461bcd60e51b815260206004820152603460248201527f53796d623a205468657265206973206e6f2073796e7420726570726573656e7460448201527f6174696f6e20666f72207468697320746f6b656e00000000000000000000000060648201526084016104ea565b6068546001600160a01b031663e49029fc836117938b87614428565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015260248101919091529084166044820152606401600060405180830381600087803b1580156117e457600080fd5b505af11580156117f8573d6000803e3d6000fd5b50506068546067546040516339240a7f60e21b81526001600160a01b0361010090920482166004820152602481018d905285821660448201529116925063e49029fc9150606401600060405180830381600087803b15801561185957600080fd5b505af115801561186d573d6000803e3d6000fd5b5050505085826001600160a01b0316887f1f3f0f3c7b2df480755c6486a132f215e7b2b89fcca0beecd95a9696c71789b68b876118aa9190614428565b60408051918252602082018e90526001600160a01b038b169082015260600160405180910390a45050505050505050565b600054610100900460ff166118f65760005460ff16156118fa565b303b155b61196c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104ea565b600054610100900460ff161580156119ab57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6119b483613535565b606780547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b038781169190910291909117909155606c805473ffffffffffffffffffffffffffffffffffffffff19169184169190911790558015611a4657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b60675461010090046001600160a01b03163314611aab5760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60675460ff1615611aed5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b606081015160009081526069602052604081205460ff166002811115611b1557611b156144ba565b14611bae5760405162461bcd60e51b815260206004820152604d60248201527f53796d623a2072657665727453796e74686573697a656452657175657374206360448201527f616c6c6564206f7220746f6b656e732068617665206265656e20616c7265616460648201527f792073796e74686573697a656400000000000000000000000000000000000000608482015260a4016104ea565b6060810151600090815260696020526040808220805460ff19166001179055606854608084015160a085015192517f506890a00000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810193909352169063506890a09060440160206040518083038186803b158015611c3a57600080fd5b505afa158015611c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c729190613a0e565b90506001600160a01b038116611cf05760405162461bcd60e51b815260206004820152603460248201527f53796d623a205468657265206973206e6f2073796e7420726570726573656e7460448201527f6174696f6e20666f72207468697320746f6b656e00000000000000000000000060648201526084016104ea565b606854825160208401516001600160a01b039092169163e49029fc913091611d189190614428565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015260248101919091529084166044820152606401600060405180830381600087803b158015611d6957600080fd5b505af1158015611d7d573d6000803e3d6000fd5b505060685460675485516040516339240a7f60e21b81526001600160a01b0361010090930483166004820152602481019190915285821660448201529116925063e49029fc9150606401600060405180830381600087803b158015611de157600080fd5b505af1158015611df5573d6000803e3d6000fd5b505083516020850151611e0b9350909150614428565b602083015260e082015151611e3157611e2d818360c0015184602001516135d7565b5050565b611e738260e00151600081518110611e4b57611e4b6144d0565b6020026020010151606c60009054906101000a90046001600160a01b031684602001516135d7565b606c546040517f3bc788350000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690633bc7883590611ebc90859060040161422c565b600060405180830381600087803b158015611ed657600080fd5b505af1158015611eea573d6000803e3d6000fd5b5050505081604001518260c001516001600160a01b031683606001517f1f3f0f3c7b2df480755c6486a132f215e7b2b89fcca0beecd95a9696c71789b6856020015186600001518760800151604051611f5f9392919092835260208301919091526001600160a01b0316604082015260600190565b60405180910390a4505b50565b60675460ff1615611fae5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b60008530611fba613490565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f1981840301815291905280516020909101209050600160008281526069602052604090205460ff166002811115612032576120326144ba565b14156120a65760405162461bcd60e51b815260206004820152602560248201527f53796d623a2073796e74686574696320746f6b656e7320616c7265616479206d60448201527f696e74656400000000000000000000000000000000000000000000000000000060648201526084016104ea565b6000818152606960209081526040808320805460ff19166002179055805160608101909152602180825290916145f9908301398051602090910120604051602481018a90526044810184905260640160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092526067549151633675e4e160e11b81529092506001600160a01b036101009092049190911690636cebc9c2906121669084908a908a908a906004016141d0565b600060405180830381600087803b15801561218057600080fd5b505af1158015612194573d6000803e3d6000fd5b50505050506121a1613490565b6001600160a01b0316867f9bc8099e19706f253ae634ef1a5fb6ef84b4748c2183472905b9b2511cfa861760405160405180910390a3817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f58760405161220991815260200190565b60405180910390a250505050505050565b60675460009060ff161561225f5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b6001600160a01b0389166000908152606b60205260409020548810156122c75760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c640000000060448201526064016104ea565b6068546001600160a01b031663a8160b766122e0613490565b6040516001600160e01b031960e084901b1681526001600160a01b039182166004820152602481018c9052908c166044820152606401600060405180830381600087803b15801561233057600080fd5b505af1158015612344573d6000803e3d6000fd5b505050506001600160a01b03841661235a578693505b60685460405163161acb4760e01b81526001600160a01b038b81166004830152600092169063161acb479060240160206040518083038186803b1580156123a057600080fd5b505afa1580156123b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d89190613a0e565b90506001600160a01b0381166124305760405162461bcd60e51b815260206004820152601460248201527f53796d623a20696e636f72726563742073796e7400000000000000000000000060448201526064016104ea565b6066546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015260740160408051601f1981840301815282825280516020918201209083018190526bffffffffffffffffffffffff1960608b811b8216938501939093529188901b909116605483015260688201869052925060009060880160405160208183030381529060405280519060200120905060006040518060600160405280603d8152602001614530603d91398051602090910120604051602481018f905260448101849052606481018690526001600160a01b03808616608483015260a482018e90528c1660c482015260e40160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252815160c0810190925291508061256e613490565b6001600160a01b0390811682528c81166020830152604082018e905285811660608301528e16608082015260a001600190526000838152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180548516918616919091179055608085015160048301805494851691909516908117855560a0860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b908490811115612670576126706144ba565b02179055505060668054915060006126878361446b565b9091555050606754604051633675e4e160e11b81526101009091046001600160a01b031690636cebc9c2906126c69084908d908d908c906004016141d0565b600060405180830381600087803b1580156126e057600080fd5b505af11580156126f4573d6000803e3d6000fd5b50505050505050836001600160a01b03168361270e613490565b604080518581526001600160a01b038c811660208301529181018d90528d821660608201529116907f5f00e8f0d61ff1190912879949026c85a81f3f96038c7f4cd868bdfe882e0eeb9060800160405180910390a4817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f58260405161279591815260200190565b60405180910390a29998505050505050505050565b6127b2613490565b6001600160a01b03166127cd6033546001600160a01b031690565b6001600160a01b0316146128235760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6068546001600160a01b03161561287c5760405162461bcd60e51b815260206004820152601860248201527f53796d623a2046616272696320616c726561647920736574000000000000000060448201526064016104ea565b6068805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fe7258eee4870ba270f25f5a42dd11bfe5a77658959c916807b94b8e9063c3cd0906020015b60405180910390a150565b60675460009060ff16156129235760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b60a08201516001600160a01b03166000908152606b60209081526040909120549083015110156129955760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c640000000060448201526064016104ea565b6068546001600160a01b031663a8160b766129ae613490565b602085015160a08601516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201526024810192909252919091166044820152606401600060405180830381600087803b158015612a0a57600080fd5b505af1158015612a1e573d6000803e3d6000fd5b505050506101608201516001600160a01b0316612a4b576101008201516001600160a01b03166101608301525b60685460a083015160405163161acb4760e01b81526001600160a01b039182166004820152600092919091169063161acb479060240160206040518083038186803b158015612a9957600080fd5b505afa158015612aad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad19190613a0e565b90506001600160a01b038116612b295760405162461bcd60e51b815260206004820152601460248201527f53796d623a20696e636f72726563742073796e7400000000000000000000000060448201526064016104ea565b6066546040516bffffffffffffffffffffffff193060601b1660208201526034810191909152466054820152607401604051602081830303815290604052805190602001209150826040015160001415612b8557604083018290525b600082846101200151856101600151866101800151604051602001612bdb9493929190938452606092831b6bffffffffffffffffffffffff1990811660208601529190921b166034830152604882015260680190565b60405160208183030381529060405280519060200120905060006040518060800160405280605781526020016145a2605791398051906020012085600001518660400151848861010001518960200151888b608001518c60c001518d60e00151604051602401612c5399989796959493929190614344565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505090506040518060c0016040528086606001516001600160a01b031681526020018661010001516001600160a01b0316815260200186602001518152602001846001600160a01b031681526020018660a001516001600160a01b0316815260200160016002811115612cf957612cf96144ba565b90526000838152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180548516918616919091179055608085015160048301805494851691909516908117855560a0860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b908490811115612dcb57612dcb6144ba565b0217905550506066805491506000612de28361446b565b9091555050606754610120860151610140870151610180880151604051633675e4e160e11b81526101009094046001600160a01b031693636cebc9c293612e3293879391929091906004016141d0565b600060405180830381600087803b158015612e4c57600080fd5b505af1158015612e60573d6000803e3d6000fd5b505050505050508161016001516001600160a01b031682610180015183606001516001600160a01b03167f5f00e8f0d61ff1190912879949026c85a81f3f96038c7f4cd868bdfe882e0eeb8486610100015187602001518860a00151604051612eee94939291909384526001600160a01b039283166020850152604084019190915216606082015260800190565b60405180910390a46101a08201516040518281527f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f59060200160405180910390a2919050565b612f3c613490565b6001600160a01b0316612f576033546001600160a01b031690565b6001600160a01b031614612fad5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6001600160a01b0381166130295760405162461bcd60e51b815260206004820152602760248201527f53796d623a206d657461526f757465722063616e6e6f74206265207a65726f2060448201527f616464726573730000000000000000000000000000000000000000000000000060648201526084016104ea565b606c805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fd5c54ab1d37bfef4dd2253d9d73c292e46f5bd8a67ca5920aab4c2e1993178e7906020016128d3565b61308c613490565b6001600160a01b03166130a76033546001600160a01b031690565b6001600160a01b0316146130fd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6001600160a01b0381166131795760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ea565b611f69816134d6565b60675461010090046001600160a01b031633146131e15760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60675460ff16156132235760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b6000818152606a6020526040902060016004820154600160a01b900460ff166002811115613253576132536144ba565b146132c65760405162461bcd60e51b815260206004820152602960248201527f53796d623a207374617465206e6f74206f70656e206f7220747820646f65732060448201527f6e6f74206578697374000000000000000000000000000000000000000000000060648201526084016104ea565b6004810180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674020000000000000000000000000000000000000000179055606854815460028301546001600160a01b039283169263e49029fc921690613330908790614428565b60048581015460405160e086901b6001600160e01b03191681526001600160a01b0394851692810192909252602482019290925291166044820152606401600060405180830381600087803b15801561338857600080fd5b505af115801561339c573d6000803e3d6000fd5b50506068546067546004858101546040516339240a7f60e21b81526001600160a01b0361010090940484169281019290925260248201899052821660448201529116925063e49029fc9150606401600060405180830381600087803b15801561340457600080fd5b505af1158015613418573d6000803e3d6000fd5b5050825460028401546001600160a01b0390911692508491507fb6f5f7b98cc78a8031c967af163a8c197f470a35df1e326a9038859679e6a1849061345e908790614428565b600485015460408051928352602083018990526001600160a01b039091169082015260600160405180910390a3505050565b6065546000906001600160a01b03163314156134d157507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b603380546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166135a05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ea565b6135a8613731565b6065805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b03167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161364c9190614105565b6000604051808303816000865af19150503d8060008114613689576040519150601f19603f3d011682016040523d82523d6000602084013e61368e565b606091505b50915091508180156136b85750805115806136b85750808060200190518101906136b89190613aa2565b61372a5760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c65640000000000000000000000000000000000000060648201526084016104ea565b5050505050565b600054610100900460ff1661379c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ea565b6137a46137ac565b610f63613817565b600054610100900460ff16610f635760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ea565b600054610100900460ff166138825760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ea565b610f6361388d613490565b6134d6565b803561389d8161451a565b919050565b600082601f8301126138b357600080fd5b8135602067ffffffffffffffff8211156138cf576138cf6144e6565b8160051b6138de8282016143f7565b8381528281019086840183880185018910156138f957600080fd5b600093505b858410156139255780356139118161451a565b8352600193909301929184019184016138fe565b50979650505050505050565b60008083601f84011261394357600080fd5b50813567ffffffffffffffff81111561395b57600080fd5b60208301915083602082850101111561397357600080fd5b9250929050565b600082601f83011261398b57600080fd5b813567ffffffffffffffff8111156139a5576139a56144e6565b6139b86020601f19601f840116016143f7565b8181528460208386010111156139cd57600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156139fc57600080fd5b8135613a078161451a565b9392505050565b600060208284031215613a2057600080fd5b8151613a078161451a565b600080600060608486031215613a4057600080fd5b8335613a4b8161451a565b92506020840135613a5b8161451a565b91506040840135613a6b8161451a565b809150509250925092565b60008060408385031215613a8957600080fd5b8235613a948161451a565b946020939093013593505050565b600060208284031215613ab457600080fd5b81518015158114613a0757600080fd5b600060208284031215613ad657600080fd5b5035919050565b600060208284031215613aef57600080fd5b813567ffffffffffffffff80821115613b0757600080fd5b908301906101c08286031215613b1c57600080fd5b613b246143a9565b823581526020830135602082015260408301356040820152613b4860608401613892565b6060820152613b5960808401613892565b6080820152613b6a60a08401613892565b60a082015260c083013582811115613b8157600080fd5b613b8d8782860161397a565b60c08301525060e083013560e08201526101009150613bad828401613892565b828201526101209150613bc1828401613892565b828201526101409150613bd5828401613892565b828201526101609150613be9828401613892565b9181019190915261018082810135908201526101a091820135918101919091529392505050565b600060208284031215613c2257600080fd5b813567ffffffffffffffff80821115613c3a57600080fd5b908301906101a08286031215613c4f57600080fd5b613c576143d3565b82358152602083013560208201526040830135604082015260608301356060820152613c8560808401613892565b608082015260a083013560a0820152613ca060c08401613892565b60c082015260e083013582811115613cb757600080fd5b613cc3878286016138a2565b60e083015250610100613cd7818501613892565b908201526101208381013583811115613cef57600080fd5b613cfb8882870161397a565b828401525050610140613d0f818501613892565b908201526101608381013583811115613d2757600080fd5b613d338882870161397a565b91830191909152506101809283013592810192909252509392505050565b60008060008060008060008060006101208a8c031215613d7057600080fd5b8935985060208a0135613d828161451a565b975060408a0135965060608a0135613d998161451a565b955060808a0135613da98161451a565b945060a08a0135613db98161451a565b935060c08a0135613dc98161451a565b8093505060e08a013591506101008a013590509295985092959850929598565b60008060408385031215613dfc57600080fd5b50508035926020909101359150565b60008060008060008060c08789031215613e2457600080fd5b86359550602087013594506040870135613e3d8161451a565b93506060870135613e4d8161451a565b92506080870135915060a0870135613e648161451a565b809150509295509295509295565b600080600080600080600060e0888a031215613e8d57600080fd5b87359650602088013595506040880135613ea68161451a565b94506060880135613eb68161451a565b93506080880135925060a0880135613ecd8161451a565b8092505060c0880135905092959891949750929550565b60008060008060008060c08789031215613efd57600080fd5b86359550602087013594506040870135613f168161451a565b93506060870135613f268161451a565b9598949750929560808101359460a0909101359350915050565b600080600080600080600080600060e08a8c031215613f5e57600080fd5b8935985060208a0135975060408a0135613f778161451a565b965060608a013567ffffffffffffffff80821115613f9457600080fd5b613fa08d838e01613931565b909850965060808c01359150613fb58261451a565b90945060a08b013590613fc78261451a565b90935060c08b01359080821115613fdd57600080fd5b50613fea8c828d01613931565b915080935050809150509295985092959850929598565b600080600080600080600060e0888a03121561401c57600080fd5b873596506020880135955060408801359450606088013561403c8161451a565b93506080880135925060a0880135915060c088013561405a8161451a565b8091505092959891949750929550565b600081518084526020808501945080840160005b838110156140a35781516001600160a01b03168752958201959082019060010161407e565b509495945050505050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b600081518084526140f181602086016020860161443f565b601f01601f19169290920160200192915050565b6000825161411781846020870161443f565b9190910192915050565b6001600160a01b03878116825286811660208301526040820186905284811660608301528316608082015260c08101614159836144fc565b8260a0830152979650505050505050565b60006001600160a01b03808c1683528a6020840152808a16604084015260e0606084015261419c60e08401898b6140ae565b818816608085015281871660a085015283810360c08501526141bf8186886140ae565b9d9c50505050505050505050505050565b6080815260006141e360808301876140d9565b6001600160a01b0395861660208401529390941660408201526060015292915050565b60208101614213836144fc565b91905290565b602081526000613a0760208301846140d9565b60208152815160208201526020820151604082015260408201516060820152606082015160808201526000608083015161427160a08401826001600160a01b03169052565b5060a083015160c083015260c083015161429660e08401826001600160a01b03169052565b5060e08301516101a061010081818601526142b56101c086018461406a565b908601519092506101206142d3868201836001600160a01b03169052565b80870151915050601f196101408187860301818801526142f385846140d9565b945080880151925050610160614313818801846001600160a01b03169052565b8088015192505061018081878603018188015261433085846140d9565b970151959092019490945250929392505050565b60006101208b83528a60208401528960408401526001600160a01b03808a16606085015288608085015280881660a085015280871660c0850152508060e0840152614391818401866140d9565b915050826101008301529a9950505050505050505050565b6040516101c0810167ffffffffffffffff811182821017156143cd576143cd6144e6565b60405290565b6040516101a0810167ffffffffffffffff811182821017156143cd576143cd6144e6565b604051601f8201601f1916810167ffffffffffffffff81118282101715614420576144206144e6565b604052919050565b60008282101561443a5761443a6144a4565b500390565b60005b8381101561445a578181015183820152602001614442565b83811115611a465750506000910152565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561449d5761449d6144a4565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60038110611f6957634e487b7160e01b600052602160045260246000fd5b6001600160a01b0381168114611f6957600080fdfe756e73796e74686573697a652875696e743235362c627974657333322c627974657333322c616464726573732c75696e743235362c6164647265737329756e73796e74686573697a652875696e743235362c627974657333322c616464726573732c75696e743235362c61646472657373296d657461556e73796e74686573697a652875696e743235362c627974657333322c627974657333322c616464726573732c75696e743235362c616464726573732c616464726573732c62797465732c75696e743235362972657665727453796e74686573697a652875696e743235362c6279746573333229a2646970667358221220db412997ea2bb14b76415a836f3f1de650a5b1d044076ff04074e2c81bd7500664736f6c63430008070033
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80639d866985116100f9578063dbec15bb11610097578063e78cea9211610071578063e78cea921461045b578063eadd5c3414610473578063f2fde38b14610486578063f70519ae1461049957600080fd5b8063dbec15bb14610422578063dd8c903914610435578063e66bb5501461044857600080fd5b8063c29a91bc116100d3578063c29a91bc146103b9578063c4a588f8146103cc578063cbef5f2c146103df578063d23fd796146103f257600080fd5b80639d86698514610329578063a83e754b14610393578063c0c53b8b146103a657600080fd5b80635d176f2f116101665780637819d8af116101405780637819d8af146102ea5780638456cb59146102fd5780638bb39802146103055780638da5cb5b1461031857600080fd5b80635d176f2f1461029757806368775278146102c2578063715018a6146102e257600080fd5b8063572b6c05116101a2578063572b6c051461022e57806359514893146102605780635badbe4c146102735780635c975abb1461028a57600080fd5b80630f5b2f68146101c95780633f4ba83a146101de578063486ff0cd146101e6575b600080fd5b6101dc6101d7366004613e72565b6104ac565b005b6101dc6107b2565b604080518082018252600581527f322e302e31000000000000000000000000000000000000000000000000000000602082015290516102259190614219565b60405180910390f35b61025061023c3660046139ea565b6065546001600160a01b0391821691161490565b6040519015158152602001610225565b6101dc61026e366004613e0b565b61087b565b61027c60665481565b604051908152602001610225565b6067546102509060ff1681565b6068546102aa906001600160a01b031681565b6040516001600160a01b039091168152602001610225565b61027c6102d03660046139ea565b606b6020526000908152604090205481565b6101dc610ee0565b6101dc6102f8366004613f40565b610f65565b6101dc611366565b6101dc610313366004613a76565b611415565b6033546001600160a01b03166102aa565b610381610337366004613ac4565b606a60205260009081526040902080546001820154600283015460038401546004909401546001600160a01b0393841694928416939192821691811690600160a01b900460ff1686565b60405161022596959493929190614121565b6101dc6103a1366004614001565b6114e6565b6101dc6103b4366004613a2b565b6118db565b6101dc6103c7366004613c10565b611a4c565b6101dc6103da366004613ee4565b611f6c565b61027c6103ed366004613d51565b61221a565b610415610400366004613ac4565b60696020526000908152604090205460ff1681565b6040516102259190614206565b606c546102aa906001600160a01b031681565b6101dc6104433660046139ea565b6127aa565b61027c610456366004613add565b6128de565b6067546102aa9061010090046001600160a01b031681565b6101dc6104813660046139ea565b612f34565b6101dc6104943660046139ea565b613084565b6101dc6104a7366004613de9565b613182565b60675460ff16156104f35760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064015b60405180910390fd5b60675461010090046001600160a01b031633146105525760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60408051602081018890526bffffffffffffffffffffffff1930606090811b8216938301939093529184901b909116605482015246606882015260009060880160408051601f1981840301815291905280516020909101209050600160008281526069602052604090205460ff1660028111156105d1576105d16144ba565b14156106455760405162461bcd60e51b815260206004820152602560248201527f53796d623a2073796e74686574696320746f6b656e7320616c7265616479206d60448201527f696e74656400000000000000000000000000000000000000000000000000000060648201526084016104ea565b6000818152606960209081526040808320805460ff19166002179055805160608101909152602180825290916145f9908301398051602090910120604051602481018b90526044810184905260640160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092526067549151633675e4e160e11b81529092506001600160a01b036101009092049190911690636cebc9c2906107059084908b908b908b906004016141d0565b600060405180830381600087803b15801561071f57600080fd5b505af1158015610733573d6000803e3d6000fd5b5050505050817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f58860405161076a91815260200190565b60405180910390a26040516001600160a01b0384169088907f9bc8099e19706f253ae634ef1a5fb6ef84b4748c2183472905b9b2511cfa861790600090a35050505050505050565b6107ba613490565b6001600160a01b03166107d56033546001600160a01b031690565b6001600160a01b03161461082b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6067805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61085e613490565b6040516001600160a01b03909116815260200160405180910390a1565b60675461010090046001600160a01b031633146108da5760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60675460ff161561091c5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b6000858152606a6020526040902060016004820154600160a01b900460ff16600281111561094c5761094c6144ba565b146109bf5760405162461bcd60e51b815260206004820152602960248201527f53796d623a207374617465206e6f74206f70656e206f7220747820646f65732060448201527f6e6f74206578697374000000000000000000000000000000000000000000000060648201526084016104ea565b60048181018054740200000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff8216179091556068546067546040516339240a7f60e21b81526001600160a01b03610100909204821694810194909452602484018b90529182166044840152169063e49029fc90606401600060405180830381600087803b158015610a6157600080fd5b505af1158015610a75573d6000803e3d6000fd5b505050506000878260020154610a8b9190614428565b8254600484015460408051848152602081018d90526001600160a01b0392831681830152905193945091169189917fb6f5f7b98cc78a8031c967af163a8c197f470a35df1e326a9038859679e6a184919081900360600190a36001600160a01b038316610b035760018201546001600160a01b031692505b60685460048381015460405163161acb4760e01b81526001600160a01b0391821692810192909252600092169063161acb479060240160206040518083038186803b158015610b5157600080fd5b505afa158015610b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b899190613a0e565b6066546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015290915060009060740160408051601f1981840301815282825280516020918201209083018190526bffffffffffffffffffffffff1960608c811b8216938501939093529188901b9091166054830152606882018890529150600090608801604051602081830303815290604052805190602001209050600060405180606001604052806035815260200161456d6035913980516020909101206001870154604051602481018f9052604481018590526001600160a01b0380881660648301526084820189905290911660a482015260c40160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252815160c08101909252915080610ccc613490565b6001600160a01b0390811682526001808a01548216602084015260408301899052878216606084015260048a0154909116608083015260a0909101526000838152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180548516918616919091179055608085015160048301805494851691909516908117855560a0860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b908490811115610dd857610dd86144ba565b0217905550506066805491506000610def8361446b565b9091555050606754604051633675e4e160e11b81526101009091046001600160a01b031690636cebc9c290610e2e9084908e908e908e906004016141d0565b600060405180830381600087803b158015610e4857600080fd5b505af1158015610e5c573d6000803e3d6000fd5b50505050866001600160a01b031688610e73613490565b600189015460048a0154604080518981526001600160a01b0393841660208201529081018b905290821660608201529116907f5f00e8f0d61ff1190912879949026c85a81f3f96038c7f4cd868bdfe882e0eeb9060800160405180910390a4505050505050505050505050565b610ee8613490565b6001600160a01b0316610f036033546001600160a01b031690565b6001600160a01b031614610f595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b610f6360006134d6565b565b60675461010090046001600160a01b03163314610fc45760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60675460ff16156110065760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b6000888152606a6020526040902060016004820154600160a01b900460ff166002811115611036576110366144ba565b146110a95760405162461bcd60e51b815260206004820152602960248201527f53796d623a207374617465206e6f74206f70656e206f7220747820646f65732060448201527f6e6f74206578697374000000000000000000000000000000000000000000000060648201526084016104ea565b6004810180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674020000000000000000000000000000000000000000179055606854815460028301546001600160a01b039283169263e49029fc921690611113908e90614428565b60048581015460405160e086901b6001600160e01b03191681526001600160a01b0394851692810192909252602482019290925291166044820152606401600060405180830381600087803b15801561116b57600080fd5b505af115801561117f573d6000803e3d6000fd5b50505050606860009054906101000a90046001600160a01b03166001600160a01b031663e49029fc606760019054906101000a90046001600160a01b03168c8460040160009054906101000a90046001600160a01b03166040518463ffffffff1660e01b8152600401611212939291906001600160a01b0393841681526020810192909252909116604082015260600190565b600060405180830381600087803b15801561122c57600080fd5b505af1158015611240573d6000803e3d6000fd5b5050606c54600484015460028501546001600160a01b03928316945063732cffe99350911690611271908e90614428565b8b8b8b8a8c8b8b6040518a63ffffffff1660e01b815260040161129c9998979695949392919061416a565b600060405180830381600087803b1580156112b657600080fd5b505af11580156112ca573d6000803e3d6000fd5b5050825460028401546001600160a01b0390911692508b91507fb6f5f7b98cc78a8031c967af163a8c197f470a35df1e326a9038859679e6a18490611310908e90614428565b8d8560040160009054906101000a90046001600160a01b03166040516113529392919092835260208301919091526001600160a01b0316604082015260600190565b60405180910390a350505050505050505050565b61136e613490565b6001600160a01b03166113896033546001600160a01b031690565b6001600160a01b0316146113df5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6067805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861085e613490565b61141d613490565b6001600160a01b03166114386033546001600160a01b031690565b6001600160a01b03161461148e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6001600160a01b0382166000818152606b6020908152604091829020849055815192835282018390527fa6742efd4f410d6fd9688a6cf6a15b6d51121097a263056a3576baaacdc4a9ae910160405180910390a15050565b60675461010090046001600160a01b031633146115455760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60675460ff16156115875760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b60008681526069602052604081205460ff1660028111156115aa576115aa6144ba565b146116435760405162461bcd60e51b815260206004820152604d60248201527f53796d623a2072657665727453796e74686573697a656452657175657374206360448201527f616c6c6564206f7220746f6b656e732068617665206265656e20616c7265616460648201527f792073796e74686573697a656400000000000000000000000000000000000000608482015260a4016104ea565b600086815260696020526040808220805460ff1916600117905560685490517f506890a00000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790529091169063506890a09060440160206040518083038186803b1580156116c157600080fd5b505afa1580156116d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f99190613a0e565b90506001600160a01b0381166117775760405162461bcd60e51b815260206004820152603460248201527f53796d623a205468657265206973206e6f2073796e7420726570726573656e7460448201527f6174696f6e20666f72207468697320746f6b656e00000000000000000000000060648201526084016104ea565b6068546001600160a01b031663e49029fc836117938b87614428565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015260248101919091529084166044820152606401600060405180830381600087803b1580156117e457600080fd5b505af11580156117f8573d6000803e3d6000fd5b50506068546067546040516339240a7f60e21b81526001600160a01b0361010090920482166004820152602481018d905285821660448201529116925063e49029fc9150606401600060405180830381600087803b15801561185957600080fd5b505af115801561186d573d6000803e3d6000fd5b5050505085826001600160a01b0316887f1f3f0f3c7b2df480755c6486a132f215e7b2b89fcca0beecd95a9696c71789b68b876118aa9190614428565b60408051918252602082018e90526001600160a01b038b169082015260600160405180910390a45050505050505050565b600054610100900460ff166118f65760005460ff16156118fa565b303b155b61196c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104ea565b600054610100900460ff161580156119ab57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6119b483613535565b606780547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b038781169190910291909117909155606c805473ffffffffffffffffffffffffffffffffffffffff19169184169190911790558015611a4657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b60675461010090046001600160a01b03163314611aab5760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60675460ff1615611aed5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b606081015160009081526069602052604081205460ff166002811115611b1557611b156144ba565b14611bae5760405162461bcd60e51b815260206004820152604d60248201527f53796d623a2072657665727453796e74686573697a656452657175657374206360448201527f616c6c6564206f7220746f6b656e732068617665206265656e20616c7265616460648201527f792073796e74686573697a656400000000000000000000000000000000000000608482015260a4016104ea565b6060810151600090815260696020526040808220805460ff19166001179055606854608084015160a085015192517f506890a00000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810193909352169063506890a09060440160206040518083038186803b158015611c3a57600080fd5b505afa158015611c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c729190613a0e565b90506001600160a01b038116611cf05760405162461bcd60e51b815260206004820152603460248201527f53796d623a205468657265206973206e6f2073796e7420726570726573656e7460448201527f6174696f6e20666f72207468697320746f6b656e00000000000000000000000060648201526084016104ea565b606854825160208401516001600160a01b039092169163e49029fc913091611d189190614428565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015260248101919091529084166044820152606401600060405180830381600087803b158015611d6957600080fd5b505af1158015611d7d573d6000803e3d6000fd5b505060685460675485516040516339240a7f60e21b81526001600160a01b0361010090930483166004820152602481019190915285821660448201529116925063e49029fc9150606401600060405180830381600087803b158015611de157600080fd5b505af1158015611df5573d6000803e3d6000fd5b505083516020850151611e0b9350909150614428565b602083015260e082015151611e3157611e2d818360c0015184602001516135d7565b5050565b611e738260e00151600081518110611e4b57611e4b6144d0565b6020026020010151606c60009054906101000a90046001600160a01b031684602001516135d7565b606c546040517f3bc788350000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690633bc7883590611ebc90859060040161422c565b600060405180830381600087803b158015611ed657600080fd5b505af1158015611eea573d6000803e3d6000fd5b5050505081604001518260c001516001600160a01b031683606001517f1f3f0f3c7b2df480755c6486a132f215e7b2b89fcca0beecd95a9696c71789b6856020015186600001518760800151604051611f5f9392919092835260208301919091526001600160a01b0316604082015260600190565b60405180910390a4505b50565b60675460ff1615611fae5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b60008530611fba613490565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f1981840301815291905280516020909101209050600160008281526069602052604090205460ff166002811115612032576120326144ba565b14156120a65760405162461bcd60e51b815260206004820152602560248201527f53796d623a2073796e74686574696320746f6b656e7320616c7265616479206d60448201527f696e74656400000000000000000000000000000000000000000000000000000060648201526084016104ea565b6000818152606960209081526040808320805460ff19166002179055805160608101909152602180825290916145f9908301398051602090910120604051602481018a90526044810184905260640160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092526067549151633675e4e160e11b81529092506001600160a01b036101009092049190911690636cebc9c2906121669084908a908a908a906004016141d0565b600060405180830381600087803b15801561218057600080fd5b505af1158015612194573d6000803e3d6000fd5b50505050506121a1613490565b6001600160a01b0316867f9bc8099e19706f253ae634ef1a5fb6ef84b4748c2183472905b9b2511cfa861760405160405180910390a3817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f58760405161220991815260200190565b60405180910390a250505050505050565b60675460009060ff161561225f5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b6001600160a01b0389166000908152606b60205260409020548810156122c75760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c640000000060448201526064016104ea565b6068546001600160a01b031663a8160b766122e0613490565b6040516001600160e01b031960e084901b1681526001600160a01b039182166004820152602481018c9052908c166044820152606401600060405180830381600087803b15801561233057600080fd5b505af1158015612344573d6000803e3d6000fd5b505050506001600160a01b03841661235a578693505b60685460405163161acb4760e01b81526001600160a01b038b81166004830152600092169063161acb479060240160206040518083038186803b1580156123a057600080fd5b505afa1580156123b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d89190613a0e565b90506001600160a01b0381166124305760405162461bcd60e51b815260206004820152601460248201527f53796d623a20696e636f72726563742073796e7400000000000000000000000060448201526064016104ea565b6066546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015260740160408051601f1981840301815282825280516020918201209083018190526bffffffffffffffffffffffff1960608b811b8216938501939093529188901b909116605483015260688201869052925060009060880160405160208183030381529060405280519060200120905060006040518060600160405280603d8152602001614530603d91398051602090910120604051602481018f905260448101849052606481018690526001600160a01b03808616608483015260a482018e90528c1660c482015260e40160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252815160c0810190925291508061256e613490565b6001600160a01b0390811682528c81166020830152604082018e905285811660608301528e16608082015260a001600190526000838152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180548516918616919091179055608085015160048301805494851691909516908117855560a0860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b908490811115612670576126706144ba565b02179055505060668054915060006126878361446b565b9091555050606754604051633675e4e160e11b81526101009091046001600160a01b031690636cebc9c2906126c69084908d908d908c906004016141d0565b600060405180830381600087803b1580156126e057600080fd5b505af11580156126f4573d6000803e3d6000fd5b50505050505050836001600160a01b03168361270e613490565b604080518581526001600160a01b038c811660208301529181018d90528d821660608201529116907f5f00e8f0d61ff1190912879949026c85a81f3f96038c7f4cd868bdfe882e0eeb9060800160405180910390a4817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f58260405161279591815260200190565b60405180910390a29998505050505050505050565b6127b2613490565b6001600160a01b03166127cd6033546001600160a01b031690565b6001600160a01b0316146128235760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6068546001600160a01b03161561287c5760405162461bcd60e51b815260206004820152601860248201527f53796d623a2046616272696320616c726561647920736574000000000000000060448201526064016104ea565b6068805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fe7258eee4870ba270f25f5a42dd11bfe5a77658959c916807b94b8e9063c3cd0906020015b60405180910390a150565b60675460009060ff16156129235760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b60a08201516001600160a01b03166000908152606b60209081526040909120549083015110156129955760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c640000000060448201526064016104ea565b6068546001600160a01b031663a8160b766129ae613490565b602085015160a08601516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201526024810192909252919091166044820152606401600060405180830381600087803b158015612a0a57600080fd5b505af1158015612a1e573d6000803e3d6000fd5b505050506101608201516001600160a01b0316612a4b576101008201516001600160a01b03166101608301525b60685460a083015160405163161acb4760e01b81526001600160a01b039182166004820152600092919091169063161acb479060240160206040518083038186803b158015612a9957600080fd5b505afa158015612aad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad19190613a0e565b90506001600160a01b038116612b295760405162461bcd60e51b815260206004820152601460248201527f53796d623a20696e636f72726563742073796e7400000000000000000000000060448201526064016104ea565b6066546040516bffffffffffffffffffffffff193060601b1660208201526034810191909152466054820152607401604051602081830303815290604052805190602001209150826040015160001415612b8557604083018290525b600082846101200151856101600151866101800151604051602001612bdb9493929190938452606092831b6bffffffffffffffffffffffff1990811660208601529190921b166034830152604882015260680190565b60405160208183030381529060405280519060200120905060006040518060800160405280605781526020016145a2605791398051906020012085600001518660400151848861010001518960200151888b608001518c60c001518d60e00151604051602401612c5399989796959493929190614344565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505090506040518060c0016040528086606001516001600160a01b031681526020018661010001516001600160a01b0316815260200186602001518152602001846001600160a01b031681526020018660a001516001600160a01b0316815260200160016002811115612cf957612cf96144ba565b90526000838152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180548516918616919091179055608085015160048301805494851691909516908117855560a0860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b908490811115612dcb57612dcb6144ba565b0217905550506066805491506000612de28361446b565b9091555050606754610120860151610140870151610180880151604051633675e4e160e11b81526101009094046001600160a01b031693636cebc9c293612e3293879391929091906004016141d0565b600060405180830381600087803b158015612e4c57600080fd5b505af1158015612e60573d6000803e3d6000fd5b505050505050508161016001516001600160a01b031682610180015183606001516001600160a01b03167f5f00e8f0d61ff1190912879949026c85a81f3f96038c7f4cd868bdfe882e0eeb8486610100015187602001518860a00151604051612eee94939291909384526001600160a01b039283166020850152604084019190915216606082015260800190565b60405180910390a46101a08201516040518281527f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f59060200160405180910390a2919050565b612f3c613490565b6001600160a01b0316612f576033546001600160a01b031690565b6001600160a01b031614612fad5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6001600160a01b0381166130295760405162461bcd60e51b815260206004820152602760248201527f53796d623a206d657461526f757465722063616e6e6f74206265207a65726f2060448201527f616464726573730000000000000000000000000000000000000000000000000060648201526084016104ea565b606c805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fd5c54ab1d37bfef4dd2253d9d73c292e46f5bd8a67ca5920aab4c2e1993178e7906020016128d3565b61308c613490565b6001600160a01b03166130a76033546001600160a01b031690565b6001600160a01b0316146130fd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ea565b6001600160a01b0381166131795760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ea565b611f69816134d6565b60675461010090046001600160a01b031633146131e15760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f742074686520627269646765000060448201526064016104ea565b60675460ff16156132235760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064016104ea565b6000818152606a6020526040902060016004820154600160a01b900460ff166002811115613253576132536144ba565b146132c65760405162461bcd60e51b815260206004820152602960248201527f53796d623a207374617465206e6f74206f70656e206f7220747820646f65732060448201527f6e6f74206578697374000000000000000000000000000000000000000000000060648201526084016104ea565b6004810180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674020000000000000000000000000000000000000000179055606854815460028301546001600160a01b039283169263e49029fc921690613330908790614428565b60048581015460405160e086901b6001600160e01b03191681526001600160a01b0394851692810192909252602482019290925291166044820152606401600060405180830381600087803b15801561338857600080fd5b505af115801561339c573d6000803e3d6000fd5b50506068546067546004858101546040516339240a7f60e21b81526001600160a01b0361010090940484169281019290925260248201899052821660448201529116925063e49029fc9150606401600060405180830381600087803b15801561340457600080fd5b505af1158015613418573d6000803e3d6000fd5b5050825460028401546001600160a01b0390911692508491507fb6f5f7b98cc78a8031c967af163a8c197f470a35df1e326a9038859679e6a1849061345e908790614428565b600485015460408051928352602083018990526001600160a01b039091169082015260600160405180910390a3505050565b6065546000906001600160a01b03163314156134d157507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b603380546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166135a05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ea565b6135a8613731565b6065805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b03167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161364c9190614105565b6000604051808303816000865af19150503d8060008114613689576040519150601f19603f3d011682016040523d82523d6000602084013e61368e565b606091505b50915091508180156136b85750805115806136b85750808060200190518101906136b89190613aa2565b61372a5760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c65640000000000000000000000000000000000000060648201526084016104ea565b5050505050565b600054610100900460ff1661379c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ea565b6137a46137ac565b610f63613817565b600054610100900460ff16610f635760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ea565b600054610100900460ff166138825760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ea565b610f6361388d613490565b6134d6565b803561389d8161451a565b919050565b600082601f8301126138b357600080fd5b8135602067ffffffffffffffff8211156138cf576138cf6144e6565b8160051b6138de8282016143f7565b8381528281019086840183880185018910156138f957600080fd5b600093505b858410156139255780356139118161451a565b8352600193909301929184019184016138fe565b50979650505050505050565b60008083601f84011261394357600080fd5b50813567ffffffffffffffff81111561395b57600080fd5b60208301915083602082850101111561397357600080fd5b9250929050565b600082601f83011261398b57600080fd5b813567ffffffffffffffff8111156139a5576139a56144e6565b6139b86020601f19601f840116016143f7565b8181528460208386010111156139cd57600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156139fc57600080fd5b8135613a078161451a565b9392505050565b600060208284031215613a2057600080fd5b8151613a078161451a565b600080600060608486031215613a4057600080fd5b8335613a4b8161451a565b92506020840135613a5b8161451a565b91506040840135613a6b8161451a565b809150509250925092565b60008060408385031215613a8957600080fd5b8235613a948161451a565b946020939093013593505050565b600060208284031215613ab457600080fd5b81518015158114613a0757600080fd5b600060208284031215613ad657600080fd5b5035919050565b600060208284031215613aef57600080fd5b813567ffffffffffffffff80821115613b0757600080fd5b908301906101c08286031215613b1c57600080fd5b613b246143a9565b823581526020830135602082015260408301356040820152613b4860608401613892565b6060820152613b5960808401613892565b6080820152613b6a60a08401613892565b60a082015260c083013582811115613b8157600080fd5b613b8d8782860161397a565b60c08301525060e083013560e08201526101009150613bad828401613892565b828201526101209150613bc1828401613892565b828201526101409150613bd5828401613892565b828201526101609150613be9828401613892565b9181019190915261018082810135908201526101a091820135918101919091529392505050565b600060208284031215613c2257600080fd5b813567ffffffffffffffff80821115613c3a57600080fd5b908301906101a08286031215613c4f57600080fd5b613c576143d3565b82358152602083013560208201526040830135604082015260608301356060820152613c8560808401613892565b608082015260a083013560a0820152613ca060c08401613892565b60c082015260e083013582811115613cb757600080fd5b613cc3878286016138a2565b60e083015250610100613cd7818501613892565b908201526101208381013583811115613cef57600080fd5b613cfb8882870161397a565b828401525050610140613d0f818501613892565b908201526101608381013583811115613d2757600080fd5b613d338882870161397a565b91830191909152506101809283013592810192909252509392505050565b60008060008060008060008060006101208a8c031215613d7057600080fd5b8935985060208a0135613d828161451a565b975060408a0135965060608a0135613d998161451a565b955060808a0135613da98161451a565b945060a08a0135613db98161451a565b935060c08a0135613dc98161451a565b8093505060e08a013591506101008a013590509295985092959850929598565b60008060408385031215613dfc57600080fd5b50508035926020909101359150565b60008060008060008060c08789031215613e2457600080fd5b86359550602087013594506040870135613e3d8161451a565b93506060870135613e4d8161451a565b92506080870135915060a0870135613e648161451a565b809150509295509295509295565b600080600080600080600060e0888a031215613e8d57600080fd5b87359650602088013595506040880135613ea68161451a565b94506060880135613eb68161451a565b93506080880135925060a0880135613ecd8161451a565b8092505060c0880135905092959891949750929550565b60008060008060008060c08789031215613efd57600080fd5b86359550602087013594506040870135613f168161451a565b93506060870135613f268161451a565b9598949750929560808101359460a0909101359350915050565b600080600080600080600080600060e08a8c031215613f5e57600080fd5b8935985060208a0135975060408a0135613f778161451a565b965060608a013567ffffffffffffffff80821115613f9457600080fd5b613fa08d838e01613931565b909850965060808c01359150613fb58261451a565b90945060a08b013590613fc78261451a565b90935060c08b01359080821115613fdd57600080fd5b50613fea8c828d01613931565b915080935050809150509295985092959850929598565b600080600080600080600060e0888a03121561401c57600080fd5b873596506020880135955060408801359450606088013561403c8161451a565b93506080880135925060a0880135915060c088013561405a8161451a565b8091505092959891949750929550565b600081518084526020808501945080840160005b838110156140a35781516001600160a01b03168752958201959082019060010161407e565b509495945050505050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b600081518084526140f181602086016020860161443f565b601f01601f19169290920160200192915050565b6000825161411781846020870161443f565b9190910192915050565b6001600160a01b03878116825286811660208301526040820186905284811660608301528316608082015260c08101614159836144fc565b8260a0830152979650505050505050565b60006001600160a01b03808c1683528a6020840152808a16604084015260e0606084015261419c60e08401898b6140ae565b818816608085015281871660a085015283810360c08501526141bf8186886140ae565b9d9c50505050505050505050505050565b6080815260006141e360808301876140d9565b6001600160a01b0395861660208401529390941660408201526060015292915050565b60208101614213836144fc565b91905290565b602081526000613a0760208301846140d9565b60208152815160208201526020820151604082015260408201516060820152606082015160808201526000608083015161427160a08401826001600160a01b03169052565b5060a083015160c083015260c083015161429660e08401826001600160a01b03169052565b5060e08301516101a061010081818601526142b56101c086018461406a565b908601519092506101206142d3868201836001600160a01b03169052565b80870151915050601f196101408187860301818801526142f385846140d9565b945080880151925050610160614313818801846001600160a01b03169052565b8088015192505061018081878603018188015261433085846140d9565b970151959092019490945250929392505050565b60006101208b83528a60208401528960408401526001600160a01b03808a16606085015288608085015280881660a085015280871660c0850152508060e0840152614391818401866140d9565b915050826101008301529a9950505050505050505050565b6040516101c0810167ffffffffffffffff811182821017156143cd576143cd6144e6565b60405290565b6040516101a0810167ffffffffffffffff811182821017156143cd576143cd6144e6565b604051601f8201601f1916810167ffffffffffffffff81118282101715614420576144206144e6565b604052919050565b60008282101561443a5761443a6144a4565b500390565b60005b8381101561445a578181015183820152602001614442565b83811115611a465750506000910152565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561449d5761449d6144a4565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60038110611f6957634e487b7160e01b600052602160045260246000fd5b6001600160a01b0381168114611f6957600080fdfe756e73796e74686573697a652875696e743235362c627974657333322c627974657333322c616464726573732c75696e743235362c6164647265737329756e73796e74686573697a652875696e743235362c627974657333322c616464726573732c75696e743235362c61646472657373296d657461556e73796e74686573697a652875696e743235362c627974657333322c627974657333322c616464726573732c75696e743235362c616464726573732c616464726573732c62797465732c75696e743235362972657665727453796e74686573697a652875696e743235362c6279746573333229a2646970667358221220db412997ea2bb14b76415a836f3f1de650a5b1d044076ff04074e2c81bd7500664736f6c63430008070033