Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Portal
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 2000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// 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 "@openzeppelin/contracts/token/ERC20/IERC20.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);
event SetWrapper(address wrapper);
event SetBalanceOf(address[] tokens);
/// ** 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);
}
function setWrapper(address _wrapper) external onlyOwner {
wrapper = _wrapper;
emit SetWrapper(_wrapper);
}
function setBalanceOf(address[] memory _tokens) external onlyOwner {
for (uint256 i = 0; i < _tokens.length; i++) {
require(tokenWhitelist[_tokens[i]], "Symb: unauthorized token");
balanceOf[_tokens[i]] = IERC20(_tokens[i]).balanceOf(address(this));
}
emit SetBalanceOf(_tokens);
}
/**
* @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);
}
}// 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;
}// 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));
}
}// 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);
}
}
}
}// 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;
}// 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);
}
}// 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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// 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;
}
}// 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');
}
}// 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;
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
interface IWrapper {
function deposit() external payable;
function withdraw(uint256 amount) external;
}// 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;
}// 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;
}
}// 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();
}
}
}{
"optimizer": {
"enabled": true,
"runs": 2000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"crossChainID","type":"bytes32"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bridgingFee","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"BurnCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"clientId","type":"bytes32"}],"name":"ClientIdLog","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"MetaRevertRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"RevertBurnRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bridgingFee","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"RevertSynthesizeCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"SetBalanceOf","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"metaRouter","type":"address"}],"name":"SetMetaRouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"SetTokenThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"bool","name":"activate","type":"bool"}],"name":"SetWhitelistToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"wrapper","type":"address"}],"name":"SetWrapper","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"chainID","type":"uint256"},{"indexed":true,"internalType":"address","name":"revertableAddress","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"SynthesizeRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_bridge","type":"address"},{"internalType":"address","name":"_trustedForwarder","type":"address"},{"internalType":"address","name":"_wrapper","type":"address"},{"internalType":"address","name":"_whitelistedToken","type":"address"},{"internalType":"contract IMetaRouter","name":"_metaRouter","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"stableBridgingFee","type":"uint256"},{"internalType":"bytes32","name":"internalID","type":"bytes32"},{"internalType":"address","name":"receiveSide","type":"address"},{"internalType":"address","name":"managerChainBridge","type":"address"},{"internalType":"address","name":"sourceChainBridge","type":"address"},{"internalType":"uint256","name":"managerChainId","type":"uint256"},{"internalType":"uint256","name":"sourceChainId","type":"uint256"},{"internalType":"address","name":"router","type":"address"},{"internalType":"bytes","name":"swapCalldata","type":"bytes"},{"internalType":"address","name":"sourceChainSynthesis","type":"address"},{"internalType":"address","name":"burnToken","type":"address"},{"internalType":"bytes","name":"burnCalldata","type":"bytes"},{"internalType":"bytes32","name":"clientID","type":"bytes32"}],"internalType":"struct MetaRouteStructs.MetaRevertTransaction","name":"_metaRevertTransaction","type":"tuple"}],"name":"metaRevertRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"metaRouter","outputs":[{"internalType":"contract IMetaRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"stableBridgingFee","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"rtoken","type":"address"},{"internalType":"address","name":"chain2address","type":"address"},{"internalType":"address","name":"receiveSide","type":"address"},{"internalType":"address","name":"oppositeBridge","type":"address"},{"internalType":"address","name":"syntCaller","type":"address"},{"internalType":"uint256","name":"chainID","type":"uint256"},{"internalType":"address[]","name":"swapTokens","type":"address[]"},{"internalType":"address","name":"secondDexRouter","type":"address"},{"internalType":"bytes","name":"secondSwapCalldata","type":"bytes"},{"internalType":"address","name":"finalReceiveSide","type":"address"},{"internalType":"bytes","name":"finalCalldata","type":"bytes"},{"internalType":"uint256","name":"finalOffset","type":"uint256"},{"internalType":"address","name":"revertableAddress","type":"address"},{"internalType":"bytes32","name":"clientID","type":"bytes32"}],"internalType":"struct MetaRouteStructs.MetaSynthesizeTransaction","name":"_metaSynthesizeTransaction","type":"tuple"}],"name":"metaSynthesize","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stableBridgingFee","type":"uint256"},{"internalType":"bytes32","name":"_crossChainID","type":"bytes32"},{"internalType":"bytes32","name":"_externalID","type":"bytes32"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_rToken","type":"address"},{"internalType":"address","name":"_finalReceiveSide","type":"address"},{"internalType":"bytes","name":"_finalCalldata","type":"bytes"},{"internalType":"uint256","name":"_finalOffset","type":"uint256"}],"name":"metaUnsynthesize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requests","outputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"chain2address","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"rtoken","type":"address"},{"internalType":"enum Portal.RequestState","name":"state","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stableBridgingFee","type":"uint256"},{"internalType":"bytes32","name":"_internalID","type":"bytes32"},{"internalType":"address","name":"_receiveSide","type":"address"},{"internalType":"address","name":"_oppositeBridge","type":"address"},{"internalType":"uint256","name":"_chainId","type":"uint256"},{"internalType":"bytes32","name":"_clientID","type":"bytes32"}],"name":"revertBurnRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stableBridgingFee","type":"uint256"},{"internalType":"bytes32","name":"_externalID","type":"bytes32"}],"name":"revertSynthesize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"setBalanceOf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IMetaRouter","name":"_metaRouter","type":"address"}],"name":"setMetaRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_threshold","type":"uint256"}],"name":"setTokenThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"bool","name":"_activate","type":"bool"}],"name":"setWhitelistToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wrapper","type":"address"}],"name":"setWrapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stableBridgingFee","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_chain2address","type":"address"},{"internalType":"address","name":"_receiveSide","type":"address"},{"internalType":"address","name":"_oppositeBridge","type":"address"},{"internalType":"address","name":"_revertableAddress","type":"address"},{"internalType":"uint256","name":"_chainID","type":"uint256"},{"internalType":"bytes32","name":"_clientID","type":"bytes32"}],"name":"synthesize","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stableBridgingFee","type":"uint256"},{"internalType":"bytes32","name":"_externalID","type":"bytes32"},{"internalType":"bytes32","name":"_crossChainID","type":"bytes32"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"unsynthesize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"unsynthesizeStates","outputs":[{"internalType":"enum Portal.UnsynthesizeState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"versionRecipient","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"wrapper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50613dcb806100206000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80638bb3980211610104578063c42a2894116100a2578063eadd5c3411610071578063eadd5c3414610488578063f2fde38b1461049b578063fab92894146104ae578063fce633c2146104de57600080fd5b8063c42a28941461043c578063ce654c171461044f578063dbec15bb14610462578063e78cea921461047557600080fd5b8063ac210cc7116100de578063ac210cc7146103f0578063b1659a3c14610403578063c2167d9314610416578063c23a4c881461042957600080fd5b80638bb39802146103595780638da5cb5b1461036c5780639d8669851461039157600080fd5b80635badbe4c1161017c578063715018a61161014b578063715018a614610313578063753d75631461031b5780637c374f991461033e5780638456cb591461035157600080fd5b80635badbe4c146102af5780635c975abb146102c657806368775278146102d357806370a08231146102f357600080fd5b80633f4ba83a116101b85780633f4ba83a1461021a578063486ff0cd146102225780634a9136641461026a578063572b6c051461027d57600080fd5b806308759e9b146101df5780631459457a146101f45780631ebe53ef14610207575b600080fd5b6101f26101ed366004613092565b6104f1565b005b6101f26102023660046130ee565b61079f565b6101f261021536600461315f565b610922565b6101f2610b3c565b604080518082018252600581527f322e302e3100000000000000000000000000000000000000000000000000000060208201529051610261919061320d565b60405180910390f35b6101f2610278366004613345565b610c05565b61029f61028b366004613382565b6065546001600160a01b0391821691161490565b6040519015158152602001610261565b6102b860685481565b604051908152602001610261565b60695461029f9060ff1681565b6102b86102e1366004613382565b606d6020526000908152604090205481565b6102b8610301366004613382565b606c6020526000908152604090205481565b6101f2610e42565b61029f610329366004613382565b606e6020526000908152604090205460ff1681565b6101f261034c3660046133ad565b610ec7565b6101f2610fa4565b6101f26103673660046133e6565b611053565b6033546001600160a01b03165b6040516001600160a01b039091168152602001610261565b6103df61039f366004613412565b606a6020526000908152604090208054600182015460028301546003909301546001600160a01b039283169391831692811690600160a01b900460ff1685565b60405161026195949392919061345f565b606654610379906001600160a01b031681565b6102b861041136600461349f565b61111d565b6101f2610424366004613382565b611264565b6101f26104373660046135a7565b611338565b6101f261044a36600461364d565b611640565b6102b861045d36600461366f565b6118c1565b606f54610379906001600160a01b031681565b606754610379906001600160a01b031681565b6101f2610496366004613382565b611a0d565b6101f26104a9366004613382565b611b5d565b6104d16104bc366004613412565b606b6020526000908152604090205460ff1681565b60405161026191906137f2565b6101f26104ec366004613805565b611c5e565b60695460ff16156105385760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064015b60405180910390fd5b600085306105446122db565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff1660028111156105bc576105bc61342b565b036106155760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b606482015260840161052f565b6000818152606b6020908152604091829020805460ff1916600217905581518083018352601b81527f7265766572744275726e2875696e743235362c62797465733332290000000000908201528151602481018a90526044808201859052835180830390910181526064909101835290810180516001600160e01b03167ff70519ae000000000000000000000000000000000000000000000000000000001790526067549151633675e4e160e11b815290916001600160a01b031690636cebc9c2906106eb9084908a908a908a9060040161393a565b600060405180830381600087803b15801561070557600080fd5b505af1158015610719573d6000803e3d6000fd5b50505050506107266122db565b6001600160a01b0316867f40590cc12db0488520ce425059f83f8caed91bdf98de5ff829dc57c63843161b60405160405180910390a3817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f58760405161078e91815260200190565b60405180910390a250505050505050565b600054610100900460ff166107ba5760005460ff16156107be565b303b155b6108305760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161052f565b600054610100900460ff1615801561086f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61087885612320565b606780546001600160a01b0380891673ffffffffffffffffffffffffffffffffffffffff199283161790925560668054878416908316179055606f805485841692169190911790558316156108eb576001600160a01b0383166000908152606e60205260409020805460ff191660011790555b801561091a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b505050505050565b6067546001600160a01b0316331461097c5760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f7420746865206272696467650000604482015260640161052f565b60695460ff16156109be5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6000858152606b602052604081205460ff1660028111156109e1576109e161342b565b14610a545760405162461bcd60e51b815260206004820152602660248201527f53796d623a2073796e74686574696320746f6b656e7320656d657267656e637960448201527f556e6275726e0000000000000000000000000000000000000000000000000000606482015260840161052f565b6001600160a01b0383166000908152606c6020526040902054610a78908390613986565b6001600160a01b0384166000908152606c6020908152604080832093909355878252606b905220805460ff19166001179055610abe8382610ab98986613986565b6123c2565b606754610ad69084906001600160a01b0316886123c2565b6001600160a01b03811684867faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26610b0d8a87613986565b60408051918252602082018c90526001600160a01b0389169082015260600160405180910390a4505050505050565b610b446122db565b6001600160a01b0316610b5f6033546001600160a01b031690565b6001600160a01b031614610bb55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6069805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610be86122db565b6040516001600160a01b03909116815260200160405180910390a1565b610c0d6122db565b6001600160a01b0316610c286033546001600160a01b031690565b6001600160a01b031614610c7e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b60005b8151811015610e0757606e6000838381518110610ca057610ca061399f565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16610d135760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e0000000000000000604482015260640161052f565b818181518110610d2557610d2561399f565b60209081029190910101516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610d8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db291906139b5565b606c6000848481518110610dc857610dc861399f565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080610dff906139ce565b915050610c81565b507f5a980ed3bb4dd09162988674fd35c7002fa70e44dd03d2942ac38c074b1a638e81604051610e379190613a4a565b60405180910390a150565b610e4a6122db565b6001600160a01b0316610e656033546001600160a01b031690565b6001600160a01b031614610ebb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b610ec5600061251c565b565b610ecf6122db565b6001600160a01b0316610eea6033546001600160a01b031690565b6001600160a01b031614610f405760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6001600160a01b0382166000818152606e6020908152604091829020805460ff19168515159081179091558251938452908301527f0a4552f1105808db6a44587c9ef0a7c4064bf620b9d843b514ad7365bd52239a91015b60405180910390a15050565b610fac6122db565b6001600160a01b0316610fc76033546001600160a01b031690565b6001600160a01b03161461101d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6069805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610be86122db565b61105b6122db565b6001600160a01b03166110766033546001600160a01b031690565b6001600160a01b0316146110cc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6001600160a01b0382166000818152606d6020908152604091829020849055815192835282018390527fa6742efd4f410d6fd9688a6cf6a15b6d51121097a263056a3576baaacdc4a9ae9101610f98565b60695460009060ff16156111625760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6001600160a01b0389166000908152606e602052604090205460ff166111ca5760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e0000000000000000604482015260640161052f565b6001600160a01b0389166000908152606d60205260409020548810156112325760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c6400000000604482015260640161052f565b6112458961123e6122db565b308b61257b565b6112568a8a8a8a8a8a8a8a8a6126d6565b9a9950505050505050505050565b61126c6122db565b6001600160a01b03166112876033546001600160a01b031690565b6001600160a01b0316146112dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6066805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fce42f6a6b3d7a9e5602623686f752d848285a87b22f0168a666c9c6064d2d23090602001610e37565b6067546001600160a01b031633146113925760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f7420746865206272696467650000604482015260640161052f565b60695460ff16156113d45760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6000878152606b602052604081205460ff1660028111156113f7576113f761342b565b1461146a5760405162461bcd60e51b815260206004820152602660248201527f53796d623a2073796e74686574696320746f6b656e7320656d657267656e637960448201527f556e6275726e0000000000000000000000000000000000000000000000000000606482015260840161052f565b6001600160a01b0384166000908152606c602052604090205461148e908690613986565b6001600160a01b038581166000908152606c60209081526040808320949094558a8252606b905291909120805460ff191660011790556067546114d4918691168b6123c2565b6114de8986613986565b94508151600003611548576114f48487876123c2565b60408051868152602081018b90526001600160a01b03861681830152905130918a918a917faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26919081900360600190a4611635565b606f546115609085906001600160a01b0316876123c2565b606f546040517ff5b697a50000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063f5b697a5906115b390879089908890889088908e90600401613a5d565b600060405180830381600087803b1580156115cd57600080fd5b505af11580156115e1573d6000803e3d6000fd5b505060408051888152602081018d90526001600160a01b0388168183015290513093508b92508a917faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26919081900360600190a45b505050505050505050565b6067546001600160a01b0316331461169a5760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f7420746865206272696467650000604482015260640161052f565b60695460ff16156116dc5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6000818152606a6020526040902060016003820154600160a01b900460ff16600281111561170c5761170c61342b565b1461177f5760405162461bcd60e51b815260206004820152602960248201527f53796d623a207374617465206e6f74206f70656e206f7220747820646f65732060448201527f6e6f742065786973740000000000000000000000000000000000000000000000606482015260840161052f565b600381018054740200000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff82161790915560028201546001600160a01b039091166000908152606c60205260409020546117eb9190613986565b6003820180546001600160a01b039081166000908152606c6020526040902092909255548254600284015461182e93928316929190911690610ab9908790613986565b600381015460675461184d916001600160a01b039081169116856123c2565b805460028201546001600160a01b039091169083907fefcdf9ea4e65571d2ce9c030c46954e950662df8a7d8bd039fc4417e37b2f88c9061188f908790613986565b600385015460408051928352602083018990526001600160a01b039091169082015260600160405180910390a3505050565b60695460009060ff16156119065760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6040808301516001600160a01b03166000908152606e602052205460ff166119705760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e0000000000000000604482015260640161052f565b6040808301516001600160a01b03166000908152606d6020908152919020549083015110156119e15760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c6400000000604482015260640161052f565b6119fc82604001516119f16122db565b30856020015161257b565b611a0582612a97565b90505b919050565b611a156122db565b6001600160a01b0316611a306033546001600160a01b031690565b6001600160a01b031614611a865760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6001600160a01b038116611b025760405162461bcd60e51b815260206004820152602760248201527f53796d623a206d657461526f757465722063616e6e6f74206265207a65726f2060448201527f6164647265737300000000000000000000000000000000000000000000000000606482015260840161052f565b606f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fd5c54ab1d37bfef4dd2253d9d73c292e46f5bd8a67ca5920aab4c2e1993178e790602001610e37565b611b656122db565b6001600160a01b0316611b806033546001600160a01b031690565b6001600160a01b031614611bd65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6001600160a01b038116611c525760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161052f565b611c5b8161251c565b50565b60695460ff1615611ca05760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6101008101515115611f4b576000816020015130611cbc6122db565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff166002811115611d3457611d3461342b565b03611d8d5760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b606482015260840161052f565b6000818152606b60209081526040808320805460ff1916600217905580516080810190915260438082529091613d0890830139805190602001208360000151838560e00151866101000151876101200151886101400151896101600151604051602401611e009796959493929190613aa9565b60408051601f198184030181529181526020820180516001600160e01b03167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260675485830151606087015160a08801519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c293611e8d93879392909160040161393a565b600060405180830381600087803b158015611ea757600080fd5b505af1158015611ebb573d6000803e3d6000fd5b50505050611ec76122db565b6001600160a01b031683602001517f40590cc12db0488520ce425059f83f8caed91bdf98de5ff829dc57c63843161b60405160405180910390a38261018001517f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f58460200151604051611f3c91815260200190565b60405180910390a25050612296565b610160810151511561214f576000816020015130611f676122db565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff166002811115611fdf57611fdf61342b565b036120385760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b606482015260840161052f565b6000818152606b60209081526040808320805460ff1916600217905580516080810190915260428082529091613cc69083013980519060200120836000015183308660800151466120876122db565b604051602481019690965260448601949094526001600160a01b039283166064860152908216608485015260a48401521660c482015260e40160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252606754610120860151606087015160a08801519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c293611e8d93879392909160040161393a565b6000604051806080016040528060588152602001613c6e605891398051906020012082600001518360200151846040015185608001514661218e6122db565b610180890151604051602481019790975260448701959095526001600160a01b039384166064870152918316608486015260a48501521660c483015260e48201526101040160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252606754610120850151606086015160a08701519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c29361226293879392909160040161393a565b600060405180830381600087803b15801561227c57600080fd5b505af1158015612290573d6000803e3d6000fd5b50505050505b61229e6122db565b6001600160a01b031681602001517fbd03c66ec5bd3d01fbf22bc794f68ac88b693023b438724019205a4b42aefb2060405160405180910390a350565b6065546000906001600160a01b0316330361231b57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b600054610100900460ff1661238b5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161052f565b612393612f11565b6065805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b03167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916124379190613b09565b6000604051808303816000865af19150503d8060008114612474576040519150601f19603f3d011682016040523d82523d6000602084013e612479565b606091505b50915091508180156124a35750805115806124a35750808060200190518101906124a39190613b25565b6125155760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c656400000000000000000000000000000000000000606482015260840161052f565b5050505050565b603380546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000928392908816916125f89190613b09565b6000604051808303816000865af19150503d8060008114612635576040519150601f19603f3d011682016040523d82523d6000602084013e61263a565b606091505b50915091508180156126645750805115806126645750808060200190518101906126649190613b25565b61091a5760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a20747260448201527f616e7366657246726f6d206661696c6564000000000000000000000000000000606482015260840161052f565b6001600160a01b0388166000908152606c60205260408120546126fa908990613b42565b6001600160a01b03808b166000908152606c60205260409020919091558416612721578693505b6068546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015260740160408051601f1981840301815282825280516020918201209083018190526bffffffffffffffffffffffff1960608a811b8216938501939093529187901b909116605483015260688201859052915060009060880160405160208183030381529060405280519060200120905060006040518060800160405280604b8152602001613d4b604b91398051602090910120604051602481018e905260448101849052606481018590526001600160a01b03808e1660848301524660a483015260c482018d90528b1660e48201526101040160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252815160a0810190925291508061287e6122db565b6001600160a01b0390811682528b81166020830152604082018d90528d166060820152608001600190526000838152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180549485169190951690811785556080860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b9084908111156129625761296261342b565b0217905550506068805491506000612979836139ce565b9091555050606754604051633675e4e160e11b81526001600160a01b0390911690636cebc9c2906129b49084908c908c908b9060040161393a565b600060405180830381600087803b1580156129ce57600080fd5b505af11580156129e2573d6000803e3d6000fd5b505050505050836001600160a01b0316836129fb6122db565b604080518581526001600160a01b038c811660208301529181018d90528d821660608201529116907f31325fe0a1a2e6a5b1e41572156ba5b4e94f0fae7e7f63ec21e9b5ce1e4b3eab9060800160405180910390a4817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f582604051612a8291815260200190565b60405180910390a29998505050505050505050565b6020808201516040808401516001600160a01b03166000908152606c909352822054612ac39190613b42565b6040808401516001600160a01b039081166000908152606c60205291909120919091556101c083015116612b065760608201516001600160a01b03166101c08301525b6068546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015260740160408051601f19818403018152828252805160209182012060808601516101c087015160e08801519386018390526bffffffffffffffffffffffff19606092831b811695870195909552901b9092166054840152606883015291506000906088016040516020818303038152906040528051906020012090506000604051806101a00160405280856000015181526020018560200151815260200184815260200183815260200185604001516001600160a01b0316815260200146815260200185606001516001600160a01b0316815260200185610100015181526020018561012001516001600160a01b0316815260200185610140015181526020018561016001516001600160a01b031681526020018561018001518152602001856101a001518152509050600081604051602401612c6f9190613b55565b60408051601f19818403018152918152602080830180516001600160e01b03167fc29a91bc00000000000000000000000000000000000000000000000000000000179052815160a08101835260c08901516001600160a01b0390811682526060808b0151821683850152928a015182850152928901519092169082015290915060808101600190526000848152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180549485169190951690811785556080860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b908490811115612db157612db161342b565b0217905550506068805491506000612dc8836139ce565b9091555050606754608086015160a087015160e0880151604051633675e4e160e11b81526001600160a01b0390941693636cebc9c293612e11938793919290919060040161393a565b600060405180830381600087803b158015612e2b57600080fd5b505af1158015612e3f573d6000803e3d6000fd5b5050505050836101c001516001600160a01b03168460e001518560c001516001600160a01b03167f31325fe0a1a2e6a5b1e41572156ba5b4e94f0fae7e7f63ec21e9b5ce1e4b3eab86886060015189602001518a60400151604051612ec994939291909384526001600160a01b039283166020850152604084019190915216606082015260800190565b60405180910390a46101e08401516040518481527f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f59060200160405180910390a25050919050565b600054610100900460ff16612f7c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161052f565b612f84612f8c565b610ec5612ff7565b600054610100900460ff16610ec55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161052f565b600054610100900460ff166130625760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161052f565b610ec561306d6122db565b61251c565b6001600160a01b0381168114611c5b57600080fd5b8035611a0881613072565b60008060008060008060c087890312156130ab57600080fd5b863595506020870135945060408701356130c481613072565b935060608701356130d481613072565b9598949750929560808101359460a0909101359350915050565b600080600080600060a0868803121561310657600080fd5b853561311181613072565b9450602086013561312181613072565b9350604086013561313181613072565b9250606086013561314181613072565b9150608086013561315181613072565b809150509295509295909350565b60008060008060008060c0878903121561317857600080fd5b863595506020870135945060408701359350606087013561319881613072565b92506080870135915060a08701356131af81613072565b809150509295509295509295565b60005b838110156131d85781810151838201526020016131c0565b50506000910152565b600081518084526131f98160208601602086016131bd565b601f01601f19169290920160200192915050565b60208152600061322060208301846131e1565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051610200810167ffffffffffffffff8111828210171561326157613261613227565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561326157613261613227565b604051601f8201601f1916810167ffffffffffffffff811182821017156132b4576132b4613227565b604052919050565b600082601f8301126132cd57600080fd5b8135602067ffffffffffffffff8211156132e9576132e9613227565b8160051b6132f882820161328b565b928352848101820192828101908785111561331257600080fd5b83870192505b8483101561333a57823561332b81613072565b82529183019190830190613318565b979650505050505050565b60006020828403121561335757600080fd5b813567ffffffffffffffff81111561336e57600080fd5b61337a848285016132bc565b949350505050565b60006020828403121561339457600080fd5b813561322081613072565b8015158114611c5b57600080fd5b600080604083850312156133c057600080fd5b82356133cb81613072565b915060208301356133db8161339f565b809150509250929050565b600080604083850312156133f957600080fd5b823561340481613072565b946020939093013593505050565b60006020828403121561342457600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60038110611c5b57634e487b7160e01b600052602160045260246000fd5b6001600160a01b0386811682528581166020830152604082018590528316606082015260a0810161348f83613441565b8260808301529695505050505050565b60008060008060008060008060006101208a8c0312156134be57600080fd5b8935985060208a01356134d081613072565b975060408a0135965060608a01356134e781613072565b955060808a01356134f781613072565b945060a08a013561350781613072565b935060c08a013561351781613072565b8093505060e08a013591506101008a013590509295985092959850929598565b600082601f83011261354857600080fd5b813567ffffffffffffffff81111561356257613562613227565b6135756020601f19601f8401160161328b565b81815284602083860101111561358a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060006101208a8c0312156135c657600080fd5b8935985060208a0135975060408a0135965060608a01356135e681613072565b955060808a0135945060a08a01356135fd81613072565b935060c08a013561360d81613072565b925060e08a013567ffffffffffffffff81111561362957600080fd5b6136358c828d01613537565b9250506101008a013590509295985092959850929598565b6000806040838503121561366057600080fd5b50508035926020909101359150565b60006020828403121561368157600080fd5b813567ffffffffffffffff8082111561369957600080fd5b9083019061020082860312156136ae57600080fd5b6136b661323d565b82358152602083013560208201526136d060408401613087565b60408201526136e160608401613087565b60608201526136f260808401613087565b608082015261370360a08401613087565b60a082015261371460c08401613087565b60c082015260e083013560e0820152610100808401358381111561373757600080fd5b613743888287016132bc565b828401525050610120613757818501613087565b90820152610140838101358381111561376f57600080fd5b61377b88828701613537565b82840152505061016061378f818501613087565b9082015261018083810135838111156137a757600080fd5b6137b388828701613537565b8284015250506101a0915081830135828201526101c091506137d6828401613087565b918101919091526101e091820135918101919091529392505050565b602081016137ff83613441565b91905290565b60006020828403121561381757600080fd5b813567ffffffffffffffff8082111561382f57600080fd5b908301906101a0828603121561384457600080fd5b61384c613267565b823581526020830135602082015261386660408401613087565b604082015261387760608401613087565b606082015261388860808401613087565b608082015260a083013560a082015260c083013560c08201526138ad60e08401613087565b60e082015261010080840135838111156138c657600080fd5b6138d288828701613537565b8284015250506101206138e6818501613087565b908201526101406138f8848201613087565b90820152610160838101358381111561391057600080fd5b61391c88828701613537565b91830191909152506101809283013592810192909252509392505050565b60808152600061394d60808301876131e1565b6001600160a01b0395861660208401529390941660408201526060015292915050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561399957613999613970565b92915050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156139c757600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036139ff576139ff613970565b5060010190565b600081518084526020808501945080840160005b83811015613a3f5781516001600160a01b031687529582019590820190600101613a1a565b509495945050505050565b6020815260006132206020830184613a06565b60006001600160a01b038089168352876020840152808716604084015260c06060840152613a8e60c08401876131e1565b60808401959095529290921660a09091015250949350505050565b87815286602082015260006001600160a01b03808816604084015260e06060840152613ad860e08401886131e1565b818716608085015281861660a085015283810360c0850152613afa81866131e1565b9b9a5050505050505050505050565b60008251613b1b8184602087016131bd565b9190910192915050565b600060208284031215613b3757600080fd5b81516132208161339f565b8082018082111561399957613999613970565b602081528151602082015260208201516040820152604082015160608201526060820151608082015260006080830151613b9a60a08401826001600160a01b03169052565b5060a083015160c083015260c0830151613bbf60e08401826001600160a01b03169052565b5060e08301516101a06101008181860152613bde6101c0860184613a06565b90860151909250610120613bfc868201836001600160a01b03169052565b80870151915050601f19610140818786030181880152613c1c85846131e1565b945080880151925050610160613c3c818801846001600160a01b03169052565b80880151925050610180818786030181880152613c5985846131e1565b97015195909201949094525092939250505056fe72657665727453796e74686573697a655265717565737442794272696467652875696e743235362c627974657333322c616464726573732c616464726573732c75696e743235362c616464726573732c62797465733332297265766572744275726e416e644275726e2875696e743235362c627974657333322c616464726573732c616464726573732c75696e743235362c61646472657373297265766572744d6574614275726e2875696e743235362c627974657333322c616464726573732c62797465732c616464726573732c616464726573732c6279746573296d696e7453796e746865746963546f6b656e2875696e743235362c627974657333322c627974657333322c616464726573732c75696e743235362c75696e743235362c6164647265737329a2646970667358221220b0052e583e73633a5252f3e3e3758b6a375ec6e74093ef348712759bf3dcfdd264736f6c63430008130033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80638bb3980211610104578063c42a2894116100a2578063eadd5c3411610071578063eadd5c3414610488578063f2fde38b1461049b578063fab92894146104ae578063fce633c2146104de57600080fd5b8063c42a28941461043c578063ce654c171461044f578063dbec15bb14610462578063e78cea921461047557600080fd5b8063ac210cc7116100de578063ac210cc7146103f0578063b1659a3c14610403578063c2167d9314610416578063c23a4c881461042957600080fd5b80638bb39802146103595780638da5cb5b1461036c5780639d8669851461039157600080fd5b80635badbe4c1161017c578063715018a61161014b578063715018a614610313578063753d75631461031b5780637c374f991461033e5780638456cb591461035157600080fd5b80635badbe4c146102af5780635c975abb146102c657806368775278146102d357806370a08231146102f357600080fd5b80633f4ba83a116101b85780633f4ba83a1461021a578063486ff0cd146102225780634a9136641461026a578063572b6c051461027d57600080fd5b806308759e9b146101df5780631459457a146101f45780631ebe53ef14610207575b600080fd5b6101f26101ed366004613092565b6104f1565b005b6101f26102023660046130ee565b61079f565b6101f261021536600461315f565b610922565b6101f2610b3c565b604080518082018252600581527f322e302e3100000000000000000000000000000000000000000000000000000060208201529051610261919061320d565b60405180910390f35b6101f2610278366004613345565b610c05565b61029f61028b366004613382565b6065546001600160a01b0391821691161490565b6040519015158152602001610261565b6102b860685481565b604051908152602001610261565b60695461029f9060ff1681565b6102b86102e1366004613382565b606d6020526000908152604090205481565b6102b8610301366004613382565b606c6020526000908152604090205481565b6101f2610e42565b61029f610329366004613382565b606e6020526000908152604090205460ff1681565b6101f261034c3660046133ad565b610ec7565b6101f2610fa4565b6101f26103673660046133e6565b611053565b6033546001600160a01b03165b6040516001600160a01b039091168152602001610261565b6103df61039f366004613412565b606a6020526000908152604090208054600182015460028301546003909301546001600160a01b039283169391831692811690600160a01b900460ff1685565b60405161026195949392919061345f565b606654610379906001600160a01b031681565b6102b861041136600461349f565b61111d565b6101f2610424366004613382565b611264565b6101f26104373660046135a7565b611338565b6101f261044a36600461364d565b611640565b6102b861045d36600461366f565b6118c1565b606f54610379906001600160a01b031681565b606754610379906001600160a01b031681565b6101f2610496366004613382565b611a0d565b6101f26104a9366004613382565b611b5d565b6104d16104bc366004613412565b606b6020526000908152604090205460ff1681565b60405161026191906137f2565b6101f26104ec366004613805565b611c5e565b60695460ff16156105385760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b60448201526064015b60405180910390fd5b600085306105446122db565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff1660028111156105bc576105bc61342b565b036106155760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b606482015260840161052f565b6000818152606b6020908152604091829020805460ff1916600217905581518083018352601b81527f7265766572744275726e2875696e743235362c62797465733332290000000000908201528151602481018a90526044808201859052835180830390910181526064909101835290810180516001600160e01b03167ff70519ae000000000000000000000000000000000000000000000000000000001790526067549151633675e4e160e11b815290916001600160a01b031690636cebc9c2906106eb9084908a908a908a9060040161393a565b600060405180830381600087803b15801561070557600080fd5b505af1158015610719573d6000803e3d6000fd5b50505050506107266122db565b6001600160a01b0316867f40590cc12db0488520ce425059f83f8caed91bdf98de5ff829dc57c63843161b60405160405180910390a3817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f58760405161078e91815260200190565b60405180910390a250505050505050565b600054610100900460ff166107ba5760005460ff16156107be565b303b155b6108305760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161052f565b600054610100900460ff1615801561086f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61087885612320565b606780546001600160a01b0380891673ffffffffffffffffffffffffffffffffffffffff199283161790925560668054878416908316179055606f805485841692169190911790558316156108eb576001600160a01b0383166000908152606e60205260409020805460ff191660011790555b801561091a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b505050505050565b6067546001600160a01b0316331461097c5760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f7420746865206272696467650000604482015260640161052f565b60695460ff16156109be5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6000858152606b602052604081205460ff1660028111156109e1576109e161342b565b14610a545760405162461bcd60e51b815260206004820152602660248201527f53796d623a2073796e74686574696320746f6b656e7320656d657267656e637960448201527f556e6275726e0000000000000000000000000000000000000000000000000000606482015260840161052f565b6001600160a01b0383166000908152606c6020526040902054610a78908390613986565b6001600160a01b0384166000908152606c6020908152604080832093909355878252606b905220805460ff19166001179055610abe8382610ab98986613986565b6123c2565b606754610ad69084906001600160a01b0316886123c2565b6001600160a01b03811684867faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26610b0d8a87613986565b60408051918252602082018c90526001600160a01b0389169082015260600160405180910390a4505050505050565b610b446122db565b6001600160a01b0316610b5f6033546001600160a01b031690565b6001600160a01b031614610bb55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6069805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610be86122db565b6040516001600160a01b03909116815260200160405180910390a1565b610c0d6122db565b6001600160a01b0316610c286033546001600160a01b031690565b6001600160a01b031614610c7e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b60005b8151811015610e0757606e6000838381518110610ca057610ca061399f565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16610d135760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e0000000000000000604482015260640161052f565b818181518110610d2557610d2561399f565b60209081029190910101516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610d8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db291906139b5565b606c6000848481518110610dc857610dc861399f565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080610dff906139ce565b915050610c81565b507f5a980ed3bb4dd09162988674fd35c7002fa70e44dd03d2942ac38c074b1a638e81604051610e379190613a4a565b60405180910390a150565b610e4a6122db565b6001600160a01b0316610e656033546001600160a01b031690565b6001600160a01b031614610ebb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b610ec5600061251c565b565b610ecf6122db565b6001600160a01b0316610eea6033546001600160a01b031690565b6001600160a01b031614610f405760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6001600160a01b0382166000818152606e6020908152604091829020805460ff19168515159081179091558251938452908301527f0a4552f1105808db6a44587c9ef0a7c4064bf620b9d843b514ad7365bd52239a91015b60405180910390a15050565b610fac6122db565b6001600160a01b0316610fc76033546001600160a01b031690565b6001600160a01b03161461101d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6069805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610be86122db565b61105b6122db565b6001600160a01b03166110766033546001600160a01b031690565b6001600160a01b0316146110cc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6001600160a01b0382166000818152606d6020908152604091829020849055815192835282018390527fa6742efd4f410d6fd9688a6cf6a15b6d51121097a263056a3576baaacdc4a9ae9101610f98565b60695460009060ff16156111625760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6001600160a01b0389166000908152606e602052604090205460ff166111ca5760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e0000000000000000604482015260640161052f565b6001600160a01b0389166000908152606d60205260409020548810156112325760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c6400000000604482015260640161052f565b6112458961123e6122db565b308b61257b565b6112568a8a8a8a8a8a8a8a8a6126d6565b9a9950505050505050505050565b61126c6122db565b6001600160a01b03166112876033546001600160a01b031690565b6001600160a01b0316146112dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6066805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fce42f6a6b3d7a9e5602623686f752d848285a87b22f0168a666c9c6064d2d23090602001610e37565b6067546001600160a01b031633146113925760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f7420746865206272696467650000604482015260640161052f565b60695460ff16156113d45760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6000878152606b602052604081205460ff1660028111156113f7576113f761342b565b1461146a5760405162461bcd60e51b815260206004820152602660248201527f53796d623a2073796e74686574696320746f6b656e7320656d657267656e637960448201527f556e6275726e0000000000000000000000000000000000000000000000000000606482015260840161052f565b6001600160a01b0384166000908152606c602052604090205461148e908690613986565b6001600160a01b038581166000908152606c60209081526040808320949094558a8252606b905291909120805460ff191660011790556067546114d4918691168b6123c2565b6114de8986613986565b94508151600003611548576114f48487876123c2565b60408051868152602081018b90526001600160a01b03861681830152905130918a918a917faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26919081900360600190a4611635565b606f546115609085906001600160a01b0316876123c2565b606f546040517ff5b697a50000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063f5b697a5906115b390879089908890889088908e90600401613a5d565b600060405180830381600087803b1580156115cd57600080fd5b505af11580156115e1573d6000803e3d6000fd5b505060408051888152602081018d90526001600160a01b0388168183015290513093508b92508a917faeef64b7687b985665b6620c7fa271b6f051a3fbe2bfc366fb9c964602eb6d26919081900360600190a45b505050505050505050565b6067546001600160a01b0316331461169a5760405162461bcd60e51b815260206004820152601e60248201527f53796d623a2063616c6c6572206973206e6f7420746865206272696467650000604482015260640161052f565b60695460ff16156116dc5760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6000818152606a6020526040902060016003820154600160a01b900460ff16600281111561170c5761170c61342b565b1461177f5760405162461bcd60e51b815260206004820152602960248201527f53796d623a207374617465206e6f74206f70656e206f7220747820646f65732060448201527f6e6f742065786973740000000000000000000000000000000000000000000000606482015260840161052f565b600381018054740200000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff82161790915560028201546001600160a01b039091166000908152606c60205260409020546117eb9190613986565b6003820180546001600160a01b039081166000908152606c6020526040902092909255548254600284015461182e93928316929190911690610ab9908790613986565b600381015460675461184d916001600160a01b039081169116856123c2565b805460028201546001600160a01b039091169083907fefcdf9ea4e65571d2ce9c030c46954e950662df8a7d8bd039fc4417e37b2f88c9061188f908790613986565b600385015460408051928352602083018990526001600160a01b039091169082015260600160405180910390a3505050565b60695460009060ff16156119065760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6040808301516001600160a01b03166000908152606e602052205460ff166119705760405162461bcd60e51b815260206004820152601860248201527f53796d623a20756e617574686f72697a656420746f6b656e0000000000000000604482015260640161052f565b6040808301516001600160a01b03166000908152606d6020908152919020549083015110156119e15760405162461bcd60e51b815260206004820152601c60248201527f53796d623a20616d6f756e7420756e646572207468726573686f6c6400000000604482015260640161052f565b6119fc82604001516119f16122db565b30856020015161257b565b611a0582612a97565b90505b919050565b611a156122db565b6001600160a01b0316611a306033546001600160a01b031690565b6001600160a01b031614611a865760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6001600160a01b038116611b025760405162461bcd60e51b815260206004820152602760248201527f53796d623a206d657461526f757465722063616e6e6f74206265207a65726f2060448201527f6164647265737300000000000000000000000000000000000000000000000000606482015260840161052f565b606f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fd5c54ab1d37bfef4dd2253d9d73c292e46f5bd8a67ca5920aab4c2e1993178e790602001610e37565b611b656122db565b6001600160a01b0316611b806033546001600160a01b031690565b6001600160a01b031614611bd65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161052f565b6001600160a01b038116611c525760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161052f565b611c5b8161251c565b50565b60695460ff1615611ca05760405162461bcd60e51b815260206004820152600c60248201526b14de5b588e881c185d5cd95960a21b604482015260640161052f565b6101008101515115611f4b576000816020015130611cbc6122db565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff166002811115611d3457611d3461342b565b03611d8d5760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b606482015260840161052f565b6000818152606b60209081526040808320805460ff1916600217905580516080810190915260438082529091613d0890830139805190602001208360000151838560e00151866101000151876101200151886101400151896101600151604051602401611e009796959493929190613aa9565b60408051601f198184030181529181526020820180516001600160e01b03167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925260675485830151606087015160a08801519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c293611e8d93879392909160040161393a565b600060405180830381600087803b158015611ea757600080fd5b505af1158015611ebb573d6000803e3d6000fd5b50505050611ec76122db565b6001600160a01b031683602001517f40590cc12db0488520ce425059f83f8caed91bdf98de5ff829dc57c63843161b60405160405180910390a38261018001517f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f58460200151604051611f3c91815260200190565b60405180910390a25050612296565b610160810151511561214f576000816020015130611f676122db565b6040805160208101949094526bffffffffffffffffffffffff19606093841b811691850191909152911b16605482015246606882015260880160408051601f198184030181529190528051602090910120905060016000828152606b602052604090205460ff166002811115611fdf57611fdf61342b565b036120385760405162461bcd60e51b8152602060048201526024808201527f53796d623a205265616c20746f6b656e7320616c7265616479207472616e7366604482015263195c995960e21b606482015260840161052f565b6000818152606b60209081526040808320805460ff1916600217905580516080810190915260428082529091613cc69083013980519060200120836000015183308660800151466120876122db565b604051602481019690965260448601949094526001600160a01b039283166064860152908216608485015260a48401521660c482015260e40160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252606754610120860151606087015160a08801519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c293611e8d93879392909160040161393a565b6000604051806080016040528060588152602001613c6e605891398051906020012082600001518360200151846040015185608001514661218e6122db565b610180890151604051602481019790975260448701959095526001600160a01b039384166064870152918316608486015260a48501521660c483015260e48201526101040160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252606754610120850151606086015160a08701519451633675e4e160e11b81529395506001600160a01b0390921693636cebc9c29361226293879392909160040161393a565b600060405180830381600087803b15801561227c57600080fd5b505af1158015612290573d6000803e3d6000fd5b50505050505b61229e6122db565b6001600160a01b031681602001517fbd03c66ec5bd3d01fbf22bc794f68ac88b693023b438724019205a4b42aefb2060405160405180910390a350565b6065546000906001600160a01b0316330361231b57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b600054610100900460ff1661238b5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161052f565b612393612f11565b6065805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b03167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916124379190613b09565b6000604051808303816000865af19150503d8060008114612474576040519150601f19603f3d011682016040523d82523d6000602084013e612479565b606091505b50915091508180156124a35750805115806124a35750808060200190518101906124a39190613b25565b6125155760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c656400000000000000000000000000000000000000606482015260840161052f565b5050505050565b603380546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000928392908816916125f89190613b09565b6000604051808303816000865af19150503d8060008114612635576040519150601f19603f3d011682016040523d82523d6000602084013e61263a565b606091505b50915091508180156126645750805115806126645750808060200190518101906126649190613b25565b61091a5760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a20747260448201527f616e7366657246726f6d206661696c6564000000000000000000000000000000606482015260840161052f565b6001600160a01b0388166000908152606c60205260408120546126fa908990613b42565b6001600160a01b03808b166000908152606c60205260409020919091558416612721578693505b6068546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015260740160408051601f1981840301815282825280516020918201209083018190526bffffffffffffffffffffffff1960608a811b8216938501939093529187901b909116605483015260688201859052915060009060880160405160208183030381529060405280519060200120905060006040518060800160405280604b8152602001613d4b604b91398051602090910120604051602481018e905260448101849052606481018590526001600160a01b03808e1660848301524660a483015260c482018d90528b1660e48201526101040160408051601f198184030181529181526020820180516001600160e01b03167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252815160a0810190925291508061287e6122db565b6001600160a01b0390811682528b81166020830152604082018d90528d166060820152608001600190526000838152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180549485169190951690811785556080860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b9084908111156129625761296261342b565b0217905550506068805491506000612979836139ce565b9091555050606754604051633675e4e160e11b81526001600160a01b0390911690636cebc9c2906129b49084908c908c908b9060040161393a565b600060405180830381600087803b1580156129ce57600080fd5b505af11580156129e2573d6000803e3d6000fd5b505050505050836001600160a01b0316836129fb6122db565b604080518581526001600160a01b038c811660208301529181018d90528d821660608201529116907f31325fe0a1a2e6a5b1e41572156ba5b4e94f0fae7e7f63ec21e9b5ce1e4b3eab9060800160405180910390a4817f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f582604051612a8291815260200190565b60405180910390a29998505050505050505050565b6020808201516040808401516001600160a01b03166000908152606c909352822054612ac39190613b42565b6040808401516001600160a01b039081166000908152606c60205291909120919091556101c083015116612b065760608201516001600160a01b03166101c08301525b6068546040516bffffffffffffffffffffffff193060601b166020820152603481019190915246605482015260740160408051601f19818403018152828252805160209182012060808601516101c087015160e08801519386018390526bffffffffffffffffffffffff19606092831b811695870195909552901b9092166054840152606883015291506000906088016040516020818303038152906040528051906020012090506000604051806101a00160405280856000015181526020018560200151815260200184815260200183815260200185604001516001600160a01b0316815260200146815260200185606001516001600160a01b0316815260200185610100015181526020018561012001516001600160a01b0316815260200185610140015181526020018561016001516001600160a01b031681526020018561018001518152602001856101a001518152509050600081604051602401612c6f9190613b55565b60408051601f19818403018152918152602080830180516001600160e01b03167fc29a91bc00000000000000000000000000000000000000000000000000000000179052815160a08101835260c08901516001600160a01b0390811682526060808b0151821683850152928a015182850152928901519092169082015290915060808101600190526000848152606a60209081526040918290208351815473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b039283161783559285015160018301805485169183169190911790559284015160028083019190915560608501516003830180549485169190951690811785556080860151929492937fffffffffffffffffffffff000000000000000000000000000000000000000000161790600160a01b908490811115612db157612db161342b565b0217905550506068805491506000612dc8836139ce565b9091555050606754608086015160a087015160e0880151604051633675e4e160e11b81526001600160a01b0390941693636cebc9c293612e11938793919290919060040161393a565b600060405180830381600087803b158015612e2b57600080fd5b505af1158015612e3f573d6000803e3d6000fd5b5050505050836101c001516001600160a01b03168460e001518560c001516001600160a01b03167f31325fe0a1a2e6a5b1e41572156ba5b4e94f0fae7e7f63ec21e9b5ce1e4b3eab86886060015189602001518a60400151604051612ec994939291909384526001600160a01b039283166020850152604084019190915216606082015260800190565b60405180910390a46101e08401516040518481527f5a297b2c9a9f94a0f4e5a796c74ad38e219d1185fccf5f79c18726a830c2b6f59060200160405180910390a25050919050565b600054610100900460ff16612f7c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161052f565b612f84612f8c565b610ec5612ff7565b600054610100900460ff16610ec55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161052f565b600054610100900460ff166130625760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161052f565b610ec561306d6122db565b61251c565b6001600160a01b0381168114611c5b57600080fd5b8035611a0881613072565b60008060008060008060c087890312156130ab57600080fd5b863595506020870135945060408701356130c481613072565b935060608701356130d481613072565b9598949750929560808101359460a0909101359350915050565b600080600080600060a0868803121561310657600080fd5b853561311181613072565b9450602086013561312181613072565b9350604086013561313181613072565b9250606086013561314181613072565b9150608086013561315181613072565b809150509295509295909350565b60008060008060008060c0878903121561317857600080fd5b863595506020870135945060408701359350606087013561319881613072565b92506080870135915060a08701356131af81613072565b809150509295509295509295565b60005b838110156131d85781810151838201526020016131c0565b50506000910152565b600081518084526131f98160208601602086016131bd565b601f01601f19169290920160200192915050565b60208152600061322060208301846131e1565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051610200810167ffffffffffffffff8111828210171561326157613261613227565b60405290565b6040516101a0810167ffffffffffffffff8111828210171561326157613261613227565b604051601f8201601f1916810167ffffffffffffffff811182821017156132b4576132b4613227565b604052919050565b600082601f8301126132cd57600080fd5b8135602067ffffffffffffffff8211156132e9576132e9613227565b8160051b6132f882820161328b565b928352848101820192828101908785111561331257600080fd5b83870192505b8483101561333a57823561332b81613072565b82529183019190830190613318565b979650505050505050565b60006020828403121561335757600080fd5b813567ffffffffffffffff81111561336e57600080fd5b61337a848285016132bc565b949350505050565b60006020828403121561339457600080fd5b813561322081613072565b8015158114611c5b57600080fd5b600080604083850312156133c057600080fd5b82356133cb81613072565b915060208301356133db8161339f565b809150509250929050565b600080604083850312156133f957600080fd5b823561340481613072565b946020939093013593505050565b60006020828403121561342457600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60038110611c5b57634e487b7160e01b600052602160045260246000fd5b6001600160a01b0386811682528581166020830152604082018590528316606082015260a0810161348f83613441565b8260808301529695505050505050565b60008060008060008060008060006101208a8c0312156134be57600080fd5b8935985060208a01356134d081613072565b975060408a0135965060608a01356134e781613072565b955060808a01356134f781613072565b945060a08a013561350781613072565b935060c08a013561351781613072565b8093505060e08a013591506101008a013590509295985092959850929598565b600082601f83011261354857600080fd5b813567ffffffffffffffff81111561356257613562613227565b6135756020601f19601f8401160161328b565b81815284602083860101111561358a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060006101208a8c0312156135c657600080fd5b8935985060208a0135975060408a0135965060608a01356135e681613072565b955060808a0135945060a08a01356135fd81613072565b935060c08a013561360d81613072565b925060e08a013567ffffffffffffffff81111561362957600080fd5b6136358c828d01613537565b9250506101008a013590509295985092959850929598565b6000806040838503121561366057600080fd5b50508035926020909101359150565b60006020828403121561368157600080fd5b813567ffffffffffffffff8082111561369957600080fd5b9083019061020082860312156136ae57600080fd5b6136b661323d565b82358152602083013560208201526136d060408401613087565b60408201526136e160608401613087565b60608201526136f260808401613087565b608082015261370360a08401613087565b60a082015261371460c08401613087565b60c082015260e083013560e0820152610100808401358381111561373757600080fd5b613743888287016132bc565b828401525050610120613757818501613087565b90820152610140838101358381111561376f57600080fd5b61377b88828701613537565b82840152505061016061378f818501613087565b9082015261018083810135838111156137a757600080fd5b6137b388828701613537565b8284015250506101a0915081830135828201526101c091506137d6828401613087565b918101919091526101e091820135918101919091529392505050565b602081016137ff83613441565b91905290565b60006020828403121561381757600080fd5b813567ffffffffffffffff8082111561382f57600080fd5b908301906101a0828603121561384457600080fd5b61384c613267565b823581526020830135602082015261386660408401613087565b604082015261387760608401613087565b606082015261388860808401613087565b608082015260a083013560a082015260c083013560c08201526138ad60e08401613087565b60e082015261010080840135838111156138c657600080fd5b6138d288828701613537565b8284015250506101206138e6818501613087565b908201526101406138f8848201613087565b90820152610160838101358381111561391057600080fd5b61391c88828701613537565b91830191909152506101809283013592810192909252509392505050565b60808152600061394d60808301876131e1565b6001600160a01b0395861660208401529390941660408201526060015292915050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561399957613999613970565b92915050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156139c757600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036139ff576139ff613970565b5060010190565b600081518084526020808501945080840160005b83811015613a3f5781516001600160a01b031687529582019590820190600101613a1a565b509495945050505050565b6020815260006132206020830184613a06565b60006001600160a01b038089168352876020840152808716604084015260c06060840152613a8e60c08401876131e1565b60808401959095529290921660a09091015250949350505050565b87815286602082015260006001600160a01b03808816604084015260e06060840152613ad860e08401886131e1565b818716608085015281861660a085015283810360c0850152613afa81866131e1565b9b9a5050505050505050505050565b60008251613b1b8184602087016131bd565b9190910192915050565b600060208284031215613b3757600080fd5b81516132208161339f565b8082018082111561399957613999613970565b602081528151602082015260208201516040820152604082015160608201526060820151608082015260006080830151613b9a60a08401826001600160a01b03169052565b5060a083015160c083015260c0830151613bbf60e08401826001600160a01b03169052565b5060e08301516101a06101008181860152613bde6101c0860184613a06565b90860151909250610120613bfc868201836001600160a01b03169052565b80870151915050601f19610140818786030181880152613c1c85846131e1565b945080880151925050610160613c3c818801846001600160a01b03169052565b80880151925050610180818786030181880152613c5985846131e1565b97015195909201949094525092939250505056fe72657665727453796e74686573697a655265717565737442794272696467652875696e743235362c627974657333322c616464726573732c616464726573732c75696e743235362c616464726573732c62797465733332297265766572744275726e416e644275726e2875696e743235362c627974657333322c616464726573732c616464726573732c75696e743235362c61646472657373297265766572744d6574614275726e2875696e743235362c627974657333322c616464726573732c62797465732c616464726573732c616464726573732c6279746573296d696e7453796e746865746963546f6b656e2875696e743235362c627974657333322c627974657333322c616464726573732c75696e743235362c75696e743235362c6164647265737329a2646970667358221220b0052e583e73633a5252f3e3e3758b6a375ec6e74093ef348712759bf3dcfdd264736f6c63430008130033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$973,332.49
Net Worth in FRAX
980,933.56796
Token Allocations
UXLINK
65.59%
USDC
24.85%
WETH
7.27%
Others
2.29%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ARB | 65.59% | $0.011631 | 54,892,612.238 | $638,450.48 | |
| ARB | 24.85% | $0.999697 | 241,915.9433 | $241,842.64 | |
| ARB | 7.27% | $2,947.5 | 24.0162 | $70,787.72 | |
| ARB | 1.03% | $0.025456 | 395,588.7654 | $10,070.27 | |
| ARB | 0.60% | $0.999697 | 5,804.4625 | $5,802.7 | |
| ARB | 0.56% | $0.002741 | 2,000,000 | $5,481.05 | |
| ARB | 0.08% | $0.185629 | 4,452.51 | $826.51 | |
| ARB | <0.01% | <$0.000001 | 6,928,782,556.9453 | $67.21 | |
| ARB | <0.01% | $0.992045 | 3.927 | $3.9 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.