Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Portal
- Optimization enabled
- true
- Compiler version
- v0.8.7+commit.e28d00a7
- Optimization runs
- 2000
- EVM Version
- default
- Verified at
- 2024-05-20T14:33:02.650405Z
contracts/synth-core/Portal.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol";
import "./interfaces/IBridge.sol";
import "@uniswap/lib/contracts/libraries/TransferHelper.sol";
import "../utils/RelayRecipientUpgradeable.sol";
import "./interfaces/IWrapper.sol";
import "./metarouter/interfaces/IMetaRouter.sol";
/**
* @title A contract that synthesizes tokens
* @notice In order to create a synthetic representation on another network, the user must call synthesize function here
* @dev All function calls are currently implemented without side effects
*/
contract Portal is RelayRecipientUpgradeable {
/// ** PUBLIC states **
address public wrapper;
address public bridge;
uint256 public requestCount;
bool public paused;
mapping(bytes32 => TxState) public requests;
mapping(bytes32 => UnsynthesizeState) public unsynthesizeStates;
mapping(address => uint256) public balanceOf;
mapping(address => uint256) public tokenThreshold;
mapping(address => bool) public tokenWhitelist;
IMetaRouter public metaRouter;
/// ** STRUCTS **
enum RequestState {
Default,
Sent,
Reverted
}
enum UnsynthesizeState {
Default,
Unsynthesized,
RevertRequest
}
struct TxState {
address recipient;
address chain2address;
uint256 amount;
address rtoken;
RequestState state;
}
struct SynthesizeWithPermitTransaction {
uint256 stableBridgingFee;
bytes approvalData;
address token;
uint256 amount;
address chain2address;
address receiveSide;
address oppositeBridge;
address revertableAddress;
uint256 chainID;
bytes32 clientID;
}
/// ** EVENTS **
event SynthesizeRequest(
bytes32 id, // todo it wasn't indexed
address indexed from,
uint256 indexed chainID,
address indexed revertableAddress, // todo it was indexed
address to,
uint256 amount,
address token
);
event RevertBurnRequest(bytes32 indexed id, address indexed to);
event ClientIdLog(bytes32 requestId, bytes32 indexed clientId);
event MetaRevertRequest(bytes32 indexed id, address indexed to);
event BurnCompleted(
bytes32 indexed id,
bytes32 indexed crossChainID,
address indexed to,
uint256 amount,
uint256 bridgingFee,
address token
);
event RevertSynthesizeCompleted(
bytes32 indexed id,
address indexed to,
uint256 amount,
uint256 bridgingFee,
address token
);
event Paused(address account);
event Unpaused(address account);
event SetWhitelistToken(address token, bool activate);
event SetTokenThreshold(address token, uint256 threshold);
event SetMetaRouter(address metaRouter);
/// ** 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,
address _wrapper,
address _whitelistedToken,
IMetaRouter _metaRouter
) public virtual initializer {
__RelayRecipient_init(_trustedForwarder);
bridge = _bridge;
wrapper = _wrapper;
metaRouter = _metaRouter;
if (_whitelistedToken != address(0)) {
tokenWhitelist[_whitelistedToken] = true;
}
}
/// ** EXTERNAL PURE functions **
/**
* @notice Returns version
*/
function versionRecipient() external pure returns (string memory) {
return "2.0.1";
}
// ** EXTERNAL functions **
/**
* @notice Sends synthesize request
* @dev Token -> sToken on a second chain
* @param _stableBridgingFee Bridging fee on another network
* @param _token The address of the token that the user wants to synthesize
* @param _amount Number of tokens to synthesize
* @param _chain2address The address to which the user wants to receive the synth asset on another network
* @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 synthesization will take place
*/
function synthesize(
uint256 _stableBridgingFee,
address _token,
uint256 _amount,
address _chain2address,
address _receiveSide,
address _oppositeBridge,
address _revertableAddress,
uint256 _chainID,
bytes32 _clientID
) external whenNotPaused returns (bytes32) {
require(tokenWhitelist[_token], "Symb: unauthorized token");
require(_amount >= tokenThreshold[_token], "Symb: amount under threshold");
TransferHelper.safeTransferFrom(
_token,
_msgSender(),
address(this),
_amount
);
return
sendSynthesizeRequest(
_stableBridgingFee,
_token,
_amount,
_chain2address,
_receiveSide,
_oppositeBridge,
_revertableAddress,
_chainID,
_clientID
);
}
/**
* @notice Sends metaSynthesizeOffchain request
* @dev Token -> sToken on a second chain -> final token on a second chain
* @param _metaSynthesizeTransaction metaSynthesize offchain transaction data
*/
function metaSynthesize(
MetaRouteStructs.MetaSynthesizeTransaction
memory _metaSynthesizeTransaction
) external whenNotPaused returns (bytes32) {
require(tokenWhitelist[_metaSynthesizeTransaction.rtoken], "Symb: unauthorized token");
require(_metaSynthesizeTransaction.amount >= tokenThreshold[_metaSynthesizeTransaction.rtoken],
"Symb: amount under threshold");
TransferHelper.safeTransferFrom(
_metaSynthesizeTransaction.rtoken,
_msgSender(),
address(this),
_metaSynthesizeTransaction.amount
);
return sendMetaSynthesizeRequest(_metaSynthesizeTransaction);
}
/**
* @notice Native -> sToken on a second chain
* @param _stableBridgingFee Bridging fee on another network
* @param _chain2address The address to which the user wants to receive the synth asset on another network
* @param _receiveSide Synthesis address on another network
* @param _oppositeBridge Bridge address on another network
* @param _chainID Chain id of the network where synthesization will take place
*/
function synthesizeNative(
uint256 _stableBridgingFee,
address _chain2address,
address _receiveSide,
address _oppositeBridge,
address _revertableAddress,
uint256 _chainID,
bytes32 _clientID
) external payable whenNotPaused returns (bytes32) {
require(tokenWhitelist[wrapper], "Symb: unauthorized token");
require(msg.value >= tokenThreshold[wrapper], "Symb: amount under threshold");
IWrapper(wrapper).deposit{value : msg.value}();
return
sendSynthesizeRequest(
_stableBridgingFee,
wrapper,
msg.value,
_chain2address,
_receiveSide,
_oppositeBridge,
_revertableAddress,
_chainID,
_clientID
);
}
/**
* @notice Token -> sToken on a second chain withPermit
* @param _syntWithPermitTx SynthesizeWithPermit offchain transaction data
*/
function synthesizeWithPermit(
SynthesizeWithPermitTransaction memory _syntWithPermitTx
) external whenNotPaused returns (bytes32) {
require(tokenWhitelist[_syntWithPermitTx.token], "Symb: unauthorized token");
require(_syntWithPermitTx.amount >= tokenThreshold[_syntWithPermitTx.token], "Symb: amount under threshold");
{
(
address owner,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) = abi.decode(
_syntWithPermitTx.approvalData,
(address, uint256, uint256, uint8, bytes32, bytes32)
);
IERC20Permit(_syntWithPermitTx.token).permit(
owner,
address(this),
value,
deadline,
v,
r,
s
);
}
TransferHelper.safeTransferFrom(
_syntWithPermitTx.token,
_msgSender(),
address(this),
_syntWithPermitTx.amount
);
return
sendSynthesizeRequest(
_syntWithPermitTx.stableBridgingFee,
_syntWithPermitTx.token,
_syntWithPermitTx.amount,
_syntWithPermitTx.chain2address,
_syntWithPermitTx.receiveSide,
_syntWithPermitTx.oppositeBridge,
_syntWithPermitTx.revertableAddress,
_syntWithPermitTx.chainID,
_syntWithPermitTx.clientID
);
}
/**
* @notice Emergency unsynthesize
* @dev Can called only by bridge after initiation on a second chain
* @dev If a transaction arrives at the synthesization chain with an already completed revert synthesize contract will fail this transaction,
* since the state was changed during the call to the desynthesis request
* @param _stableBridgingFee Bridging fee
* @param _externalID the synthesize transaction that was received from the event when it was originally called synthesize on the Portal contract
*/
function revertSynthesize(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
balanceOf[txState.rtoken] = balanceOf[txState.rtoken] - txState.amount;
TransferHelper.safeTransfer(
txState.rtoken,
txState.recipient,
txState.amount - _stableBridgingFee
);
TransferHelper.safeTransfer(
txState.rtoken,
bridge,
_stableBridgingFee
);
emit RevertSynthesizeCompleted(
_externalID,
txState.recipient,
txState.amount - _stableBridgingFee,
_stableBridgingFee,
txState.rtoken
);
}
/**
* @notice Revert synthesize
* @dev After revertSynthesizeRequest in Synthesis this method is called
* @param _stableBridgingFee Bridging fee
* @param _externalID the burn transaction that was received from the event when it was originally called burn on the Synthesis contract
* @param _token The address of the token to unsynthesize
* @param _amount Number of tokens to unsynthesize
* @param _to The address to receive tokens
*/
function unsynthesize(
uint256 _stableBridgingFee,
bytes32 _externalID,
bytes32 _crossChainID,
address _token,
uint256 _amount,
address _to
) external onlyBridge whenNotPaused {
require(
unsynthesizeStates[_externalID] == UnsynthesizeState.Default,
"Symb: synthetic tokens emergencyUnburn"
);
balanceOf[_token] = balanceOf[_token] - _amount;
unsynthesizeStates[_externalID] = UnsynthesizeState.Unsynthesized;
TransferHelper.safeTransfer(_token, _to, _amount - _stableBridgingFee);
TransferHelper.safeTransfer(_token, bridge, _stableBridgingFee);
emit BurnCompleted(_externalID, _crossChainID, _to, _amount - _stableBridgingFee, _stableBridgingFee, _token);
}
/**
* @notice Unsynthesize and final call on second chain
* @dev Token -> sToken on a first chain -> final token on a second chain
* @param _stableBridgingFee Number of tokens to send to bridge (fee)
* @param _externalID the metaBurn transaction that was received from the event when it was originally called metaBurn on the Synthesis contract
* @param _to The address to receive tokens
* @param _amount Number of tokens to unsynthesize
* @param _rToken The address of the token to unsynthesize
* @param _finalReceiveSide router for final call
* @param _finalCalldata encoded call of a final function
* @param _finalOffset offset to patch _amount to _finalCalldata
*/
function metaUnsynthesize(
uint256 _stableBridgingFee,
bytes32 _crossChainID,
bytes32 _externalID,
address _to,
uint256 _amount,
address _rToken,
address _finalReceiveSide,
bytes memory _finalCalldata,
uint256 _finalOffset
) external onlyBridge whenNotPaused {
require(
unsynthesizeStates[_externalID] == UnsynthesizeState.Default,
"Symb: synthetic tokens emergencyUnburn"
);
balanceOf[_rToken] = balanceOf[_rToken] - _amount;
unsynthesizeStates[_externalID] = UnsynthesizeState.Unsynthesized;
TransferHelper.safeTransfer(_rToken, bridge, _stableBridgingFee);
_amount = _amount - _stableBridgingFee;
if (_finalCalldata.length == 0) {
TransferHelper.safeTransfer(_rToken, _to, _amount);
emit BurnCompleted(_externalID, _crossChainID, address(this), _amount, _stableBridgingFee, _rToken);
return;
}
// transfer ERC20 tokens to MetaRouter
TransferHelper.safeTransfer(
_rToken,
address(metaRouter),
_amount
);
// metaRouter call
metaRouter.externalCall(_rToken, _amount, _finalReceiveSide, _finalCalldata, _finalOffset, _to);
emit BurnCompleted(_externalID, _crossChainID, address(this), _amount, _stableBridgingFee, _rToken);
}
/**
* @notice Revert burnSyntheticToken() 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 "revertBurn"
* @param _stableBridgingFee Bridging fee on another network
* @param _internalID the synthesize transaction that was received from the event when it was originally called burn on the Synthesize contract
* @param _receiveSide Synthesis address on another network
* @param _oppositeBridge Bridge address on another network
* @param _chainId Chain id of the network
*/
function revertBurnRequest(
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(
unsynthesizeStates[externalID] != UnsynthesizeState.Unsynthesized,
"Symb: Real tokens already transfered"
);
unsynthesizeStates[externalID] = UnsynthesizeState.RevertRequest;
{
bytes memory out = abi.encodeWithSelector(
bytes4(keccak256(bytes("revertBurn(uint256,bytes32)"))),
_stableBridgingFee,
externalID
);
IBridge(bridge).transmitRequestV2(
out,
_receiveSide,
_oppositeBridge,
_chainId
);
}
emit RevertBurnRequest(_internalID, _msgSender());
emit ClientIdLog(_internalID, _clientID);
}
function metaRevertRequest(
MetaRouteStructs.MetaRevertTransaction memory _metaRevertTransaction
) external whenNotPaused {
if (_metaRevertTransaction.swapCalldata.length != 0){
bytes32 externalID = keccak256(abi.encodePacked(_metaRevertTransaction.internalID, address(this), _msgSender(), block.chainid));
require(
unsynthesizeStates[externalID] != UnsynthesizeState.Unsynthesized,
"Symb: Real tokens already transfered"
);
unsynthesizeStates[externalID] = UnsynthesizeState.RevertRequest;
{
bytes memory out = abi.encodeWithSelector(
bytes4(keccak256(bytes("revertMetaBurn(uint256,bytes32,address,bytes,address,address,bytes)"))),
_metaRevertTransaction.stableBridgingFee,
externalID,
_metaRevertTransaction.router,
_metaRevertTransaction.swapCalldata,
_metaRevertTransaction.sourceChainSynthesis,
_metaRevertTransaction.burnToken,
_metaRevertTransaction.burnCalldata
);
IBridge(bridge).transmitRequestV2(
out,
_metaRevertTransaction.receiveSide,
_metaRevertTransaction.managerChainBridge,
_metaRevertTransaction.managerChainId
);
emit RevertBurnRequest(_metaRevertTransaction.internalID, _msgSender());
emit ClientIdLog(_metaRevertTransaction.internalID, _metaRevertTransaction.clientID);
}
} else {
if (_metaRevertTransaction.burnCalldata.length != 0){
bytes32 externalID = keccak256(abi.encodePacked(_metaRevertTransaction.internalID, address(this), _msgSender(), block.chainid));
require(
unsynthesizeStates[externalID] != UnsynthesizeState.Unsynthesized,
"Symb: Real tokens already transfered"
);
unsynthesizeStates[externalID] = UnsynthesizeState.RevertRequest;
bytes memory out = abi.encodeWithSelector(
bytes4(keccak256(bytes("revertBurnAndBurn(uint256,bytes32,address,address,uint256,address)"))),
_metaRevertTransaction.stableBridgingFee,
externalID,
address(this),
_metaRevertTransaction.sourceChainBridge,
block.chainid,
_msgSender()
);
IBridge(bridge).transmitRequestV2(
out,
_metaRevertTransaction.sourceChainSynthesis,
_metaRevertTransaction.managerChainBridge,
_metaRevertTransaction.managerChainId
);
emit RevertBurnRequest(_metaRevertTransaction.internalID, _msgSender());
emit ClientIdLog(_metaRevertTransaction.internalID, _metaRevertTransaction.clientID);
} else {
bytes memory out = abi.encodeWithSelector(
bytes4(keccak256(bytes("revertSynthesizeRequestByBridge(uint256,bytes32,address,address,uint256,address,bytes32)"))),
_metaRevertTransaction.stableBridgingFee,
_metaRevertTransaction.internalID,
_metaRevertTransaction.receiveSide,
_metaRevertTransaction.sourceChainBridge,
block.chainid,
_msgSender(),
_metaRevertTransaction.clientID
);
IBridge(bridge).transmitRequestV2(
out,
_metaRevertTransaction.sourceChainSynthesis,
_metaRevertTransaction.managerChainBridge,
_metaRevertTransaction.managerChainId
);
}
}
emit MetaRevertRequest(_metaRevertTransaction.internalID, _msgSender());
}
// ** 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 token to tokenWhitelist
* @param _token Address of token to add to whitelist
* @param _activate true - add to whitelist, false - remove from whitelist
*/
function setWhitelistToken(address _token, bool _activate) external onlyOwner {
tokenWhitelist[_token] = _activate;
emit SetWhitelistToken(_token, _activate);
}
/**
* @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));
}
/// ** INTERNAL functions **
/**
* @dev Sends synthesize request
* @dev Internal function used in synthesize, synthesizeNative, synthesizeWithPermit
*/
function sendSynthesizeRequest(
uint256 _stableBridgingFee,
address _token,
uint256 _amount,
address _chain2address,
address _receiveSide,
address _oppositeBridge,
address _revertableAddress,
uint256 _chainID,
bytes32 _clientID
) internal returns (bytes32 internalID) {
balanceOf[_token] = balanceOf[_token] + _amount;
if (_revertableAddress == address(0)) {
_revertableAddress = _chain2address;
}
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(
"mintSyntheticToken(uint256,bytes32,bytes32,address,uint256,uint256,address)"
)
)
),
_stableBridgingFee,
externalID,
internalID,
_token,
block.chainid,
_amount,
_chain2address
);
requests[externalID] = TxState({
recipient : _msgSender(),
chain2address : _chain2address,
rtoken : _token,
amount : _amount,
state : RequestState.Sent
});
requestCount++;
IBridge(bridge).transmitRequestV2(
out,
_receiveSide,
_oppositeBridge,
_chainID
);
}
}
emit SynthesizeRequest(
internalID,
_msgSender(),
_chainID,
_revertableAddress,
_chain2address,
_amount,
_token
);
emit ClientIdLog(internalID, _clientID);
}
/**
* @dev Sends metaSynthesizeOffchain request
* @dev Internal function used in metaSynthesizeOffchain
*/
function sendMetaSynthesizeRequest(
MetaRouteStructs.MetaSynthesizeTransaction
memory _metaSynthesizeTransaction
) internal returns (bytes32 internalID) {
balanceOf[_metaSynthesizeTransaction.rtoken] =
balanceOf[_metaSynthesizeTransaction.rtoken] +
_metaSynthesizeTransaction.amount;
if (_metaSynthesizeTransaction.revertableAddress == address(0)) {
_metaSynthesizeTransaction.revertableAddress = _metaSynthesizeTransaction.chain2address;
}
internalID = keccak256(abi.encodePacked(this, requestCount, block.chainid));
bytes32 externalID = keccak256(
abi.encodePacked(internalID, _metaSynthesizeTransaction.receiveSide, _metaSynthesizeTransaction.revertableAddress, _metaSynthesizeTransaction.chainID)
);
MetaRouteStructs.MetaMintTransaction
memory _metaMintTransaction = MetaRouteStructs.MetaMintTransaction(
_metaSynthesizeTransaction.stableBridgingFee,
_metaSynthesizeTransaction.amount,
internalID,
externalID,
_metaSynthesizeTransaction.rtoken,
block.chainid,
_metaSynthesizeTransaction.chain2address,
_metaSynthesizeTransaction.swapTokens,
_metaSynthesizeTransaction.secondDexRouter,
_metaSynthesizeTransaction.secondSwapCalldata,
_metaSynthesizeTransaction.finalReceiveSide,
_metaSynthesizeTransaction.finalCalldata,
_metaSynthesizeTransaction.finalOffset
);
{
bytes memory out = abi.encodeWithSignature(
"metaMintSyntheticToken((uint256,uint256,bytes32,bytes32,address,uint256,address,address[],"
"address,bytes,address,bytes,uint256))",
_metaMintTransaction
);
requests[externalID] = TxState({
recipient : _metaSynthesizeTransaction.syntCaller,
chain2address : _metaSynthesizeTransaction.chain2address,
rtoken : _metaSynthesizeTransaction.rtoken,
amount : _metaSynthesizeTransaction.amount,
state : RequestState.Sent
});
requestCount++;
IBridge(bridge).transmitRequestV2(
out,
_metaSynthesizeTransaction.receiveSide,
_metaSynthesizeTransaction.oppositeBridge,
_metaSynthesizeTransaction.chainID
);
}
emit SynthesizeRequest(
internalID,
_metaSynthesizeTransaction.syntCaller,
_metaSynthesizeTransaction.chainID,
_metaSynthesizeTransaction.revertableAddress,
_metaSynthesizeTransaction.chain2address,
_metaSynthesizeTransaction.amount,
_metaSynthesizeTransaction.rtoken
);
emit ClientIdLog(internalID, _metaSynthesizeTransaction.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;
}
@openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.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 Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_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);
}
}
@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @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 Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
@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/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/IWrapper.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
interface IWrapper {
function deposit() external payable;
function withdraw(uint256 amount) 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;
}
}
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":"BurnCompleted","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"crossChainID","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":"ClientIdLog","inputs":[{"type":"bytes32","name":"requestId","internalType":"bytes32","indexed":false},{"type":"bytes32","name":"clientId","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"MetaRevertRequest","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"address","name":"to","internalType":"address","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":"RevertBurnRequest","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RevertSynthesizeCompleted","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":"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":"SetWhitelistToken","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"bool","name":"activate","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"SynthesizeRequest","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":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"bridge","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_bridge","internalType":"address"},{"type":"address","name":"_trustedForwarder","internalType":"address"},{"type":"address","name":"_wrapper","internalType":"address"},{"type":"address","name":"_whitelistedToken","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":[],"name":"metaRevertRequest","inputs":[{"type":"tuple","name":"_metaRevertTransaction","internalType":"struct MetaRouteStructs.MetaRevertTransaction","components":[{"type":"uint256","name":"stableBridgingFee","internalType":"uint256"},{"type":"bytes32","name":"internalID","internalType":"bytes32"},{"type":"address","name":"receiveSide","internalType":"address"},{"type":"address","name":"managerChainBridge","internalType":"address"},{"type":"address","name":"sourceChainBridge","internalType":"address"},{"type":"uint256","name":"managerChainId","internalType":"uint256"},{"type":"uint256","name":"sourceChainId","internalType":"uint256"},{"type":"address","name":"router","internalType":"address"},{"type":"bytes","name":"swapCalldata","internalType":"bytes"},{"type":"address","name":"sourceChainSynthesis","internalType":"address"},{"type":"address","name":"burnToken","internalType":"address"},{"type":"bytes","name":"burnCalldata","internalType":"bytes"},{"type":"bytes32","name":"clientID","internalType":"bytes32"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IMetaRouter"}],"name":"metaRouter","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"metaSynthesize","inputs":[{"type":"tuple","name":"_metaSynthesizeTransaction","internalType":"struct MetaRouteStructs.MetaSynthesizeTransaction","components":[{"type":"uint256","name":"stableBridgingFee","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"address","name":"rtoken","internalType":"address"},{"type":"address","name":"chain2address","internalType":"address"},{"type":"address","name":"receiveSide","internalType":"address"},{"type":"address","name":"oppositeBridge","internalType":"address"},{"type":"address","name":"syntCaller","internalType":"address"},{"type":"uint256","name":"chainID","internalType":"uint256"},{"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":"address","name":"revertableAddress","internalType":"address"},{"type":"bytes32","name":"clientID","internalType":"bytes32"}]}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"metaUnsynthesize","inputs":[{"type":"uint256","name":"_stableBridgingFee","internalType":"uint256"},{"type":"bytes32","name":"_crossChainID","internalType":"bytes32"},{"type":"bytes32","name":"_externalID","internalType":"bytes32"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_rToken","internalType":"address"},{"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":"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":"rtoken","internalType":"address"},{"type":"uint8","name":"state","internalType":"enum Portal.RequestState"}],"name":"requests","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revertBurnRequest","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":"revertSynthesize","inputs":[{"type":"uint256","name":"_stableBridgingFee","internalType":"uint256"},{"type":"bytes32","name":"_externalID","internalType":"bytes32"}]},{"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":"nonpayable","outputs":[],"name":"setWhitelistToken","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"bool","name":"_activate","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"synthesize","inputs":[{"type":"uint256","name":"_stableBridgingFee","internalType":"uint256"},{"type":"address","name":"_token","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":"payable","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"synthesizeNative","inputs":[{"type":"uint256","name":"_stableBridgingFee","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":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"synthesizeWithPermit","inputs":[{"type":"tuple","name":"_syntWithPermitTx","internalType":"struct Portal.SynthesizeWithPermitTransaction","components":[{"type":"uint256","name":"stableBridgingFee","internalType":"uint256"},{"type":"bytes","name":"approvalData","internalType":"bytes"},{"type":"address","name":"token","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":"uint256","name":"","internalType":"uint256"}],"name":"tokenThreshold","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"tokenWhitelist","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":"nonpayable","outputs":[],"name":"unsynthesize","inputs":[{"type":"uint256","name":"_stableBridgingFee","internalType":"uint256"},{"type":"bytes32","name":"_externalID","internalType":"bytes32"},{"type":"bytes32","name":"_crossChainID","internalType":"bytes32"},{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_to","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"enum Portal.UnsynthesizeState"}],"name":"unsynthesizeStates","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"versionRecipient","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"wrapper","inputs":[]}]
Contract Creation Code
0x608060405234801561001057600080fd5b506141b0806100206000396000f3fe6080604052600436106101cd5760003560e01c80638bb39802116100f7578063ce654c1711610095578063f2fde38b11610064578063f2fde38b146105bc578063fab92894146105dc578063fb7c7c2a14610619578063fce633c21461063957600080fd5b8063ce654c171461053c578063dbec15bb1461055c578063e78cea921461057c578063eadd5c341461059c57600080fd5b8063ac210cc7116100d1578063ac210cc7146104bc578063b1659a3c146104dc578063c23a4c88146104fc578063c42a28941461051c57600080fd5b80638bb39802146103fe5780638da5cb5b1461041e5780639d8669851461045057600080fd5b80635badbe4c1161016f578063715018a61161013e578063715018a614610384578063753d7563146103995780637c374f99146103c95780638456cb59146103e957600080fd5b80635badbe4c146102fa5780635c975abb14610310578063687752781461032a57806370a082311461035757600080fd5b80632816f4db116101ab5780632816f4db146102345780633f4ba83a1461025a578063486ff0cd1461026f578063572b6c05146102bb57600080fd5b806308759e9b146101d25780631459457a146101f45780631ebe53ef14610214575b600080fd5b3480156101de57600080fd5b506101f26101ed366004613a48565b610659565b005b34801561020057600080fd5b506101f261020f366004613461565b610908565b34801561022057600080fd5b506101f261022f366004613aa4565b610a8b565b610247610242366004613914565b610ca5565b6040519081526020015b60405180910390f35b34801561026657600080fd5b506101f2610e52565b34801561027b57600080fd5b50604080518082018252600581527f322e302e31000000000000000000000000000000000000000000000000000000602082015290516102519190613d09565b3480156102c757600080fd5b506102ea6102d63660046133d7565b6065546001600160a01b0391821691161490565b6040519015158152602001610251565b34801561030657600080fd5b5061024760685481565b34801561031c57600080fd5b506069546102ea9060ff1681565b34801561033657600080fd5b506102476103453660046133d7565b606d6020526000908152604090205481565b34801561036357600080fd5b506102476103723660046133d7565b606c6020526000908152604090205481565b34801561039057600080fd5b506101f2610f1b565b3480156103a557600080fd5b506102ea6103b43660046133d7565b606e6020526000908152604090205460ff1681565b3480156103d557600080fd5b506101f26103e43660046134d2565b610fa0565b3480156103f557600080fd5b506101f261107d565b34801561040a57600080fd5b506101f261041936600461350b565b61112c565b34801561042a57600080fd5b506033546001600160a01b03165b6040516001600160a01b039091168152602001610251565b34801561045c57600080fd5b506104ab61046b366004613554565b606a6020526000908152604090208054600182015460028301546003909301546001600160a01b039283169391831692811690600160a01b900460ff1685565b604051610251959493929190613c34565b3480156104c857600080fd5b50606654610438906001600160a01b031681565b3480156104e857600080fd5b506102476104f736600461398e565b6111f6565b34801561050857600080fd5b506101f2610517366004613b02565b61133d565b34801561052857600080fd5b506101f2610537366004613a26565b611646565b34801561054857600080fd5b506102476105573660046136a2565b6118c7565b34801561056857600080fd5b50606f54610438906001600160a01b031681565b34801561058857600080fd5b50606754610438906001600160a01b031681565b3480156105a857600080fd5b506101f26105b73660046133d7565b611a13565b3480156105c857600080fd5b506101f26105d73660046133d7565b611b69565b3480156105e857600080fd5b5061060c6105f7366004613554565b606b6020526000908152604090205460ff1681565b6040516102519190613cf6565b34801561062557600080fd5b50610247610634366004613825565b611c6a565b34801561064557600080fd5b506101f261065436600461356d565b611eb6565b60695460ff16156106a05760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064015b60405180910390fd5b600085306106ac612535565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff16600281111561072457610724613fe5565b141561077e5760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b6064820152608401610697565b6000818152606b6020908152604091829020805460ff1916600217905581518083018352601b81527f7265766572744275726e2875696e743235362c62797465733332290000000000908201528151602481018a90526044808201859052835180830390910181526064909101835290810180516001600160e01b03167ff70519ae000000000000000000000000000000000000000000000000000000001790526067549151633675e4e160e11b815290916001600160a01b031690636cebc9c2906108549084908a908a908a90600401613cc0565b600060405180830381600087803b15801561086e57600080fd5b505af1158015610882573d6000803e3d6000fd5b505050505061088f612535565b6001600160a01b0316867f40590cc12db0488520ce425059f83f8caed91bdf98de5ff829dc57c63843161b60405160405180910390a3817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f5876040516108f791815260200190565b60405180910390a250505050505050565b600054610100900460ff166109235760005460ff1615610927565b303b155b6109995760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610697565b600054610100900460ff161580156109d857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6109e18561257b565b606780546001600160a01b0380891673ffffffffffffffffffffffffffffffffffffffff199283161790925560668054878416908316179055606f80548584169216919091179055831615610a54576001600160a01b0383166000908152606e60205260409020805460ff191660011790555b8015610a8357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b505050505050565b6067546001600160a01b03163314610ae55760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f74207468652062726964676500006044820152606401610697565b60695460ff1615610b275760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6000858152606b602052604081205460ff166002811115610b4a57610b4a613fe5565b14610bbd5760405162461bcd60e51b815260206004820152602660248201527f53796d623a2073796e74686574696320746f6b656e7320656d657267656e637960448201527f556e6275726e00000000000000000000000000000000000000000000000000006064820152608401610697565b6001600160a01b0383166000908152606c6020526040902054610be1908390613f4f565b6001600160a01b0384166000908152606c6020908152604080832093909355878252606b905220805460ff19166001179055610c278382610c228986613f4f565b61261d565b606754610c3f9084906001600160a01b03168861261d565b6001600160a01b03811684867faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26610c768a87613f4f565b60408051918252602082018c90526001600160a01b0389169082015260600160405180910390a4505050505050565b60695460009060ff1615610cea5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6066546001600160a01b03166000908152606e602052604090205460ff16610d545760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e00000000000000006044820152606401610697565b6066546001600160a01b03166000908152606d6020526040902054341015610dbe5760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c64000000006044820152606401610697565b606660009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610e0e57600080fd5b505af1158015610e22573d6000803e3d6000fd5b5050606654610e4693508b92506001600160a01b03169050348a8a8a8a8a8a612777565b98975050505050505050565b610e5a612535565b6001600160a01b0316610e756033546001600160a01b031690565b6001600160a01b031614610ecb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6069805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610efe612535565b6040516001600160a01b03909116815260200160405180910390a1565b610f23612535565b6001600160a01b0316610f3e6033546001600160a01b031690565b6001600160a01b031614610f945760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b610f9e6000612b38565b565b610fa8612535565b6001600160a01b0316610fc36033546001600160a01b031690565b6001600160a01b0316146110195760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6001600160a01b0382166000818152606e6020908152604091829020805460ff19168515159081179091558251938452908301527f0a4552f1105808db6a44587c9ef0a7c4064bf620b9d843b514ad7365bd52239a91015b60405180910390a15050565b611085612535565b6001600160a01b03166110a06033546001600160a01b031690565b6001600160a01b0316146110f65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6069805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610efe612535565b611134612535565b6001600160a01b031661114f6033546001600160a01b031690565b6001600160a01b0316146111a55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6001600160a01b0382166000818152606d6020908152604091829020849055815192835282018390527fa6742efd4f410d6fd9688a6cf6a15b6d51121097a263056a3576baaacdc4a9ae9101611071565b60695460009060ff161561123b5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6001600160a01b0389166000908152606e602052604090205460ff166112a35760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e00000000000000006044820152606401610697565b6001600160a01b0389166000908152606d602052604090205488101561130b5760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c64000000006044820152606401610697565b61131e89611317612535565b308b612b97565b61132f8a8a8a8a8a8a8a8a8a612777565b9a9950505050505050505050565b6067546001600160a01b031633146113975760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f74207468652062726964676500006044820152606401610697565b60695460ff16156113d95760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6000878152606b602052604081205460ff1660028111156113fc576113fc613fe5565b1461146f5760405162461bcd60e51b815260206004820152602660248201527f53796d623a2073796e74686574696320746f6b656e7320656d657267656e637960448201527f556e6275726e00000000000000000000000000000000000000000000000000006064820152608401610697565b6001600160a01b0384166000908152606c6020526040902054611493908690613f4f565b6001600160a01b038581166000908152606c60209081526040808320949094558a8252606b905291909120805460ff191660011790556067546114d9918691168b61261d565b6114e38986613f4f565b945081516000141561154e576114fa84878761261d565b60408051868152602081018b90526001600160a01b03861681830152905130918a918a917faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26919081900360600190a461163b565b606f546115669085906001600160a01b03168761261d565b606f546040517ff5b697a50000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063f5b697a5906115b990879089908890889088908e90600401613c74565b600060405180830381600087803b1580156115d357600080fd5b505af11580156115e7573d6000803e3d6000fd5b505060408051888152602081018d90526001600160a01b0388168183015290513093508b92508a917faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26919081900360600190a45b505050505050505050565b6067546001600160a01b031633146116a05760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f74207468652062726964676500006044820152606401610697565b60695460ff16156116e25760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6000818152606a6020526040902060016003820154600160a01b900460ff16600281111561171257611712613fe5565b146117855760405162461bcd60e51b815260206004820152602960248201527f53796d623a207374617465206e6f74206f70656e206f7220747820646f65732060448201527f6e6f7420657869737400000000000000000000000000000000000000000000006064820152608401610697565b600381018054740200000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff82161790915560028201546001600160a01b039091166000908152606c60205260409020546117f19190613f4f565b6003820180546001600160a01b039081166000908152606c6020526040902092909255548254600284015461183493928316929190911690610c22908790613f4f565b6003810154606754611853916001600160a01b0390811691168561261d565b805460028201546001600160a01b039091169083907fefcdf9ea4e65571d2ce9c030c46954e950662df8a7d8bd039fc4417e37b2f88c90611895908790613f4f565b600385015460408051928352602083018990526001600160a01b039091169082015260600160405180910390a3505050565b60695460009060ff161561190c5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6040808301516001600160a01b03166000908152606e602052205460ff166119765760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e00000000000000006044820152606401610697565b6040808301516001600160a01b03166000908152606d6020908152919020549083015110156119e75760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c64000000006044820152606401610697565b611a0282604001516119f7612535565b308560200151612b97565b611a0b82612cf2565b90505b919050565b611a1b612535565b6001600160a01b0316611a366033546001600160a01b031690565b6001600160a01b031614611a8c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6001600160a01b038116611b085760405162461bcd60e51b815260206004820152602760248201527f53796d623a206d657461526f757465722063616e6e6f74206265207a65726f2060448201527f61646472657373000000000000000000000000000000000000000000000000006064820152608401610697565b606f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fd5c54ab1d37bfef4dd2253d9d73c292e46f5bd8a67ca5920aab4c2e1993178e79060200160405180910390a150565b611b71612535565b6001600160a01b0316611b8c6033546001600160a01b031690565b6001600160a01b031614611be25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6001600160a01b038116611c5e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610697565b611c6781612b38565b50565b60695460009060ff1615611caf5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6040808301516001600160a01b03166000908152606e602052205460ff16611d195760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e00000000000000006044820152606401610697565b6040808301516001600160a01b03166000908152606d602052205460608301511015611d875760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c64000000006044820152606401610697565b6000806000806000808760200151806020019051810190611da891906133fb565b6040808f015190517fd505accf0000000000000000000000000000000000000000000000000000000081526001600160a01b038089166004830152306024830152604482018890526064820187905260ff8616608483015260a4820185905260c48201849052979d50959b5093995091975095509350919091169063d505accf9060e401600060405180830381600087803b158015611e4657600080fd5b505af1158015611e5a573d6000803e3d6000fd5b50505050505050505050611e7f8260400151611e74612535565b308560600151612b97565b611a0b82600001518360400151846060015185608001518660a001518760c001518860e001518961010001518a6101200151612777565b60695460ff1615611ef85760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b61010081015151156121a4576000816020015130611f14612535565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff166002811115611f8c57611f8c613fe5565b1415611fe65760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b6064820152608401610697565b6000818152606b60209081526040808320805460ff19166002179055805160808101909152604380825290916140ed90830139805190602001208360000151838560e001518661010001518761012001518861014001518961016001516040516024016120599796959493929190613e34565b60408051601f198184030181529181526020820180516001600160e01b03167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260675485830151606087015160a08801519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c2936120e6938793929091600401613cc0565b600060405180830381600087803b15801561210057600080fd5b505af1158015612114573d6000803e3d6000fd5b50505050612120612535565b6001600160a01b031683602001517f40590cc12db0488520ce425059f83f8caed91bdf98de5ff829dc57c63843161b60405160405180910390a38261018001517f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f5846020015160405161219591815260200190565b60405180910390a250506124f0565b61016081015151156123a95760008160200151306121c0612535565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff16600281111561223857612238613fe5565b14156122925760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b6064820152608401610697565b6000818152606b60209081526040808320805460ff19166002179055805160808101909152604280825290916140ab9083013980519060200120836000015183308660800151466122e1612535565b604051602481019690965260448601949094526001600160a01b039283166064860152908216608485015260a48401521660c482015260e40160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252606754610120860151606087015160a08801519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c2936120e6938793929091600401613cc0565b600060405180608001604052806058815260200161405360589139805190602001208260000151836020015184604001518560800151466123e8612535565b610180890151604051602481019790975260448701959095526001600160a01b039384166064870152918316608486015260a48501521660c483015260e48201526101040160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252606754610120850151606086015160a08701519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c2936124bc938793929091600401613cc0565b600060405180830381600087803b1580156124d657600080fd5b505af11580156124ea573d6000803e3d6000fd5b50505050505b6124f8612535565b6001600160a01b031681602001517fbd03c66ec5bd3d01fbf22bc794f68ac88b693023b438724019205a4b42aefb2060405160405180910390a350565b6065546000906001600160a01b031633141561257657507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b600054610100900460ff166125e65760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610697565b6125ee61316c565b6065805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b03167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916126929190613c18565b6000604051808303816000865af19150503d80600081146126cf576040519150601f19603f3d011682016040523d82523d6000602084013e6126d4565b606091505b50915091508180156126fe5750805115806126fe5750808060200190518101906126fe9190613537565b6127705760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c6564000000000000000000000000000000000000006064820152608401610697565b5050505050565b6001600160a01b0388166000908152606c602052604081205461279b908990613f37565b6001600160a01b03808b166000908152606c602052604090209190915584166127c2578693505b6068546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015260740160408051601f1981840301815282825280516020918201209083018190526bffffffffffffffffffffffff1960608a811b8216938501939093529187901b909116605483015260688201859052915060009060880160405160208183030381529060405280519060200120905060006040518060800160405280604b8152602001614130604b91398051602090910120604051602481018e905260448101849052606481018590526001600160a01b03808e1660848301524660a483015260c482018d90528b1660e48201526101040160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252815160a0810190925291508061291f612535565b6001600160a01b0390811682528b81166020830152604082018d90528d166060820152608001600190526000838152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180549485169190951690811785556080860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b908490811115612a0357612a03613fe5565b0217905550506068805491506000612a1a83613f96565b9091555050606754604051633675e4e160e11b81526001600160a01b0390911690636cebc9c290612a559084908c908c908b90600401613cc0565b600060405180830381600087803b158015612a6f57600080fd5b505af1158015612a83573d6000803e3d6000fd5b505050505050836001600160a01b031683612a9c612535565b604080518581526001600160a01b038c811660208301529181018d90528d821660608201529116907f31325fe0a1a2e6a5b1e41572156ba5b4e94f0fae7e7f63ec21e9b5ce1e4b3eab9060800160405180910390a4817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f582604051612b2391815260200190565b60405180910390a29998505050505050505050565b603380546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691612c149190613c18565b6000604051808303816000865af19150503d8060008114612c51576040519150601f19603f3d011682016040523d82523d6000602084013e612c56565b606091505b5091509150818015612c80575080511580612c80575080806020019051810190612c809190613537565b610a835760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a20747260448201527f616e7366657246726f6d206661696c65640000000000000000000000000000006064820152608401610697565b6020808201516040808401516001600160a01b03166000908152606c909352822054612d1e9190613f37565b6040808401516001600160a01b039081166000908152606c60205291909120919091556101c083015116612d615760608201516001600160a01b03166101c08301525b6068546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015260740160408051601f19818403018152828252805160209182012060808601516101c087015160e08801519386018390526bffffffffffffffffffffffff19606092831b811695870195909552901b9092166054840152606883015291506000906088016040516020818303038152906040528051906020012090506000604051806101a00160405280856000015181526020018560200151815260200184815260200183815260200185604001516001600160a01b0316815260200146815260200185606001516001600160a01b0316815260200185610100015181526020018561012001516001600160a01b0316815260200185610140015181526020018561016001516001600160a01b031681526020018561018001518152602001856101a001518152509050600081604051602401612eca9190613d1c565b60408051601f19818403018152918152602080830180516001600160e01b03167fc29a91bc00000000000000000000000000000000000000000000000000000000179052815160a08101835260c08901516001600160a01b0390811682526060808b0151821683850152928a015182850152928901519092169082015290915060808101600190526000848152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180549485169190951690811785556080860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b90849081111561300c5761300c613fe5565b021790555050606880549150600061302383613f96565b9091555050606754608086015160a087015160e0880151604051633675e4e160e11b81526001600160a01b0390941693636cebc9c29361306c9387939192909190600401613cc0565b600060405180830381600087803b15801561308657600080fd5b505af115801561309a573d6000803e3d6000fd5b5050505050836101c001516001600160a01b03168460e001518560c001516001600160a01b03167f31325fe0a1a2e6a5b1e41572156ba5b4e94f0fae7e7f63ec21e9b5ce1e4b3eab86886060015189602001518a6040015160405161312494939291909384526001600160a01b039283166020850152604084019190915216606082015260800190565b60405180910390a46101e08401516040518481527f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f59060200160405180910390a25050919050565b600054610100900460ff166131d75760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610697565b6131df6131e7565b610f9e613252565b600054610100900460ff16610f9e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610697565b600054610100900460ff166132bd5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610697565b610f9e6132c8612535565b612b38565b8035611a0e8161402f565b600082601f8301126132e957600080fd5b8135602067ffffffffffffffff82111561330557613305613ffb565b8160051b613314828201613f06565b83815282810190868401838801850189101561332f57600080fd5b600093505b8584101561335b5780356133478161402f565b835260019390930192918401918401613334565b50979650505050505050565b600082601f83011261337857600080fd5b813567ffffffffffffffff81111561339257613392613ffb565b6133a56020601f19601f84011601613f06565b8181528460208386010111156133ba57600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156133e957600080fd5b81356133f48161402f565b9392505050565b60008060008060008060c0878903121561341457600080fd5b865161341f8161402f565b809650506020870151945060408701519350606087015160ff8116811461344557600080fd5b809350506080870151915060a087015190509295509295509295565b600080600080600060a0868803121561347957600080fd5b85356134848161402f565b945060208601356134948161402f565b935060408601356134a48161402f565b925060608601356134b48161402f565b915060808601356134c48161402f565b809150509295509295909350565b600080604083850312156134e557600080fd5b82356134f08161402f565b9150602083013561350081614044565b809150509250929050565b6000806040838503121561351e57600080fd5b82356135298161402f565b946020939093013593505050565b60006020828403121561354957600080fd5b81516133f481614044565b60006020828403121561356657600080fd5b5035919050565b60006020828403121561357f57600080fd5b813567ffffffffffffffff8082111561359757600080fd5b908301906101a082860312156135ac57600080fd5b6135b4613e94565b82358152602083013560208201526135ce604084016132cd565b60408201526135df606084016132cd565b60608201526135f0608084016132cd565b608082015260a083013560a082015260c083013560c082015261361560e084016132cd565b60e0820152610100808401358381111561362e57600080fd5b61363a88828701613367565b82840152505061012061364e8185016132cd565b908201526101406136608482016132cd565b90820152610160838101358381111561367857600080fd5b61368488828701613367565b91830191909152506101809283013592810192909252509392505050565b6000602082840312156136b457600080fd5b813567ffffffffffffffff808211156136cc57600080fd5b9083019061020082860312156136e157600080fd5b6136e9613ebe565b8235815260208301356020820152613703604084016132cd565b6040820152613714606084016132cd565b6060820152613725608084016132cd565b608082015261373660a084016132cd565b60a082015261374760c084016132cd565b60c082015260e083013560e0820152610100808401358381111561376a57600080fd5b613776888287016132d8565b82840152505061012061378a8185016132cd565b9082015261014083810135838111156137a257600080fd5b6137ae88828701613367565b8284015250506101606137c28185016132cd565b9082015261018083810135838111156137da57600080fd5b6137e688828701613367565b8284015250506101a0915081830135828201526101c091506138098284016132cd565b918101919091526101e091820135918101919091529392505050565b60006020828403121561383757600080fd5b813567ffffffffffffffff8082111561384f57600080fd5b90830190610140828603121561386457600080fd5b61386c613ee2565b8235815260208301358281111561388257600080fd5b61388e87828601613367565b6020830152506138a0604084016132cd565b6040820152606083013560608201526138bb608084016132cd565b60808201526138cc60a084016132cd565b60a08201526138dd60c084016132cd565b60c08201526138ee60e084016132cd565b60e082015261010083810135908201526101209283013592810192909252509392505050565b600080600080600080600060e0888a03121561392f57600080fd5b8735965060208801356139418161402f565b955060408801356139518161402f565b945060608801356139618161402f565b935060808801356139718161402f565b9699959850939692959460a0840135945060c09093013592915050565b60008060008060008060008060006101208a8c0312156139ad57600080fd5b8935985060208a01356139bf8161402f565b975060408a0135965060608a01356139d68161402f565b955060808a01356139e68161402f565b945060a08a01356139f68161402f565b935060c08a0135613a068161402f565b8093505060e08a013591506101008a013590509295985092959850929598565b60008060408385031215613a3957600080fd5b50508035926020909101359150565b60008060008060008060c08789031215613a6157600080fd5b86359550602087013594506040870135613a7a8161402f565b93506060870135613a8a8161402f565b9598949750929560808101359460a0909101359350915050565b60008060008060008060c08789031215613abd57600080fd5b8635955060208701359450604087013593506060870135613add8161402f565b92506080870135915060a0870135613af48161402f565b809150509295509295509295565b60008060008060008060008060006101208a8c031215613b2157600080fd5b8935985060208a0135975060408a0135965060608a0135613b418161402f565b955060808a0135945060a08a0135613b588161402f565b935060c08a0135613b688161402f565b925060e08a013567ffffffffffffffff811115613b8457600080fd5b613b908c828d01613367565b9250506101008a013590509295985092959850929598565b600081518084526020808501945080840160005b83811015613be15781516001600160a01b031687529582019590820190600101613bbc565b509495945050505050565b60008151808452613c04816020860160208601613f66565b601f01601f19169290920160200192915050565b60008251613c2a818460208701613f66565b9190910192915050565b6001600160a01b0386811682528581166020830152604082018590528316606082015260a08101613c6483614011565b8260808301529695505050505050565b60006001600160a01b038089168352876020840152808716604084015260c06060840152613ca560c0840187613bec565b60808401959095529290921660a09091015250949350505050565b608081526000613cd36080830187613bec565b6001600160a01b0395861660208401529390941660408201526060015292915050565b60208101613d0383614011565b91905290565b6020815260006133f46020830184613bec565b602081528151602082015260208201516040820152604082015160608201526060820151608082015260006080830151613d6160a08401826001600160a01b03169052565b5060a083015160c083015260c0830151613d8660e08401826001600160a01b03169052565b5060e08301516101a06101008181860152613da56101c0860184613ba8565b90860151909250610120613dc3868201836001600160a01b03169052565b80870151915050601f19610140818786030181880152613de38584613bec565b945080880151925050610160613e03818801846001600160a01b03169052565b80880151925050610180818786030181880152613e208584613bec565b970151959092019490945250929392505050565b87815286602082015260006001600160a01b03808816604084015260e06060840152613e6360e0840188613bec565b818716608085015281861660a085015283810360c0850152613e858186613bec565b9b9a5050505050505050505050565b6040516101a0810167ffffffffffffffff81118282101715613eb857613eb8613ffb565b60405290565b604051610200810167ffffffffffffffff81118282101715613eb857613eb8613ffb565b604051610140810167ffffffffffffffff81118282101715613eb857613eb8613ffb565b604051601f8201601f1916810167ffffffffffffffff81118282101715613f2f57613f2f613ffb565b604052919050565b60008219821115613f4a57613f4a613fcf565b500190565b600082821015613f6157613f61613fcf565b500390565b60005b83811015613f81578181015183820152602001613f69565b83811115613f90576000848401525b50505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613fc857613fc8613fcf565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60038110611c6757634e487b7160e01b600052602160045260246000fd5b6001600160a01b0381168114611c6757600080fd5b8015158114611c6757600080fdfe72657665727453796e74686573697a655265717565737442794272696467652875696e743235362c627974657333322c616464726573732c616464726573732c75696e743235362c616464726573732c62797465733332297265766572744275726e416e644275726e2875696e743235362c627974657333322c616464726573732c616464726573732c75696e743235362c61646472657373297265766572744d6574614275726e2875696e743235362c627974657333322c616464726573732c62797465732c616464726573732c616464726573732c6279746573296d696e7453796e746865746963546f6b656e2875696e743235362c627974657333322c627974657333322c616464726573732c75696e743235362c75696e743235362c6164647265737329a26469706673582212201ab6a8ee1ce7667753469f66994a0f7b890205298868366d5fc3b498a72165ee64736f6c63430008070033
Deployed ByteCode
0x6080604052600436106101cd5760003560e01c80638bb39802116100f7578063ce654c1711610095578063f2fde38b11610064578063f2fde38b146105bc578063fab92894146105dc578063fb7c7c2a14610619578063fce633c21461063957600080fd5b8063ce654c171461053c578063dbec15bb1461055c578063e78cea921461057c578063eadd5c341461059c57600080fd5b8063ac210cc7116100d1578063ac210cc7146104bc578063b1659a3c146104dc578063c23a4c88146104fc578063c42a28941461051c57600080fd5b80638bb39802146103fe5780638da5cb5b1461041e5780639d8669851461045057600080fd5b80635badbe4c1161016f578063715018a61161013e578063715018a614610384578063753d7563146103995780637c374f99146103c95780638456cb59146103e957600080fd5b80635badbe4c146102fa5780635c975abb14610310578063687752781461032a57806370a082311461035757600080fd5b80632816f4db116101ab5780632816f4db146102345780633f4ba83a1461025a578063486ff0cd1461026f578063572b6c05146102bb57600080fd5b806308759e9b146101d25780631459457a146101f45780631ebe53ef14610214575b600080fd5b3480156101de57600080fd5b506101f26101ed366004613a48565b610659565b005b34801561020057600080fd5b506101f261020f366004613461565b610908565b34801561022057600080fd5b506101f261022f366004613aa4565b610a8b565b610247610242366004613914565b610ca5565b6040519081526020015b60405180910390f35b34801561026657600080fd5b506101f2610e52565b34801561027b57600080fd5b50604080518082018252600581527f322e302e31000000000000000000000000000000000000000000000000000000602082015290516102519190613d09565b3480156102c757600080fd5b506102ea6102d63660046133d7565b6065546001600160a01b0391821691161490565b6040519015158152602001610251565b34801561030657600080fd5b5061024760685481565b34801561031c57600080fd5b506069546102ea9060ff1681565b34801561033657600080fd5b506102476103453660046133d7565b606d6020526000908152604090205481565b34801561036357600080fd5b506102476103723660046133d7565b606c6020526000908152604090205481565b34801561039057600080fd5b506101f2610f1b565b3480156103a557600080fd5b506102ea6103b43660046133d7565b606e6020526000908152604090205460ff1681565b3480156103d557600080fd5b506101f26103e43660046134d2565b610fa0565b3480156103f557600080fd5b506101f261107d565b34801561040a57600080fd5b506101f261041936600461350b565b61112c565b34801561042a57600080fd5b506033546001600160a01b03165b6040516001600160a01b039091168152602001610251565b34801561045c57600080fd5b506104ab61046b366004613554565b606a6020526000908152604090208054600182015460028301546003909301546001600160a01b039283169391831692811690600160a01b900460ff1685565b604051610251959493929190613c34565b3480156104c857600080fd5b50606654610438906001600160a01b031681565b3480156104e857600080fd5b506102476104f736600461398e565b6111f6565b34801561050857600080fd5b506101f2610517366004613b02565b61133d565b34801561052857600080fd5b506101f2610537366004613a26565b611646565b34801561054857600080fd5b506102476105573660046136a2565b6118c7565b34801561056857600080fd5b50606f54610438906001600160a01b031681565b34801561058857600080fd5b50606754610438906001600160a01b031681565b3480156105a857600080fd5b506101f26105b73660046133d7565b611a13565b3480156105c857600080fd5b506101f26105d73660046133d7565b611b69565b3480156105e857600080fd5b5061060c6105f7366004613554565b606b6020526000908152604090205460ff1681565b6040516102519190613cf6565b34801561062557600080fd5b50610247610634366004613825565b611c6a565b34801561064557600080fd5b506101f261065436600461356d565b611eb6565b60695460ff16156106a05760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064015b60405180910390fd5b600085306106ac612535565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff16600281111561072457610724613fe5565b141561077e5760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b6064820152608401610697565b6000818152606b6020908152604091829020805460ff1916600217905581518083018352601b81527f7265766572744275726e2875696e743235362c62797465733332290000000000908201528151602481018a90526044808201859052835180830390910181526064909101835290810180516001600160e01b03167ff70519ae000000000000000000000000000000000000000000000000000000001790526067549151633675e4e160e11b815290916001600160a01b031690636cebc9c2906108549084908a908a908a90600401613cc0565b600060405180830381600087803b15801561086e57600080fd5b505af1158015610882573d6000803e3d6000fd5b505050505061088f612535565b6001600160a01b0316867f40590cc12db0488520ce425059f83f8caed91bdf98de5ff829dc57c63843161b60405160405180910390a3817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f5876040516108f791815260200190565b60405180910390a250505050505050565b600054610100900460ff166109235760005460ff1615610927565b303b155b6109995760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610697565b600054610100900460ff161580156109d857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6109e18561257b565b606780546001600160a01b0380891673ffffffffffffffffffffffffffffffffffffffff199283161790925560668054878416908316179055606f80548584169216919091179055831615610a54576001600160a01b0383166000908152606e60205260409020805460ff191660011790555b8015610a8357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b505050505050565b6067546001600160a01b03163314610ae55760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f74207468652062726964676500006044820152606401610697565b60695460ff1615610b275760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6000858152606b602052604081205460ff166002811115610b4a57610b4a613fe5565b14610bbd5760405162461bcd60e51b815260206004820152602660248201527f53796d623a2073796e74686574696320746f6b656e7320656d657267656e637960448201527f556e6275726e00000000000000000000000000000000000000000000000000006064820152608401610697565b6001600160a01b0383166000908152606c6020526040902054610be1908390613f4f565b6001600160a01b0384166000908152606c6020908152604080832093909355878252606b905220805460ff19166001179055610c278382610c228986613f4f565b61261d565b606754610c3f9084906001600160a01b03168861261d565b6001600160a01b03811684867faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26610c768a87613f4f565b60408051918252602082018c90526001600160a01b0389169082015260600160405180910390a4505050505050565b60695460009060ff1615610cea5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6066546001600160a01b03166000908152606e602052604090205460ff16610d545760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e00000000000000006044820152606401610697565b6066546001600160a01b03166000908152606d6020526040902054341015610dbe5760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c64000000006044820152606401610697565b606660009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610e0e57600080fd5b505af1158015610e22573d6000803e3d6000fd5b5050606654610e4693508b92506001600160a01b03169050348a8a8a8a8a8a612777565b98975050505050505050565b610e5a612535565b6001600160a01b0316610e756033546001600160a01b031690565b6001600160a01b031614610ecb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6069805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610efe612535565b6040516001600160a01b03909116815260200160405180910390a1565b610f23612535565b6001600160a01b0316610f3e6033546001600160a01b031690565b6001600160a01b031614610f945760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b610f9e6000612b38565b565b610fa8612535565b6001600160a01b0316610fc36033546001600160a01b031690565b6001600160a01b0316146110195760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6001600160a01b0382166000818152606e6020908152604091829020805460ff19168515159081179091558251938452908301527f0a4552f1105808db6a44587c9ef0a7c4064bf620b9d843b514ad7365bd52239a91015b60405180910390a15050565b611085612535565b6001600160a01b03166110a06033546001600160a01b031690565b6001600160a01b0316146110f65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6069805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610efe612535565b611134612535565b6001600160a01b031661114f6033546001600160a01b031690565b6001600160a01b0316146111a55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6001600160a01b0382166000818152606d6020908152604091829020849055815192835282018390527fa6742efd4f410d6fd9688a6cf6a15b6d51121097a263056a3576baaacdc4a9ae9101611071565b60695460009060ff161561123b5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6001600160a01b0389166000908152606e602052604090205460ff166112a35760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e00000000000000006044820152606401610697565b6001600160a01b0389166000908152606d602052604090205488101561130b5760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c64000000006044820152606401610697565b61131e89611317612535565b308b612b97565b61132f8a8a8a8a8a8a8a8a8a612777565b9a9950505050505050505050565b6067546001600160a01b031633146113975760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f74207468652062726964676500006044820152606401610697565b60695460ff16156113d95760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6000878152606b602052604081205460ff1660028111156113fc576113fc613fe5565b1461146f5760405162461bcd60e51b815260206004820152602660248201527f53796d623a2073796e74686574696320746f6b656e7320656d657267656e637960448201527f556e6275726e00000000000000000000000000000000000000000000000000006064820152608401610697565b6001600160a01b0384166000908152606c6020526040902054611493908690613f4f565b6001600160a01b038581166000908152606c60209081526040808320949094558a8252606b905291909120805460ff191660011790556067546114d9918691168b61261d565b6114e38986613f4f565b945081516000141561154e576114fa84878761261d565b60408051868152602081018b90526001600160a01b03861681830152905130918a918a917faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26919081900360600190a461163b565b606f546115669085906001600160a01b03168761261d565b606f546040517ff5b697a50000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063f5b697a5906115b990879089908890889088908e90600401613c74565b600060405180830381600087803b1580156115d357600080fd5b505af11580156115e7573d6000803e3d6000fd5b505060408051888152602081018d90526001600160a01b0388168183015290513093508b92508a917faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26919081900360600190a45b505050505050505050565b6067546001600160a01b031633146116a05760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f74207468652062726964676500006044820152606401610697565b60695460ff16156116e25760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6000818152606a6020526040902060016003820154600160a01b900460ff16600281111561171257611712613fe5565b146117855760405162461bcd60e51b815260206004820152602960248201527f53796d623a207374617465206e6f74206f70656e206f7220747820646f65732060448201527f6e6f7420657869737400000000000000000000000000000000000000000000006064820152608401610697565b600381018054740200000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff82161790915560028201546001600160a01b039091166000908152606c60205260409020546117f19190613f4f565b6003820180546001600160a01b039081166000908152606c6020526040902092909255548254600284015461183493928316929190911690610c22908790613f4f565b6003810154606754611853916001600160a01b0390811691168561261d565b805460028201546001600160a01b039091169083907fefcdf9ea4e65571d2ce9c030c46954e950662df8a7d8bd039fc4417e37b2f88c90611895908790613f4f565b600385015460408051928352602083018990526001600160a01b039091169082015260600160405180910390a3505050565b60695460009060ff161561190c5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6040808301516001600160a01b03166000908152606e602052205460ff166119765760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e00000000000000006044820152606401610697565b6040808301516001600160a01b03166000908152606d6020908152919020549083015110156119e75760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c64000000006044820152606401610697565b611a0282604001516119f7612535565b308560200151612b97565b611a0b82612cf2565b90505b919050565b611a1b612535565b6001600160a01b0316611a366033546001600160a01b031690565b6001600160a01b031614611a8c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6001600160a01b038116611b085760405162461bcd60e51b815260206004820152602760248201527f53796d623a206d657461526f757465722063616e6e6f74206265207a65726f2060448201527f61646472657373000000000000000000000000000000000000000000000000006064820152608401610697565b606f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fd5c54ab1d37bfef4dd2253d9d73c292e46f5bd8a67ca5920aab4c2e1993178e79060200160405180910390a150565b611b71612535565b6001600160a01b0316611b8c6033546001600160a01b031690565b6001600160a01b031614611be25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610697565b6001600160a01b038116611c5e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610697565b611c6781612b38565b50565b60695460009060ff1615611caf5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b6040808301516001600160a01b03166000908152606e602052205460ff16611d195760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e00000000000000006044820152606401610697565b6040808301516001600160a01b03166000908152606d602052205460608301511015611d875760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c64000000006044820152606401610697565b6000806000806000808760200151806020019051810190611da891906133fb565b6040808f015190517fd505accf0000000000000000000000000000000000000000000000000000000081526001600160a01b038089166004830152306024830152604482018890526064820187905260ff8616608483015260a4820185905260c48201849052979d50959b5093995091975095509350919091169063d505accf9060e401600060405180830381600087803b158015611e4657600080fd5b505af1158015611e5a573d6000803e3d6000fd5b50505050505050505050611e7f8260400151611e74612535565b308560600151612b97565b611a0b82600001518360400151846060015185608001518660a001518760c001518860e001518961010001518a6101200151612777565b60695460ff1615611ef85760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b6044820152606401610697565b61010081015151156121a4576000816020015130611f14612535565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff166002811115611f8c57611f8c613fe5565b1415611fe65760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b6064820152608401610697565b6000818152606b60209081526040808320805460ff19166002179055805160808101909152604380825290916140ed90830139805190602001208360000151838560e001518661010001518761012001518861014001518961016001516040516024016120599796959493929190613e34565b60408051601f198184030181529181526020820180516001600160e01b03167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260675485830151606087015160a08801519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c2936120e6938793929091600401613cc0565b600060405180830381600087803b15801561210057600080fd5b505af1158015612114573d6000803e3d6000fd5b50505050612120612535565b6001600160a01b031683602001517f40590cc12db0488520ce425059f83f8caed91bdf98de5ff829dc57c63843161b60405160405180910390a38261018001517f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f5846020015160405161219591815260200190565b60405180910390a250506124f0565b61016081015151156123a95760008160200151306121c0612535565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff16600281111561223857612238613fe5565b14156122925760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b6064820152608401610697565b6000818152606b60209081526040808320805460ff19166002179055805160808101909152604280825290916140ab9083013980519060200120836000015183308660800151466122e1612535565b604051602481019690965260448601949094526001600160a01b039283166064860152908216608485015260a48401521660c482015260e40160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252606754610120860151606087015160a08801519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c2936120e6938793929091600401613cc0565b600060405180608001604052806058815260200161405360589139805190602001208260000151836020015184604001518560800151466123e8612535565b610180890151604051602481019790975260448701959095526001600160a01b039384166064870152918316608486015260a48501521660c483015260e48201526101040160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252606754610120850151606086015160a08701519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c2936124bc938793929091600401613cc0565b600060405180830381600087803b1580156124d657600080fd5b505af11580156124ea573d6000803e3d6000fd5b50505050505b6124f8612535565b6001600160a01b031681602001517fbd03c66ec5bd3d01fbf22bc794f68ac88b693023b438724019205a4b42aefb2060405160405180910390a350565b6065546000906001600160a01b031633141561257657507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b600054610100900460ff166125e65760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610697565b6125ee61316c565b6065805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b03167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916126929190613c18565b6000604051808303816000865af19150503d80600081146126cf576040519150601f19603f3d011682016040523d82523d6000602084013e6126d4565b606091505b50915091508180156126fe5750805115806126fe5750808060200190518101906126fe9190613537565b6127705760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c6564000000000000000000000000000000000000006064820152608401610697565b5050505050565b6001600160a01b0388166000908152606c602052604081205461279b908990613f37565b6001600160a01b03808b166000908152606c602052604090209190915584166127c2578693505b6068546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015260740160408051601f1981840301815282825280516020918201209083018190526bffffffffffffffffffffffff1960608a811b8216938501939093529187901b909116605483015260688201859052915060009060880160405160208183030381529060405280519060200120905060006040518060800160405280604b8152602001614130604b91398051602090910120604051602481018e905260448101849052606481018590526001600160a01b03808e1660848301524660a483015260c482018d90528b1660e48201526101040160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252815160a0810190925291508061291f612535565b6001600160a01b0390811682528b81166020830152604082018d90528d166060820152608001600190526000838152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180549485169190951690811785556080860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b908490811115612a0357612a03613fe5565b0217905550506068805491506000612a1a83613f96565b9091555050606754604051633675e4e160e11b81526001600160a01b0390911690636cebc9c290612a559084908c908c908b90600401613cc0565b600060405180830381600087803b158015612a6f57600080fd5b505af1158015612a83573d6000803e3d6000fd5b505050505050836001600160a01b031683612a9c612535565b604080518581526001600160a01b038c811660208301529181018d90528d821660608201529116907f31325fe0a1a2e6a5b1e41572156ba5b4e94f0fae7e7f63ec21e9b5ce1e4b3eab9060800160405180910390a4817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f582604051612b2391815260200190565b60405180910390a29998505050505050505050565b603380546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691612c149190613c18565b6000604051808303816000865af19150503d8060008114612c51576040519150601f19603f3d011682016040523d82523d6000602084013e612c56565b606091505b5091509150818015612c80575080511580612c80575080806020019051810190612c809190613537565b610a835760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a20747260448201527f616e7366657246726f6d206661696c65640000000000000000000000000000006064820152608401610697565b6020808201516040808401516001600160a01b03166000908152606c909352822054612d1e9190613f37565b6040808401516001600160a01b039081166000908152606c60205291909120919091556101c083015116612d615760608201516001600160a01b03166101c08301525b6068546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015260740160408051601f19818403018152828252805160209182012060808601516101c087015160e08801519386018390526bffffffffffffffffffffffff19606092831b811695870195909552901b9092166054840152606883015291506000906088016040516020818303038152906040528051906020012090506000604051806101a00160405280856000015181526020018560200151815260200184815260200183815260200185604001516001600160a01b0316815260200146815260200185606001516001600160a01b0316815260200185610100015181526020018561012001516001600160a01b0316815260200185610140015181526020018561016001516001600160a01b031681526020018561018001518152602001856101a001518152509050600081604051602401612eca9190613d1c565b60408051601f19818403018152918152602080830180516001600160e01b03167fc29a91bc00000000000000000000000000000000000000000000000000000000179052815160a08101835260c08901516001600160a01b0390811682526060808b0151821683850152928a015182850152928901519092169082015290915060808101600190526000848152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180549485169190951690811785556080860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b90849081111561300c5761300c613fe5565b021790555050606880549150600061302383613f96565b9091555050606754608086015160a087015160e0880151604051633675e4e160e11b81526001600160a01b0390941693636cebc9c29361306c9387939192909190600401613cc0565b600060405180830381600087803b15801561308657600080fd5b505af115801561309a573d6000803e3d6000fd5b5050505050836101c001516001600160a01b03168460e001518560c001516001600160a01b03167f31325fe0a1a2e6a5b1e41572156ba5b4e94f0fae7e7f63ec21e9b5ce1e4b3eab86886060015189602001518a6040015160405161312494939291909384526001600160a01b039283166020850152604084019190915216606082015260800190565b60405180910390a46101e08401516040518481527f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f59060200160405180910390a25050919050565b600054610100900460ff166131d75760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610697565b6131df6131e7565b610f9e613252565b600054610100900460ff16610f9e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610697565b600054610100900460ff166132bd5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610697565b610f9e6132c8612535565b612b38565b8035611a0e8161402f565b600082601f8301126132e957600080fd5b8135602067ffffffffffffffff82111561330557613305613ffb565b8160051b613314828201613f06565b83815282810190868401838801850189101561332f57600080fd5b600093505b8584101561335b5780356133478161402f565b835260019390930192918401918401613334565b50979650505050505050565b600082601f83011261337857600080fd5b813567ffffffffffffffff81111561339257613392613ffb565b6133a56020601f19601f84011601613f06565b8181528460208386010111156133ba57600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156133e957600080fd5b81356133f48161402f565b9392505050565b60008060008060008060c0878903121561341457600080fd5b865161341f8161402f565b809650506020870151945060408701519350606087015160ff8116811461344557600080fd5b809350506080870151915060a087015190509295509295509295565b600080600080600060a0868803121561347957600080fd5b85356134848161402f565b945060208601356134948161402f565b935060408601356134a48161402f565b925060608601356134b48161402f565b915060808601356134c48161402f565b809150509295509295909350565b600080604083850312156134e557600080fd5b82356134f08161402f565b9150602083013561350081614044565b809150509250929050565b6000806040838503121561351e57600080fd5b82356135298161402f565b946020939093013593505050565b60006020828403121561354957600080fd5b81516133f481614044565b60006020828403121561356657600080fd5b5035919050565b60006020828403121561357f57600080fd5b813567ffffffffffffffff8082111561359757600080fd5b908301906101a082860312156135ac57600080fd5b6135b4613e94565b82358152602083013560208201526135ce604084016132cd565b60408201526135df606084016132cd565b60608201526135f0608084016132cd565b608082015260a083013560a082015260c083013560c082015261361560e084016132cd565b60e0820152610100808401358381111561362e57600080fd5b61363a88828701613367565b82840152505061012061364e8185016132cd565b908201526101406136608482016132cd565b90820152610160838101358381111561367857600080fd5b61368488828701613367565b91830191909152506101809283013592810192909252509392505050565b6000602082840312156136b457600080fd5b813567ffffffffffffffff808211156136cc57600080fd5b9083019061020082860312156136e157600080fd5b6136e9613ebe565b8235815260208301356020820152613703604084016132cd565b6040820152613714606084016132cd565b6060820152613725608084016132cd565b608082015261373660a084016132cd565b60a082015261374760c084016132cd565b60c082015260e083013560e0820152610100808401358381111561376a57600080fd5b613776888287016132d8565b82840152505061012061378a8185016132cd565b9082015261014083810135838111156137a257600080fd5b6137ae88828701613367565b8284015250506101606137c28185016132cd565b9082015261018083810135838111156137da57600080fd5b6137e688828701613367565b8284015250506101a0915081830135828201526101c091506138098284016132cd565b918101919091526101e091820135918101919091529392505050565b60006020828403121561383757600080fd5b813567ffffffffffffffff8082111561384f57600080fd5b90830190610140828603121561386457600080fd5b61386c613ee2565b8235815260208301358281111561388257600080fd5b61388e87828601613367565b6020830152506138a0604084016132cd565b6040820152606083013560608201526138bb608084016132cd565b60808201526138cc60a084016132cd565b60a08201526138dd60c084016132cd565b60c08201526138ee60e084016132cd565b60e082015261010083810135908201526101209283013592810192909252509392505050565b600080600080600080600060e0888a03121561392f57600080fd5b8735965060208801356139418161402f565b955060408801356139518161402f565b945060608801356139618161402f565b935060808801356139718161402f565b9699959850939692959460a0840135945060c09093013592915050565b60008060008060008060008060006101208a8c0312156139ad57600080fd5b8935985060208a01356139bf8161402f565b975060408a0135965060608a01356139d68161402f565b955060808a01356139e68161402f565b945060a08a01356139f68161402f565b935060c08a0135613a068161402f565b8093505060e08a013591506101008a013590509295985092959850929598565b60008060408385031215613a3957600080fd5b50508035926020909101359150565b60008060008060008060c08789031215613a6157600080fd5b86359550602087013594506040870135613a7a8161402f565b93506060870135613a8a8161402f565b9598949750929560808101359460a0909101359350915050565b60008060008060008060c08789031215613abd57600080fd5b8635955060208701359450604087013593506060870135613add8161402f565b92506080870135915060a0870135613af48161402f565b809150509295509295509295565b60008060008060008060008060006101208a8c031215613b2157600080fd5b8935985060208a0135975060408a0135965060608a0135613b418161402f565b955060808a0135945060a08a0135613b588161402f565b935060c08a0135613b688161402f565b925060e08a013567ffffffffffffffff811115613b8457600080fd5b613b908c828d01613367565b9250506101008a013590509295985092959850929598565b600081518084526020808501945080840160005b83811015613be15781516001600160a01b031687529582019590820190600101613bbc565b509495945050505050565b60008151808452613c04816020860160208601613f66565b601f01601f19169290920160200192915050565b60008251613c2a818460208701613f66565b9190910192915050565b6001600160a01b0386811682528581166020830152604082018590528316606082015260a08101613c6483614011565b8260808301529695505050505050565b60006001600160a01b038089168352876020840152808716604084015260c06060840152613ca560c0840187613bec565b60808401959095529290921660a09091015250949350505050565b608081526000613cd36080830187613bec565b6001600160a01b0395861660208401529390941660408201526060015292915050565b60208101613d0383614011565b91905290565b6020815260006133f46020830184613bec565b602081528151602082015260208201516040820152604082015160608201526060820151608082015260006080830151613d6160a08401826001600160a01b03169052565b5060a083015160c083015260c0830151613d8660e08401826001600160a01b03169052565b5060e08301516101a06101008181860152613da56101c0860184613ba8565b90860151909250610120613dc3868201836001600160a01b03169052565b80870151915050601f19610140818786030181880152613de38584613bec565b945080880151925050610160613e03818801846001600160a01b03169052565b80880151925050610180818786030181880152613e208584613bec565b970151959092019490945250929392505050565b87815286602082015260006001600160a01b03808816604084015260e06060840152613e6360e0840188613bec565b818716608085015281861660a085015283810360c0850152613e858186613bec565b9b9a5050505050505050505050565b6040516101a0810167ffffffffffffffff81118282101715613eb857613eb8613ffb565b60405290565b604051610200810167ffffffffffffffff81118282101715613eb857613eb8613ffb565b604051610140810167ffffffffffffffff81118282101715613eb857613eb8613ffb565b604051601f8201601f1916810167ffffffffffffffff81118282101715613f2f57613f2f613ffb565b604052919050565b60008219821115613f4a57613f4a613fcf565b500190565b600082821015613f6157613f61613fcf565b500390565b60005b83811015613f81578181015183820152602001613f69565b83811115613f90576000848401525b50505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613fc857613fc8613fcf565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60038110611c6757634e487b7160e01b600052602160045260246000fd5b6001600160a01b0381168114611c6757600080fd5b8015158114611c6757600080fdfe72657665727453796e74686573697a655265717565737442794272696467652875696e743235362c627974657333322c616464726573732c616464726573732c75696e743235362c616464726573732c62797465733332297265766572744275726e416e644275726e2875696e743235362c627974657333322c616464726573732c616464726573732c75696e743235362c61646472657373297265766572744d6574614275726e2875696e743235362c627974657333322c616464726573732c62797465732c616464726573732c616464726573732c6279746573296d696e7453796e746865746963546f6b656e2875696e743235362c627974657333322c627974657333322c616464726573732c75696e743235362c75696e743235362c6164647265737329a26469706673582212201ab6a8ee1ce7667753469f66994a0f7b890205298868366d5fc3b498a72165ee64736f6c63430008070033