Overview
MNT Balance
MNT Value
$0.00Latest 25 from a total of 103 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Revert Redeem Lo... | 90542713 | 19 hrs ago | IN | 1.5204032 MNT | 0.02268262 | ||||
| Revert Redeem Lo... | 90426140 | 3 days ago | IN | 1.4354426 MNT | 0.02243364 | ||||
| Revert Redeem Lo... | 90193912 | 8 days ago | IN | 6.09504805 MNT | 0.02291183 | ||||
| Revert Redeem Lo... | 89921956 | 15 days ago | IN | 1.3722965 MNT | 0.02133546 | ||||
| Redeem Local | 89839913 | 17 days ago | IN | 30 MNT | 0.02214355 | ||||
| Redeem Local | 89839890 | 17 days ago | IN | 30 MNT | 0.01880929 | ||||
| Redeem Local | 89839754 | 17 days ago | IN | 30 MNT | 0.02217361 | ||||
| Redeem Local | 89839686 | 17 days ago | IN | 30 MNT | 0.01930769 | ||||
| Send Credits | 89839547 | 17 days ago | IN | 30 MNT | 0.0162757 | ||||
| Redeem Local | 89839464 | 17 days ago | IN | 30 MNT | 0.0212094 | ||||
| Redeem Local | 89839419 | 17 days ago | IN | 30 MNT | 0.01881192 | ||||
| Send Credits | 89839353 | 17 days ago | IN | 30 MNT | 0.01627669 | ||||
| Redeem Local | 89839264 | 17 days ago | IN | 30 MNT | 0.02159219 | ||||
| Send Credits | 89839235 | 17 days ago | IN | 30 MNT | 0.01629712 | ||||
| Redeem Local | 89839157 | 17 days ago | IN | 30 MNT | 0.02254363 | ||||
| Send Credits | 89839084 | 17 days ago | IN | 30 MNT | 0.01629802 | ||||
| Send Credits | 89838876 | 17 days ago | IN | 30 MNT | 0.0162547 | ||||
| Revert Redeem Lo... | 89830852 | 17 days ago | IN | 1.18983664 MNT | 0.02109044 | ||||
| Redeem Local | 89810175 | 17 days ago | IN | 30 MNT | 0.02200286 | ||||
| Revert Redeem Lo... | 89809931 | 17 days ago | IN | 5.45100425 MNT | 0.01973476 | ||||
| Send Credits | 89809652 | 17 days ago | IN | 20 MNT | 0.01590161 | ||||
| Redeem Local | 89798028 | 18 days ago | IN | 3.67966905 MNT | 0.02100382 | ||||
| Revert Redeem Lo... | 89495144 | 25 days ago | IN | 6.24237913 MNT | 0.02033567 | ||||
| Redeem Local | 89456359 | 25 days ago | IN | 3.50760786 MNT | 0.02063968 | ||||
| Revert Redeem Lo... | 89365243 | 28 days ago | IN | 5.42079969 MNT | 0.01863586 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 90542713 | 19 hrs ago | 1.5204032 MNT | ||||
| 90426140 | 3 days ago | 1.4354426 MNT | ||||
| 90193912 | 8 days ago | 6.09504805 MNT | ||||
| 89921956 | 15 days ago | 1.3722965 MNT | ||||
| 89840093 | 17 days ago | 0.59088012 MNT | ||||
| 89839913 | 17 days ago | 30 MNT | ||||
| 89839890 | 17 days ago | 30 MNT | ||||
| 89839754 | 17 days ago | 30 MNT | ||||
| 89839686 | 17 days ago | 30 MNT | ||||
| 89839547 | 17 days ago | 30 MNT | ||||
| 89839464 | 17 days ago | 30 MNT | ||||
| 89839419 | 17 days ago | 30 MNT | ||||
| 89839353 | 17 days ago | 30 MNT | ||||
| 89839264 | 17 days ago | 30 MNT | ||||
| 89839235 | 17 days ago | 30 MNT | ||||
| 89839157 | 17 days ago | 30 MNT | ||||
| 89839084 | 17 days ago | 30 MNT | ||||
| 89838876 | 17 days ago | 30 MNT | ||||
| 89830852 | 17 days ago | 1.18983664 MNT | ||||
| 89821900 | 17 days ago | 0.59686373 MNT | ||||
| 89810175 | 17 days ago | 30 MNT | ||||
| 89809931 | 17 days ago | 5.45100425 MNT | ||||
| 89809652 | 17 days ago | 20 MNT | ||||
| 89798028 | 18 days ago | 3.67966905 MNT | ||||
| 89786070 | 18 days ago | 0.58990226 MNT |
Cross-Chain Transactions
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.7.6;
pragma abicoder v2;
// imports
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "./Factory.sol";
import "./Pool.sol";
import "./Bridge.sol";
// interfaces
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./interfaces/IStargateRouter.sol";
import "./interfaces/IStargateReceiver.sol";
// libraries
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/Address.sol";
contract Router is IStargateRouter, Ownable, ReentrancyGuard {
using SafeMath for uint256;
//---------------------------------------------------------------------------
// CONSTANTS
uint8 internal constant TYPE_REDEEM_LOCAL_RESPONSE = 1;
uint8 internal constant TYPE_REDEEM_LOCAL_CALLBACK_RETRY = 2;
uint8 internal constant TYPE_SWAP_REMOTE_RETRY = 3;
//---------------------------------------------------------------------------
// STRUCTS
struct CachedSwap {
address token;
uint256 amountLD;
address to;
bytes payload;
}
//---------------------------------------------------------------------------
// VARIABLES
Factory public factory; // used for creating pools
address public protocolFeeOwner; // can call methods to pull Stargate fees collected in pools
address public mintFeeOwner; // can call methods to pull mint fees collected in pools
Bridge public bridge;
mapping(uint16 => mapping(bytes => mapping(uint256 => bytes))) public revertLookup; //[chainId][srcAddress][nonce]
mapping(uint16 => mapping(bytes => mapping(uint256 => CachedSwap))) public cachedSwapLookup; //[chainId][srcAddress][nonce]
//---------------------------------------------------------------------------
// EVENTS
event Revert(uint8 bridgeFunctionType, uint16 chainId, bytes srcAddress, uint256 nonce);
event CachedSwapSaved(
uint16 chainId,
bytes srcAddress,
uint256 nonce,
address token,
uint256 amountLD,
address to,
bytes payload,
bytes reason
);
event RevertRedeemLocal(
uint16 srcChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
bytes to,
uint256 redeemAmountSD,
uint256 mintAmountSD,
uint256 indexed nonce,
bytes indexed srcAddress
);
event RedeemLocalCallback(
uint16 srcChainId,
bytes indexed srcAddress,
uint256 indexed nonce,
uint256 srcPoolId,
uint256 dstPoolId,
address to,
uint256 amountSD,
uint256 mintAmountSD
);
//---------------------------------------------------------------------------
// MODIFIERS
modifier onlyBridge() {
require(msg.sender == address(bridge), "Bridge: caller must be Bridge.");
_;
}
constructor() {}
function setBridgeAndFactory(Bridge _bridge, Factory _factory) external onlyOwner {
require(
address(bridge) == address(0x0) && address(factory) == address(0x0),
"Stargate: bridge and factory already initialized"
); // 1 time only
require(address(_bridge) != address(0x0), "Stargate: bridge cant be 0x0");
require(address(_factory) != address(0x0), "Stargate: factory cant be 0x0");
bridge = _bridge;
factory = _factory;
}
//---------------------------------------------------------------------------
// VIEWS
function _getPool(uint256 _poolId) internal view returns (Pool pool) {
pool = factory.getPool(_poolId);
require(address(pool) != address(0x0), "Stargate: Pool does not exist");
}
//---------------------------------------------------------------------------
// INTERNAL
function _safeTransferFrom(
address token,
address from,
address to,
uint256 value
) private {
// 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))), "Stargate: TRANSFER_FROM_FAILED");
}
//---------------------------------------------------------------------------
// LOCAL CHAIN FUNCTIONS
function addLiquidity(
uint256 _poolId,
uint256 _amountLD,
address _to
) external override nonReentrant {
Pool pool = _getPool(_poolId);
uint256 convertRate = pool.convertRate();
_amountLD = _amountLD.div(convertRate).mul(convertRate);
_safeTransferFrom(pool.token(), msg.sender, address(pool), _amountLD);
pool.mint(_to, _amountLD);
}
function swap(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLD,
uint256 _minAmountLD,
lzTxObj memory _lzTxParams,
bytes calldata _to,
bytes calldata _payload
) external payable override nonReentrant {
require(_amountLD > 0, "Stargate: cannot swap 0");
require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0");
Pool.SwapObj memory s;
Pool.CreditObj memory c;
{
Pool pool = _getPool(_srcPoolId);
{
uint256 convertRate = pool.convertRate();
_amountLD = _amountLD.div(convertRate).mul(convertRate);
}
s = pool.swap(_dstChainId, _dstPoolId, msg.sender, _amountLD, _minAmountLD, true);
_safeTransferFrom(pool.token(), msg.sender, address(pool), _amountLD);
c = pool.sendCredits(_dstChainId, _dstPoolId);
}
bridge.swap{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c, s, _lzTxParams, _to, _payload);
}
function redeemRemote(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLP,
uint256 _minAmountLD,
bytes calldata _to,
lzTxObj memory _lzTxParams
) external payable override nonReentrant {
require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0");
require(_amountLP > 0, "Stargate: not enough lp to redeemRemote");
Pool.SwapObj memory s;
Pool.CreditObj memory c;
{
Pool pool = _getPool(_srcPoolId);
uint256 amountLD = pool.amountLPtoLD(_amountLP);
// perform a swap with no liquidity
s = pool.swap(_dstChainId, _dstPoolId, msg.sender, amountLD, _minAmountLD, false);
pool.redeemRemote(_dstChainId, _dstPoolId, msg.sender, _amountLP);
c = pool.sendCredits(_dstChainId, _dstPoolId);
}
// equal to a swap, with no payload ("0x") no dstGasForCall 0
bridge.swap{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c, s, _lzTxParams, _to, "");
}
function instantRedeemLocal(
uint16 _srcPoolId,
uint256 _amountLP,
address _to
) external override nonReentrant returns (uint256 amountSD) {
require(_amountLP > 0, "Stargate: not enough lp to redeem");
Pool pool = _getPool(_srcPoolId);
amountSD = pool.instantRedeemLocal(msg.sender, _amountLP, _to);
}
function redeemLocal(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLP,
bytes calldata _to,
lzTxObj memory _lzTxParams
) external payable override nonReentrant {
require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0");
Pool pool = _getPool(_srcPoolId);
require(_amountLP > 0, "Stargate: not enough lp to redeem");
uint256 amountSD = pool.redeemLocal(msg.sender, _amountLP, _dstChainId, _dstPoolId, _to);
require(amountSD > 0, "Stargate: not enough lp to redeem with amountSD");
Pool.CreditObj memory c = pool.sendCredits(_dstChainId, _dstPoolId);
bridge.redeemLocal{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c, amountSD, _to, _lzTxParams);
}
function sendCredits(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress
) external payable override nonReentrant {
require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0");
Pool pool = _getPool(_srcPoolId);
Pool.CreditObj memory c = pool.sendCredits(_dstChainId, _dstPoolId);
bridge.sendCredits{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c);
}
function quoteLayerZeroFee(
uint16 _dstChainId,
uint8 _functionType,
bytes calldata _toAddress,
bytes calldata _transferAndCallPayload,
Router.lzTxObj memory _lzTxParams
) external view override returns (uint256, uint256) {
return bridge.quoteLayerZeroFee(_dstChainId, _functionType, _toAddress, _transferAndCallPayload, _lzTxParams);
}
function revertRedeemLocal(
uint16 _dstChainId,
bytes calldata _srcAddress,
uint256 _nonce,
address payable _refundAddress,
lzTxObj memory _lzTxParams
) external payable {
require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0");
bytes memory payload = revertLookup[_dstChainId][_srcAddress][_nonce];
require(payload.length > 0, "Stargate: no retry revert");
{
uint8 functionType;
assembly {
functionType := mload(add(payload, 32))
}
require(functionType == TYPE_REDEEM_LOCAL_RESPONSE, "Stargate: invalid function type");
}
// empty it
revertLookup[_dstChainId][_srcAddress][_nonce] = "";
uint256 srcPoolId;
uint256 dstPoolId;
assembly {
srcPoolId := mload(add(payload, 64))
dstPoolId := mload(add(payload, 96))
}
Pool.CreditObj memory c;
{
Pool pool = _getPool(dstPoolId);
c = pool.sendCredits(_dstChainId, srcPoolId);
}
bridge.redeemLocalCallback{value: msg.value}(_dstChainId, _refundAddress, c, _lzTxParams, payload);
}
function retryRevert(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint256 _nonce
) external payable {
bytes memory payload = revertLookup[_srcChainId][_srcAddress][_nonce];
require(payload.length > 0, "Stargate: no retry revert");
// empty it
revertLookup[_srcChainId][_srcAddress][_nonce] = "";
uint8 functionType;
assembly {
functionType := mload(add(payload, 32))
}
if (functionType == TYPE_REDEEM_LOCAL_CALLBACK_RETRY) {
(, uint256 srcPoolId, uint256 dstPoolId, address to, uint256 amountSD, uint256 mintAmountSD) = abi.decode(
payload,
(uint8, uint256, uint256, address, uint256, uint256)
);
_redeemLocalCallback(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, to, amountSD, mintAmountSD);
}
// for retrying the swapRemote. if it fails again, retry
else if (functionType == TYPE_SWAP_REMOTE_RETRY) {
(, uint256 srcPoolId, uint256 dstPoolId, uint256 dstGasForCall, address to, Pool.SwapObj memory s, bytes memory p) = abi.decode(
payload,
(uint8, uint256, uint256, uint256, address, Pool.SwapObj, bytes)
);
_swapRemote(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, dstGasForCall, to, s, p);
} else {
revert("Stargate: invalid function type");
}
}
function clearCachedSwap(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint256 _nonce
) external {
CachedSwap memory cs = cachedSwapLookup[_srcChainId][_srcAddress][_nonce];
require(cs.to != address(0x0), "Stargate: cache already cleared");
// clear the data
cachedSwapLookup[_srcChainId][_srcAddress][_nonce] = CachedSwap(address(0x0), 0, address(0x0), "");
IStargateReceiver(cs.to).sgReceive(_srcChainId, _srcAddress, _nonce, cs.token, cs.amountLD, cs.payload);
}
function creditChainPath(
uint16 _dstChainId,
uint256 _dstPoolId,
uint256 _srcPoolId,
Pool.CreditObj memory _c
) external onlyBridge {
Pool pool = _getPool(_srcPoolId);
pool.creditChainPath(_dstChainId, _dstPoolId, _c);
}
//---------------------------------------------------------------------------
// REMOTE CHAIN FUNCTIONS
function redeemLocalCheckOnRemote(
uint16 _srcChainId,
bytes memory _srcAddress,
uint256 _nonce,
uint256 _srcPoolId,
uint256 _dstPoolId,
uint256 _amountSD,
bytes calldata _to
) external onlyBridge {
Pool pool = _getPool(_dstPoolId);
try pool.redeemLocalCheckOnRemote(_srcChainId, _srcPoolId, _amountSD) returns (uint256 redeemAmountSD, uint256 mintAmountSD) {
revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode(
TYPE_REDEEM_LOCAL_RESPONSE,
_srcPoolId,
_dstPoolId,
redeemAmountSD,
mintAmountSD,
_to
);
emit RevertRedeemLocal(_srcChainId, _srcPoolId, _dstPoolId, _to, redeemAmountSD, mintAmountSD, _nonce, _srcAddress);
} catch {
// if the func fail, return [swapAmount: 0, mintAMount: _amountSD]
// swapAmount represents the amount of chainPath balance deducted on the remote side, which because the above tx failed, should be 0
// mintAmount is the full amount of tokens the user attempted to redeem on the src side, which gets converted back into the lp amount
revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode(TYPE_REDEEM_LOCAL_RESPONSE, _srcPoolId, _dstPoolId, 0, _amountSD, _to);
emit Revert(TYPE_REDEEM_LOCAL_RESPONSE, _srcChainId, _srcAddress, _nonce);
}
}
function redeemLocalCallback(
uint16 _srcChainId,
bytes memory _srcAddress,
uint256 _nonce,
uint256 _srcPoolId,
uint256 _dstPoolId,
address _to,
uint256 _amountSD,
uint256 _mintAmountSD
) external onlyBridge {
_redeemLocalCallback(_srcChainId, _srcAddress, _nonce, _srcPoolId, _dstPoolId, _to, _amountSD, _mintAmountSD);
}
function _redeemLocalCallback(
uint16 _srcChainId,
bytes memory _srcAddress,
uint256 _nonce,
uint256 _srcPoolId,
uint256 _dstPoolId,
address _to,
uint256 _amountSD,
uint256 _mintAmountSD
) internal {
Pool pool = _getPool(_dstPoolId);
try pool.redeemLocalCallback(_srcChainId, _srcPoolId, _to, _amountSD, _mintAmountSD) {} catch {
revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode(
TYPE_REDEEM_LOCAL_CALLBACK_RETRY,
_srcPoolId,
_dstPoolId,
_to,
_amountSD,
_mintAmountSD
);
emit Revert(TYPE_REDEEM_LOCAL_CALLBACK_RETRY, _srcChainId, _srcAddress, _nonce);
}
emit RedeemLocalCallback(_srcChainId, _srcAddress, _nonce, _srcPoolId, _dstPoolId, _to, _amountSD, _mintAmountSD);
}
function swapRemote(
uint16 _srcChainId,
bytes memory _srcAddress,
uint256 _nonce,
uint256 _srcPoolId,
uint256 _dstPoolId,
uint256 _dstGasForCall,
address _to,
Pool.SwapObj memory _s,
bytes memory _payload
) external onlyBridge {
_swapRemote(_srcChainId, _srcAddress, _nonce, _srcPoolId, _dstPoolId, _dstGasForCall, _to, _s, _payload);
}
function _swapRemote(
uint16 _srcChainId,
bytes memory _srcAddress,
uint256 _nonce,
uint256 _srcPoolId,
uint256 _dstPoolId,
uint256 _dstGasForCall,
address _to,
Pool.SwapObj memory _s,
bytes memory _payload
) internal {
Pool pool = _getPool(_dstPoolId);
// first try catch the swap remote
try pool.swapRemote(_srcChainId, _srcPoolId, _to, _s) returns (uint256 amountLD) {
if (Address.isContract(_to) && _payload.length > 0) {
// then try catch the external contract call
try IStargateReceiver(_to).sgReceive{gas: _dstGasForCall}(_srcChainId, _srcAddress, _nonce, pool.token(), amountLD, _payload) {
// do nothing
} catch (bytes memory reason) {
cachedSwapLookup[_srcChainId][_srcAddress][_nonce] = CachedSwap(pool.token(), amountLD, _to, _payload);
emit CachedSwapSaved(_srcChainId, _srcAddress, _nonce, pool.token(), amountLD, _to, _payload, reason);
}
}
} catch {
revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode(
TYPE_SWAP_REMOTE_RETRY,
_srcPoolId,
_dstPoolId,
_dstGasForCall,
_to,
_s,
_payload
);
emit Revert(TYPE_SWAP_REMOTE_RETRY, _srcChainId, _srcAddress, _nonce);
}
}
//---------------------------------------------------------------------------
// DAO Calls
function createPool(
uint256 _poolId,
address _token,
uint8 _sharedDecimals,
uint8 _localDecimals,
string memory _name,
string memory _symbol
) external onlyOwner returns (address) {
require(_token != address(0x0), "Stargate: _token cannot be 0x0");
return factory.createPool(_poolId, _token, _sharedDecimals, _localDecimals, _name, _symbol);
}
function createChainPath(
uint256 _poolId,
uint16 _dstChainId,
uint256 _dstPoolId,
uint256 _weight
) external onlyOwner {
Pool pool = _getPool(_poolId);
pool.createChainPath(_dstChainId, _dstPoolId, _weight);
}
function activateChainPath(
uint256 _poolId,
uint16 _dstChainId,
uint256 _dstPoolId
) external onlyOwner {
Pool pool = _getPool(_poolId);
pool.activateChainPath(_dstChainId, _dstPoolId);
}
function setWeightForChainPath(
uint256 _poolId,
uint16 _dstChainId,
uint256 _dstPoolId,
uint16 _weight
) external onlyOwner {
Pool pool = _getPool(_poolId);
pool.setWeightForChainPath(_dstChainId, _dstPoolId, _weight);
}
function setProtocolFeeOwner(address _owner) external onlyOwner {
require(_owner != address(0x0), "Stargate: _owner cannot be 0x0");
protocolFeeOwner = _owner;
}
function setMintFeeOwner(address _owner) external onlyOwner {
require(_owner != address(0x0), "Stargate: _owner cannot be 0x0");
mintFeeOwner = _owner;
}
function setFees(uint256 _poolId, uint256 _mintFeeBP) external onlyOwner {
Pool pool = _getPool(_poolId);
pool.setFee(_mintFeeBP);
}
function setFeeLibrary(uint256 _poolId, address _feeLibraryAddr) external onlyOwner {
Pool pool = _getPool(_poolId);
pool.setFeeLibrary(_feeLibraryAddr);
}
function setSwapStop(uint256 _poolId, bool _swapStop) external onlyOwner {
Pool pool = _getPool(_poolId);
pool.setSwapStop(_swapStop);
}
function setDeltaParam(
uint256 _poolId,
bool _batched,
uint256 _swapDeltaBP,
uint256 _lpDeltaBP,
bool _defaultSwapMode,
bool _defaultLPMode
) external onlyOwner {
Pool pool = _getPool(_poolId);
pool.setDeltaParam(_batched, _swapDeltaBP, _lpDeltaBP, _defaultSwapMode, _defaultLPMode);
}
function callDelta(uint256 _poolId, bool _fullMode) external {
Pool pool = _getPool(_poolId);
pool.callDelta(_fullMode);
}
function withdrawMintFee(uint256 _poolId, address _to) external {
require(mintFeeOwner == msg.sender, "Stargate: only mintFeeOwner");
Pool pool = _getPool(_poolId);
pool.withdrawMintFeeBalance(_to);
}
function withdrawProtocolFee(uint256 _poolId, address _to) external {
require(protocolFeeOwner == msg.sender, "Stargate: only protocolFeeOwner");
Pool pool = _getPool(_poolId);
pool.withdrawProtocolFeeBalance(_to);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.5.0;
import "./ILayerZeroUserApplicationConfig.sol";
interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {
// @notice send a LayerZero message to the specified address at a LayerZero endpoint.
// @param _dstChainId - the destination chain identifier
// @param _destination - the address on destination chain (in bytes). address length/format may vary by chains
// @param _payload - a custom bytes payload to send to the destination contract
// @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address
// @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction
// @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination
function send(
uint16 _dstChainId,
bytes calldata _destination,
bytes calldata _payload,
address payable _refundAddress,
address _zroPaymentAddress,
bytes calldata _adapterParams
) external payable;
// @notice used by the messaging library to publish verified payload
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source contract (as bytes) at the source chain
// @param _dstAddress - the address on destination chain
// @param _nonce - the unbound message ordering nonce
// @param _gasLimit - the gas limit for external contract execution
// @param _payload - verified payload to send to the destination contract
function receivePayload(
uint16 _srcChainId,
bytes calldata _srcAddress,
address _dstAddress,
uint64 _nonce,
uint _gasLimit,
bytes calldata _payload
) external;
// @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source chain contract address
function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);
// @notice get the outboundNonce from this source chain which, consequently, is always an EVM
// @param _srcAddress - the source chain contract address
function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);
// @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery
// @param _dstChainId - the destination chain identifier
// @param _userApplication - the user app address on this EVM chain
// @param _payload - the custom message to send over LayerZero
// @param _payInZRO - if false, user app pays the protocol fee in native token
// @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain
function estimateFees(
uint16 _dstChainId,
address _userApplication,
bytes calldata _payload,
bool _payInZRO,
bytes calldata _adapterParam
) external view returns (uint nativeFee, uint zroFee);
// @notice get this Endpoint's immutable source identifier
function getChainId() external view returns (uint16);
// @notice the interface to retry failed message on this Endpoint destination
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source chain contract address
// @param _payload - the payload to be retried
function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;
// @notice query if any STORED payload (message blocking) at the endpoint.
// @param _srcChainId - the source chain identifier
// @param _srcAddress - the source chain contract address
function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);
// @notice query if the _libraryAddress is valid for sending msgs.
// @param _userApplication - the user app address on this EVM chain
function getSendLibraryAddress(address _userApplication) external view returns (address);
// @notice query if the _libraryAddress is valid for receiving msgs.
// @param _userApplication - the user app address on this EVM chain
function getReceiveLibraryAddress(address _userApplication) external view returns (address);
// @notice query if the non-reentrancy guard for send() is on
// @return true if the guard is on. false otherwise
function isSendingPayload() external view returns (bool);
// @notice query if the non-reentrancy guard for receive() is on
// @return true if the guard is on. false otherwise
function isReceivingPayload() external view returns (bool);
// @notice get the configuration of the LayerZero messaging library of the specified version
// @param _version - messaging library version
// @param _chainId - the chainId for the pending config change
// @param _userApplication - the contract address of the user application
// @param _configType - type of configuration. every messaging library has its own convention.
function getConfig(
uint16 _version,
uint16 _chainId,
address _userApplication,
uint _configType
) external view returns (bytes memory);
// @notice get the send() LayerZero messaging library version
// @param _userApplication - the contract address of the user application
function getSendVersion(address _userApplication) external view returns (uint16);
// @notice get the lzReceive() LayerZero messaging library version
// @param _userApplication - the contract address of the user application
function getReceiveVersion(address _userApplication) external view returns (uint16);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.5.0;
interface ILayerZeroReceiver {
// @notice LayerZero endpoint will invoke this function to deliver the message on the destination
// @param _srcChainId - the source endpoint identifier
// @param _srcAddress - the source sending contract address from the source chain
// @param _nonce - the ordered message nonce
// @param _payload - the signed payload is the UA bytes has encoded to be sent
function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.5.0;
interface ILayerZeroUserApplicationConfig {
// @notice set the configuration of the LayerZero messaging library of the specified version
// @param _version - messaging library version
// @param _chainId - the chainId for the pending config change
// @param _configType - type of configuration. every messaging library has its own convention.
// @param _config - configuration in the bytes. can encode arbitrary content.
function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external;
// @notice set the send() LayerZero messaging library version to _version
// @param _version - new messaging library version
function setSendVersion(uint16 _version) external;
// @notice set the lzReceive() LayerZero messaging library version to _version
// @param _version - new messaging library version
function setReceiveVersion(uint16 _version) external;
// @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload
// @param _srcChainId - the chainId of the source chain
// @param _srcAddress - the contract address of the source contract at the source chain
function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.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 () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), 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 {
emit OwnershipTransferred(_owner, address(0));
_owner = 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");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.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
pragma solidity ^0.7.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @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;
// solhint-disable-next-line no-inline-assembly
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");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(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");
// solhint-disable-next-line avoid-low-level-calls
(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");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <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 GSN 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 payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.7.6;
pragma abicoder v2;
// imports
import "@openzeppelin/contracts/access/Ownable.sol";
import "./Pool.sol";
import "./Router.sol";
// interfaces
import "@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroReceiver.sol";
import "@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroEndpoint.sol";
import "@layerzerolabs/lz-evm-v1-0.7/contracts/interfaces/ILayerZeroUserApplicationConfig.sol";
// libraries
import "@openzeppelin/contracts/math/SafeMath.sol";
contract Bridge is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {
using SafeMath for uint256;
//---------------------------------------------------------------------------
// CONSTANTS
uint8 internal constant TYPE_SWAP_REMOTE = 1;
uint8 internal constant TYPE_ADD_LIQUIDITY = 2;
uint8 internal constant TYPE_REDEEM_LOCAL_CALL_BACK = 3;
uint8 internal constant TYPE_WITHDRAW_REMOTE = 4;
//---------------------------------------------------------------------------
// VARIABLES
ILayerZeroEndpoint public immutable layerZeroEndpoint;
mapping(uint16 => bytes) public bridgeLookup;
mapping(uint16 => mapping(uint8 => uint256)) public gasLookup;
Router public immutable router;
bool public useLayerZeroToken;
//---------------------------------------------------------------------------
// EVENTS
event SendMsg(uint8 msgType, uint64 nonce);
//---------------------------------------------------------------------------
// MODIFIERS
modifier onlyRouter() {
require(msg.sender == address(router), "Stargate: caller must be Router.");
_;
}
constructor(address _layerZeroEndpoint, address _router) {
require(_layerZeroEndpoint != address(0x0), "Stargate: _layerZeroEndpoint cannot be 0x0");
require(_router != address(0x0), "Stargate: _router cannot be 0x0");
layerZeroEndpoint = ILayerZeroEndpoint(_layerZeroEndpoint);
router = Router(_router);
}
//---------------------------------------------------------------------------
// EXTERNAL functions
function lzReceive(
uint16 _srcChainId,
bytes memory _srcAddress,
uint64 _nonce,
bytes memory _payload
) external override {
require(msg.sender == address(layerZeroEndpoint), "Stargate: only LayerZero endpoint can call lzReceive");
require(
_srcAddress.length == bridgeLookup[_srcChainId].length && keccak256(_srcAddress) == keccak256(bridgeLookup[_srcChainId]),
"Stargate: bridge does not match"
);
uint8 functionType;
assembly {
functionType := mload(add(_payload, 32))
}
if (functionType == TYPE_SWAP_REMOTE) {
(
,
uint256 srcPoolId,
uint256 dstPoolId,
uint256 dstGasForCall,
Pool.CreditObj memory c,
Pool.SwapObj memory s,
bytes memory to,
bytes memory payload
) = abi.decode(_payload, (uint8, uint256, uint256, uint256, Pool.CreditObj, Pool.SwapObj, bytes, bytes));
address toAddress;
assembly {
toAddress := mload(add(to, 20))
}
router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c);
router.swapRemote(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, dstGasForCall, toAddress, s, payload);
} else if (functionType == TYPE_ADD_LIQUIDITY) {
(, uint256 srcPoolId, uint256 dstPoolId, Pool.CreditObj memory c) = abi.decode(_payload, (uint8, uint256, uint256, Pool.CreditObj));
router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c);
} else if (functionType == TYPE_REDEEM_LOCAL_CALL_BACK) {
(, uint256 srcPoolId, uint256 dstPoolId, Pool.CreditObj memory c, uint256 amountSD, uint256 mintAmountSD, bytes memory to) = abi
.decode(_payload, (uint8, uint256, uint256, Pool.CreditObj, uint256, uint256, bytes));
address toAddress;
assembly {
toAddress := mload(add(to, 20))
}
router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c);
router.redeemLocalCallback(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, toAddress, amountSD, mintAmountSD);
} else if (functionType == TYPE_WITHDRAW_REMOTE) {
(, uint256 srcPoolId, uint256 dstPoolId, Pool.CreditObj memory c, uint256 amountSD, bytes memory to) = abi.decode(
_payload,
(uint8, uint256, uint256, Pool.CreditObj, uint256, bytes)
);
router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c);
router.redeemLocalCheckOnRemote(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, amountSD, to);
}
}
//---------------------------------------------------------------------------
// LOCAL CHAIN FUNCTIONS
function swap(
uint16 _chainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
Pool.CreditObj memory _c,
Pool.SwapObj memory _s,
IStargateRouter.lzTxObj memory _lzTxParams,
bytes calldata _to,
bytes calldata _payload
) external payable onlyRouter {
bytes memory payload = abi.encode(TYPE_SWAP_REMOTE, _srcPoolId, _dstPoolId, _lzTxParams.dstGasForCall, _c, _s, _to, _payload);
_call(_chainId, TYPE_SWAP_REMOTE, _refundAddress, _lzTxParams, payload);
}
function redeemLocalCallback(
uint16 _chainId,
address payable _refundAddress,
Pool.CreditObj memory _c,
IStargateRouter.lzTxObj memory _lzTxParams,
bytes memory _payload
) external payable onlyRouter {
bytes memory payload;
{
(, uint256 srcPoolId, uint256 dstPoolId, uint256 amountSD, uint256 mintAmountSD, bytes memory to) = abi.decode(
_payload,
(uint8, uint256, uint256, uint256, uint256, bytes)
);
// swap dst and src because we are headed back
payload = abi.encode(TYPE_REDEEM_LOCAL_CALL_BACK, dstPoolId, srcPoolId, _c, amountSD, mintAmountSD, to);
}
_call(_chainId, TYPE_REDEEM_LOCAL_CALL_BACK, _refundAddress, _lzTxParams, payload);
}
function redeemLocal(
uint16 _chainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
Pool.CreditObj memory _c,
uint256 _amountSD,
bytes calldata _to,
IStargateRouter.lzTxObj memory _lzTxParams
) external payable onlyRouter {
bytes memory payload = abi.encode(TYPE_WITHDRAW_REMOTE, _srcPoolId, _dstPoolId, _c, _amountSD, _to);
_call(_chainId, TYPE_WITHDRAW_REMOTE, _refundAddress, _lzTxParams, payload);
}
function sendCredits(
uint16 _chainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
Pool.CreditObj memory _c
) external payable onlyRouter {
bytes memory payload = abi.encode(TYPE_ADD_LIQUIDITY, _srcPoolId, _dstPoolId, _c);
IStargateRouter.lzTxObj memory lzTxObj = IStargateRouter.lzTxObj(0, 0, "0x");
_call(_chainId, TYPE_ADD_LIQUIDITY, _refundAddress, lzTxObj, payload);
}
function quoteLayerZeroFee(
uint16 _chainId,
uint8 _functionType,
bytes calldata _toAddress,
bytes calldata _transferAndCallPayload,
IStargateRouter.lzTxObj memory _lzTxParams
) external view returns (uint256, uint256) {
bytes memory payload = "";
Pool.CreditObj memory c = Pool.CreditObj(1, 1);
if (_functionType == TYPE_SWAP_REMOTE) {
Pool.SwapObj memory s = Pool.SwapObj(1, 1, 1, 1, 1, 1);
payload = abi.encode(TYPE_SWAP_REMOTE, 0, 0, 0, c, s, _toAddress, _transferAndCallPayload);
} else if (_functionType == TYPE_ADD_LIQUIDITY) {
payload = abi.encode(TYPE_ADD_LIQUIDITY, 0, 0, c);
} else if (_functionType == TYPE_REDEEM_LOCAL_CALL_BACK) {
payload = abi.encode(TYPE_REDEEM_LOCAL_CALL_BACK, 0, 0, c, 0, 0, _toAddress);
} else if (_functionType == TYPE_WITHDRAW_REMOTE) {
payload = abi.encode(TYPE_WITHDRAW_REMOTE, 0, 0, c, 0, _toAddress);
} else {
revert("Stargate: unsupported function type");
}
bytes memory lzTxParamBuilt = _txParamBuilder(_chainId, _functionType, _lzTxParams);
return layerZeroEndpoint.estimateFees(_chainId, address(this), payload, useLayerZeroToken, lzTxParamBuilt);
}
//---------------------------------------------------------------------------
// dao functions
function setBridge(uint16 _chainId, bytes calldata _bridgeAddress) external onlyOwner {
require(bridgeLookup[_chainId].length == 0, "Stargate: Bridge already set!");
bridgeLookup[_chainId] = _bridgeAddress;
}
function setGasAmount(
uint16 _chainId,
uint8 _functionType,
uint256 _gasAmount
) external onlyOwner {
require(_functionType >= 1 && _functionType <= 4, "Stargate: invalid _functionType");
gasLookup[_chainId][_functionType] = _gasAmount;
}
function approveTokenSpender(
address token,
address spender,
uint256 amount
) external onlyOwner {
IERC20(token).approve(spender, amount);
}
function setUseLayerZeroToken(bool enable) external onlyOwner {
useLayerZeroToken = enable;
}
function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {
layerZeroEndpoint.forceResumeReceive(_srcChainId, _srcAddress);
}
//---------------------------------------------------------------------------
// generic config for user Application
function setConfig(
uint16 _version,
uint16 _chainId,
uint256 _configType,
bytes calldata _config
) external override onlyOwner {
layerZeroEndpoint.setConfig(_version, _chainId, _configType, _config);
}
function setSendVersion(uint16 version) external override onlyOwner {
layerZeroEndpoint.setSendVersion(version);
}
function setReceiveVersion(uint16 version) external override onlyOwner {
layerZeroEndpoint.setReceiveVersion(version);
}
//---------------------------------------------------------------------------
// INTERNAL functions
function txParamBuilderType1(uint256 _gasAmount) internal pure returns (bytes memory) {
uint16 txType = 1;
return abi.encodePacked(txType, _gasAmount);
}
function txParamBuilderType2(
uint256 _gasAmount,
uint256 _dstNativeAmount,
bytes memory _dstNativeAddr
) internal pure returns (bytes memory) {
uint16 txType = 2;
return abi.encodePacked(txType, _gasAmount, _dstNativeAmount, _dstNativeAddr);
}
function _txParamBuilder(
uint16 _chainId,
uint8 _type,
IStargateRouter.lzTxObj memory _lzTxParams
) internal view returns (bytes memory) {
bytes memory lzTxParam;
address dstNativeAddr;
{
bytes memory dstNativeAddrBytes = _lzTxParams.dstNativeAddr;
assembly {
dstNativeAddr := mload(add(dstNativeAddrBytes, 20))
}
}
uint256 totalGas = gasLookup[_chainId][_type].add(_lzTxParams.dstGasForCall);
if (_lzTxParams.dstNativeAmount > 0 && dstNativeAddr != address(0x0)) {
lzTxParam = txParamBuilderType2(totalGas, _lzTxParams.dstNativeAmount, _lzTxParams.dstNativeAddr);
} else {
lzTxParam = txParamBuilderType1(totalGas);
}
return lzTxParam;
}
function _call(
uint16 _chainId,
uint8 _type,
address payable _refundAddress,
IStargateRouter.lzTxObj memory _lzTxParams,
bytes memory _payload
) internal {
bytes memory lzTxParamBuilt = _txParamBuilder(_chainId, _type, _lzTxParams);
uint64 nextNonce = layerZeroEndpoint.getOutboundNonce(_chainId, address(this)) + 1;
layerZeroEndpoint.send{value: msg.value}(_chainId, bridgeLookup[_chainId], _payload, _refundAddress, address(this), lzTxParamBuilt);
emit SendMsg(_type, nextNonce);
}
function renounceOwnership() public override onlyOwner {}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.7.6;
pragma abicoder v2;
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./Pool.sol";
contract Factory is Ownable {
using SafeMath for uint256;
//---------------------------------------------------------------------------
// VARIABLES
mapping(uint256 => Pool) public getPool; // poolId -> PoolInfo
address[] public allPools;
address public immutable router;
address public defaultFeeLibrary; // address for retrieving fee params for swaps
//---------------------------------------------------------------------------
// MODIFIERS
modifier onlyRouter() {
require(msg.sender == router, "Stargate: caller must be Router.");
_;
}
constructor(address _router) {
require(_router != address(0x0), "Stargate: _router cant be 0x0"); // 1 time only
router = _router;
}
function setDefaultFeeLibrary(address _defaultFeeLibrary) external onlyOwner {
require(_defaultFeeLibrary != address(0x0), "Stargate: fee library cant be 0x0");
defaultFeeLibrary = _defaultFeeLibrary;
}
function allPoolsLength() external view returns (uint256) {
return allPools.length;
}
function createPool(
uint256 _poolId,
address _token,
uint8 _sharedDecimals,
uint8 _localDecimals,
string memory _name,
string memory _symbol
) public onlyRouter returns (address poolAddress) {
require(address(getPool[_poolId]) == address(0x0), "Stargate: Pool already created");
Pool pool = new Pool(_poolId, router, _token, _sharedDecimals, _localDecimals, defaultFeeLibrary, _name, _symbol);
getPool[_poolId] = pool;
poolAddress = address(pool);
allPools.push(poolAddress);
}
function renounceOwnership() public override onlyOwner {}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.7.6;
// libraries
import "@openzeppelin/contracts/math/SafeMath.sol";
contract LPTokenERC20 {
using SafeMath for uint256;
//---------------------------------------------------------------------------
// CONSTANTS
string public name;
string public symbol;
bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
// set in constructor
bytes32 public DOMAIN_SEPARATOR;
//---------------------------------------------------------------------------
// VARIABLES
uint256 public decimals;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
mapping(address => uint256) public nonces;
//---------------------------------------------------------------------------
// EVENTS
event Approval(address indexed owner, address indexed spender, uint256 value);
event Transfer(address indexed from, address indexed to, uint256 value);
constructor(string memory _name, string memory _symbol) {
name = _name;
symbol = _symbol;
uint256 chainId;
assembly {
chainId := chainid()
}
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256(bytes("1")),
chainId,
address(this)
)
);
}
function _mint(address to, uint256 value) internal {
totalSupply = totalSupply.add(value);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(address(0), to, value);
}
function _burn(address from, uint256 value) internal {
balanceOf[from] = balanceOf[from].sub(value);
totalSupply = totalSupply.sub(value);
emit Transfer(from, address(0), value);
}
function _approve(
address owner,
address spender,
uint256 value
) private {
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
}
function _transfer(
address from,
address to,
uint256 value
) private {
balanceOf[from] = balanceOf[from].sub(value);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(from, to, value);
}
function approve(address spender, uint256 value) external returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
function transfer(address to, uint256 value) external returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool) {
if (allowance[from][msg.sender] != uint256(-1)) {
allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
}
_transfer(from, to, value);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(msg.sender, spender, allowance[msg.sender][spender].add(addedValue));
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(msg.sender, spender, allowance[msg.sender][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external {
require(deadline >= block.timestamp, "Bridge: EXPIRED");
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == owner, "Bridge: INVALID_SIGNATURE");
_approve(owner, spender, value);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.7.6;
pragma abicoder v2;
// imports
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "./LPTokenERC20.sol";
import "./interfaces/IStargateFeeLibrary.sol";
// libraries
import "@openzeppelin/contracts/math/SafeMath.sol";
/// Pool contracts on other chains and managed by the Stargate protocol.
contract Pool is LPTokenERC20, ReentrancyGuard {
using SafeMath for uint256;
//---------------------------------------------------------------------------
// CONSTANTS
bytes4 private constant SELECTOR = bytes4(keccak256(bytes("transfer(address,uint256)")));
uint256 public constant BP_DENOMINATOR = 10000;
//---------------------------------------------------------------------------
// STRUCTS
struct ChainPath {
bool ready; // indicate if the counter chainPath has been created.
uint16 dstChainId;
uint256 dstPoolId;
uint256 weight;
uint256 balance;
uint256 lkb;
uint256 credits;
uint256 idealBalance;
}
struct SwapObj {
uint256 amount;
uint256 eqFee;
uint256 eqReward;
uint256 lpFee;
uint256 protocolFee;
uint256 lkbRemove;
}
struct CreditObj {
uint256 credits;
uint256 idealBalance;
}
//---------------------------------------------------------------------------
// VARIABLES
// chainPath
ChainPath[] public chainPaths; // list of connected chains with shared pools
mapping(uint16 => mapping(uint256 => uint256)) public chainPathIndexLookup; // lookup for chainPath by chainId => poolId =>index
// metadata
uint256 public immutable poolId; // shared id between chains to represent same pool
uint256 public sharedDecimals; // the shared decimals (lowest common decimals between chains)
uint256 public localDecimals; // the decimals for the token
uint256 public immutable convertRate; // the decimals for the token
address public immutable token; // the token for the pool
address public immutable router; // the token for the pool
bool public stopSwap; // flag to stop swapping in extreme cases
// Fee and Liquidity
uint256 public totalLiquidity; // the total amount of tokens added on this side of the chain (fees + deposits - withdrawals)
uint256 public totalWeight; // total weight for pool percentages
uint256 public mintFeeBP; // fee basis points for the mint/deposit
uint256 public protocolFeeBalance; // fee balance created from dao fee
uint256 public mintFeeBalance; // fee balance created from mint fee
uint256 public eqFeePool; // pool rewards in Shared Decimal format. indicate the total budget for reverse swap incentive
address public feeLibrary; // address for retrieving fee params for swaps
// Delta related
uint256 public deltaCredit; // credits accumulated from txn
bool public batched; // flag to indicate if we want batch processing.
bool public defaultSwapMode; // flag for the default mode for swap
bool public defaultLPMode; // flag for the default mode for lp
uint256 public swapDeltaBP; // basis points of poolCredits to activate Delta in swap
uint256 public lpDeltaBP; // basis points of poolCredits to activate Delta in liquidity events
//---------------------------------------------------------------------------
// EVENTS
event Mint(address to, uint256 amountLP, uint256 amountSD, uint256 mintFeeAmountSD);
event Burn(address from, uint256 amountLP, uint256 amountSD);
event RedeemLocalCallback(address _to, uint256 _amountSD, uint256 _amountToMintSD);
event Swap(
uint16 chainId,
uint256 dstPoolId,
address from,
uint256 amountSD,
uint256 eqReward,
uint256 eqFee,
uint256 protocolFee,
uint256 lpFee
);
event SendCredits(uint16 dstChainId, uint256 dstPoolId, uint256 credits, uint256 idealBalance);
event RedeemRemote(uint16 chainId, uint256 dstPoolId, address from, uint256 amountLP, uint256 amountSD);
event RedeemLocal(address from, uint256 amountLP, uint256 amountSD, uint16 chainId, uint256 dstPoolId, bytes to);
event InstantRedeemLocal(address from, uint256 amountLP, uint256 amountSD, address to);
event CreditChainPath(uint16 chainId, uint256 srcPoolId, uint256 amountSD, uint256 idealBalance);
event SwapRemote(address to, uint256 amountSD, uint256 protocolFee, uint256 dstFee);
event WithdrawRemote(uint16 srcChainId, uint256 srcPoolId, uint256 swapAmount, uint256 mintAmount);
event ChainPathUpdate(uint16 dstChainId, uint256 dstPoolId, uint256 weight);
event FeesUpdated(uint256 mintFeeBP);
event FeeLibraryUpdated(address feeLibraryAddr);
event StopSwapUpdated(bool swapStop);
event WithdrawProtocolFeeBalance(address to, uint256 amountSD);
event WithdrawMintFeeBalance(address to, uint256 amountSD);
event DeltaParamUpdated(bool batched, uint256 swapDeltaBP, uint256 lpDeltaBP, bool defaultSwapMode, bool defaultLPMode);
//---------------------------------------------------------------------------
// MODIFIERS
modifier onlyRouter() {
require(msg.sender == router, "Stargate: only the router can call this method");
_;
}
constructor(
uint256 _poolId,
address _router,
address _token,
uint256 _sharedDecimals,
uint256 _localDecimals,
address _feeLibrary,
string memory _name,
string memory _symbol
) LPTokenERC20(_name, _symbol) {
require(_token != address(0x0), "Stargate: _token cannot be 0x0");
require(_router != address(0x0), "Stargate: _router cannot be 0x0");
poolId = _poolId;
router = _router;
token = _token;
sharedDecimals = _sharedDecimals;
decimals = uint8(_sharedDecimals);
localDecimals = _localDecimals;
convertRate = 10**(uint256(localDecimals).sub(sharedDecimals));
totalWeight = 0;
feeLibrary = _feeLibrary;
//delta algo related
batched = false;
defaultSwapMode = true;
defaultLPMode = true;
}
function getChainPathsLength() public view returns (uint256) {
return chainPaths.length;
}
//---------------------------------------------------------------------------
// LOCAL CHAIN FUNCTIONS
function mint(address _to, uint256 _amountLD) external nonReentrant onlyRouter returns (uint256) {
return _mintLocal(_to, _amountLD, true, true);
}
// Local Remote
// ------- ---------
// swap -> swapRemote
function swap(
uint16 _dstChainId,
uint256 _dstPoolId,
address _from,
uint256 _amountLD,
uint256 _minAmountLD,
bool newLiquidity
) external nonReentrant onlyRouter returns (SwapObj memory) {
require(!stopSwap, "Stargate: swap func stopped");
ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);
require(cp.ready == true, "Stargate: counter chainPath is not ready");
uint256 amountSD = amountLDtoSD(_amountLD);
uint256 minAmountSD = amountLDtoSD(_minAmountLD);
// request fee params from library
SwapObj memory s = IStargateFeeLibrary(feeLibrary).getFees(poolId, _dstPoolId, _dstChainId, _from, amountSD);
// equilibrium fee and reward. note eqFee/eqReward are separated from swap liquidity
eqFeePool = eqFeePool.sub(s.eqReward);
// update the new amount the user gets minus the fees
s.amount = amountSD.sub(s.eqFee).sub(s.protocolFee).sub(s.lpFee);
// users will also get the eqReward
require(s.amount.add(s.eqReward) >= minAmountSD, "Stargate: slippage too high");
// behaviours
// - protocolFee: booked, stayed and withdrawn at remote.
// - eqFee: booked, stayed and withdrawn at remote.
// - lpFee: booked and stayed at remote, can be withdrawn anywhere
s.lkbRemove = amountSD.sub(s.lpFee).add(s.eqReward);
// check for transfer solvency.
require(cp.balance >= s.lkbRemove, "Stargate: dst balance too low");
cp.balance = cp.balance.sub(s.lkbRemove);
if (newLiquidity) {
deltaCredit = deltaCredit.add(amountSD).add(s.eqReward);
} else if (s.eqReward > 0) {
deltaCredit = deltaCredit.add(s.eqReward);
}
// distribute credits on condition.
if (!batched || deltaCredit >= totalLiquidity.mul(swapDeltaBP).div(BP_DENOMINATOR)) {
_delta(defaultSwapMode);
}
emit Swap(_dstChainId, _dstPoolId, _from, s.amount, s.eqReward, s.eqFee, s.protocolFee, s.lpFee);
return s;
}
// Local Remote
// ------- ---------
// sendCredits -> creditChainPath
function sendCredits(uint16 _dstChainId, uint256 _dstPoolId) external nonReentrant onlyRouter returns (CreditObj memory c) {
ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);
require(cp.ready == true, "Stargate: counter chainPath is not ready");
cp.lkb = cp.lkb.add(cp.credits);
c.idealBalance = totalLiquidity.mul(cp.weight).div(totalWeight);
c.credits = cp.credits;
cp.credits = 0;
emit SendCredits(_dstChainId, _dstPoolId, c.credits, c.idealBalance);
}
// Local Remote
// ------- ---------
// redeemRemote -> swapRemote
function redeemRemote(
uint16 _dstChainId,
uint256 _dstPoolId,
address _from,
uint256 _amountLP
) external nonReentrant onlyRouter {
require(_from != address(0x0), "Stargate: _from cannot be 0x0");
uint256 amountSD = _burnLocal(_from, _amountLP);
//run Delta
if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) {
_delta(defaultLPMode);
}
uint256 amountLD = amountSDtoLD(amountSD);
emit RedeemRemote(_dstChainId, _dstPoolId, _from, _amountLP, amountLD);
}
function instantRedeemLocal(
address _from,
uint256 _amountLP,
address _to
) external nonReentrant onlyRouter returns (uint256 amountSD) {
require(_from != address(0x0), "Stargate: _from cannot be 0x0");
uint256 _deltaCredit = deltaCredit; // sload optimization.
uint256 _capAmountLP = _amountSDtoLP(_deltaCredit);
if (_amountLP > _capAmountLP) _amountLP = _capAmountLP;
amountSD = _burnLocal(_from, _amountLP);
deltaCredit = _deltaCredit.sub(amountSD);
uint256 amountLD = amountSDtoLD(amountSD);
_safeTransfer(token, _to, amountLD);
emit InstantRedeemLocal(_from, _amountLP, amountSD, _to);
}
// Local Remote
// ------- ---------
// redeemLocal -> redeemLocalCheckOnRemote
// redeemLocalCallback <-
function redeemLocal(
address _from,
uint256 _amountLP,
uint16 _dstChainId,
uint256 _dstPoolId,
bytes calldata _to
) external nonReentrant onlyRouter returns (uint256 amountSD) {
require(_from != address(0x0), "Stargate: _from cannot be 0x0");
// safeguard.
require(chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]].ready == true, "Stargate: counter chainPath is not ready");
amountSD = _burnLocal(_from, _amountLP);
// run Delta
if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) {
_delta(false);
}
emit RedeemLocal(_from, _amountLP, amountSD, _dstChainId, _dstPoolId, _to);
}
//---------------------------------------------------------------------------
// REMOTE CHAIN FUNCTIONS
// Local Remote
// ------- ---------
// sendCredits -> creditChainPath
function creditChainPath(
uint16 _dstChainId,
uint256 _dstPoolId,
CreditObj memory _c
) external nonReentrant onlyRouter {
ChainPath storage cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]];
cp.balance = cp.balance.add(_c.credits);
if (cp.idealBalance != _c.idealBalance) {
cp.idealBalance = _c.idealBalance;
}
emit CreditChainPath(_dstChainId, _dstPoolId, _c.credits, _c.idealBalance);
}
// Local Remote
// ------- ---------
// swap -> swapRemote
function swapRemote(
uint16 _srcChainId,
uint256 _srcPoolId,
address _to,
SwapObj memory _s
) external nonReentrant onlyRouter returns (uint256 amountLD) {
// booking lpFee
totalLiquidity = totalLiquidity.add(_s.lpFee);
// booking eqFee
eqFeePool = eqFeePool.add(_s.eqFee);
// booking stargateFee
protocolFeeBalance = protocolFeeBalance.add(_s.protocolFee);
// update LKB
uint256 chainPathIndex = chainPathIndexLookup[_srcChainId][_srcPoolId];
chainPaths[chainPathIndex].lkb = chainPaths[chainPathIndex].lkb.sub(_s.lkbRemove);
// user receives the amount + the srcReward
amountLD = amountSDtoLD(_s.amount.add(_s.eqReward));
_safeTransfer(token, _to, amountLD);
emit SwapRemote(_to, _s.amount.add(_s.eqReward), _s.protocolFee, _s.eqFee);
}
// Local Remote
// ------- ---------
// redeemLocal -> redeemLocalCheckOnRemote
// redeemLocalCallback <-
function redeemLocalCallback(
uint16 _srcChainId,
uint256 _srcPoolId,
address _to,
uint256 _amountSD,
uint256 _amountToMintSD
) external nonReentrant onlyRouter {
if (_amountToMintSD > 0) {
_mintLocal(_to, amountSDtoLD(_amountToMintSD), false, false);
}
ChainPath storage cp = getAndCheckCP(_srcChainId, _srcPoolId);
cp.lkb = cp.lkb.sub(_amountSD);
uint256 amountLD = amountSDtoLD(_amountSD);
_safeTransfer(token, _to, amountLD);
emit RedeemLocalCallback(_to, _amountSD, _amountToMintSD);
}
// Local Remote
// ------- ---------
// redeemLocal(amount) -> redeemLocalCheckOnRemote
// redeemLocalCallback <-
function redeemLocalCheckOnRemote(
uint16 _srcChainId,
uint256 _srcPoolId,
uint256 _amountSD
) external nonReentrant onlyRouter returns (uint256 swapAmount, uint256 mintAmount) {
ChainPath storage cp = getAndCheckCP(_srcChainId, _srcPoolId);
if (_amountSD > cp.balance) {
mintAmount = _amountSD - cp.balance;
swapAmount = cp.balance;
cp.balance = 0;
} else {
cp.balance = cp.balance.sub(_amountSD);
swapAmount = _amountSD;
mintAmount = 0;
}
emit WithdrawRemote(_srcChainId, _srcPoolId, swapAmount, mintAmount);
}
//---------------------------------------------------------------------------
// DAO Calls
function createChainPath(
uint16 _dstChainId,
uint256 _dstPoolId,
uint256 _weight
) external onlyRouter {
for (uint256 i = 0; i < chainPaths.length; ++i) {
ChainPath memory cp = chainPaths[i];
bool exists = cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId;
require(!exists, "Stargate: cant createChainPath of existing dstChainId and _dstPoolId");
}
totalWeight = totalWeight.add(_weight);
chainPathIndexLookup[_dstChainId][_dstPoolId] = chainPaths.length;
chainPaths.push(ChainPath(false, _dstChainId, _dstPoolId, _weight, 0, 0, 0, 0));
emit ChainPathUpdate(_dstChainId, _dstPoolId, _weight);
}
function setWeightForChainPath(
uint16 _dstChainId,
uint256 _dstPoolId,
uint16 _weight
) external onlyRouter {
ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);
totalWeight = totalWeight.sub(cp.weight).add(_weight);
cp.weight = _weight;
emit ChainPathUpdate(_dstChainId, _dstPoolId, _weight);
}
function setFee(uint256 _mintFeeBP) external onlyRouter {
require(_mintFeeBP <= BP_DENOMINATOR, "Bridge: cum fees > 100%");
mintFeeBP = _mintFeeBP;
emit FeesUpdated(mintFeeBP);
}
function setFeeLibrary(address _feeLibraryAddr) external onlyRouter {
require(_feeLibraryAddr != address(0x0), "Stargate: fee library cant be 0x0");
feeLibrary = _feeLibraryAddr;
emit FeeLibraryUpdated(_feeLibraryAddr);
}
function setSwapStop(bool _swapStop) external onlyRouter {
stopSwap = _swapStop;
emit StopSwapUpdated(_swapStop);
}
function setDeltaParam(
bool _batched,
uint256 _swapDeltaBP,
uint256 _lpDeltaBP,
bool _defaultSwapMode,
bool _defaultLPMode
) external onlyRouter {
require(_swapDeltaBP <= BP_DENOMINATOR && _lpDeltaBP <= BP_DENOMINATOR, "Stargate: wrong Delta param");
batched = _batched;
swapDeltaBP = _swapDeltaBP;
lpDeltaBP = _lpDeltaBP;
defaultSwapMode = _defaultSwapMode;
defaultLPMode = _defaultLPMode;
emit DeltaParamUpdated(_batched, _swapDeltaBP, _lpDeltaBP, _defaultSwapMode, _defaultLPMode);
}
function callDelta(bool _fullMode) external onlyRouter {
_delta(_fullMode);
}
function activateChainPath(uint16 _dstChainId, uint256 _dstPoolId) external onlyRouter {
ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);
require(cp.ready == false, "Stargate: chainPath is already active");
// this func will only be called once
cp.ready = true;
}
function withdrawProtocolFeeBalance(address _to) external onlyRouter {
if (protocolFeeBalance > 0) {
uint256 amountOfLD = amountSDtoLD(protocolFeeBalance);
protocolFeeBalance = 0;
_safeTransfer(token, _to, amountOfLD);
emit WithdrawProtocolFeeBalance(_to, amountOfLD);
}
}
function withdrawMintFeeBalance(address _to) external onlyRouter {
if (mintFeeBalance > 0) {
uint256 amountOfLD = amountSDtoLD(mintFeeBalance);
mintFeeBalance = 0;
_safeTransfer(token, _to, amountOfLD);
emit WithdrawMintFeeBalance(_to, amountOfLD);
}
}
//---------------------------------------------------------------------------
// INTERNAL
// Conversion Helpers
//---------------------------------------------------------------------------
function amountLPtoLD(uint256 _amountLP) external view returns (uint256) {
return amountSDtoLD(_amountLPtoSD(_amountLP));
}
function _amountLPtoSD(uint256 _amountLP) internal view returns (uint256) {
require(totalSupply > 0, "Stargate: cant convert LPtoSD when totalSupply == 0");
return _amountLP.mul(totalLiquidity).div(totalSupply);
}
function _amountSDtoLP(uint256 _amountSD) internal view returns (uint256) {
require(totalLiquidity > 0, "Stargate: cant convert SDtoLP when totalLiq == 0");
return _amountSD.mul(totalSupply).div(totalLiquidity);
}
function amountSDtoLD(uint256 _amount) internal view returns (uint256) {
return _amount.mul(convertRate);
}
function amountLDtoSD(uint256 _amount) internal view returns (uint256) {
return _amount.div(convertRate);
}
function getAndCheckCP(uint16 _dstChainId, uint256 _dstPoolId) internal view returns (ChainPath storage) {
require(chainPaths.length > 0, "Stargate: no chainpaths exist");
ChainPath storage cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]];
require(cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId, "Stargate: local chainPath does not exist");
return cp;
}
function getChainPath(uint16 _dstChainId, uint256 _dstPoolId) external view returns (ChainPath memory) {
ChainPath memory cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]];
require(cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId, "Stargate: local chainPath does not exist");
return cp;
}
function _burnLocal(address _from, uint256 _amountLP) internal returns (uint256) {
require(totalSupply > 0, "Stargate: cant burn when totalSupply == 0");
uint256 amountOfLPTokens = balanceOf[_from];
require(amountOfLPTokens >= _amountLP, "Stargate: not enough LP tokens to burn");
uint256 amountSD = _amountLP.mul(totalLiquidity).div(totalSupply);
//subtract totalLiquidity accordingly
totalLiquidity = totalLiquidity.sub(amountSD);
_burn(_from, _amountLP);
emit Burn(_from, _amountLP, amountSD);
return amountSD;
}
function _delta(bool fullMode) internal {
if (deltaCredit > 0 && totalWeight > 0) {
uint256 cpLength = chainPaths.length;
uint256[] memory deficit = new uint256[](cpLength);
uint256 totalDeficit = 0;
// algorithm steps 6-9: calculate the total and the amounts required to get to balance state
for (uint256 i = 0; i < cpLength; ++i) {
ChainPath storage cp = chainPaths[i];
// (liquidity * (weight/totalWeight)) - (lkb+credits)
uint256 balLiq = totalLiquidity.mul(cp.weight).div(totalWeight);
uint256 currLiq = cp.lkb.add(cp.credits);
if (balLiq > currLiq) {
// save gas since we know balLiq > currLiq and we know deficit[i] > 0
deficit[i] = balLiq - currLiq;
totalDeficit = totalDeficit.add(deficit[i]);
}
}
// indicates how much delta credit is distributed
uint256 spent;
// handle credits with 2 tranches. the [ < totalDeficit] [excessCredit]
// run full Delta, allocate all credits
if (totalDeficit == 0) {
// only fullMode delta will allocate excess credits
if (fullMode && deltaCredit > 0) {
// credit ChainPath by weights
for (uint256 i = 0; i < cpLength; ++i) {
ChainPath storage cp = chainPaths[i];
// credits = credits + toBalanceChange + remaining allocation based on weight
uint256 amtToCredit = deltaCredit.mul(cp.weight).div(totalWeight);
spent = spent.add(amtToCredit);
cp.credits = cp.credits.add(amtToCredit);
}
} // else do nth
} else if (totalDeficit <= deltaCredit) {
if (fullMode) {
// algorithm step 13: calculate amount to disperse to bring to balance state or as close as possible
uint256 excessCredit = deltaCredit - totalDeficit;
// algorithm steps 14-16: calculate credits
for (uint256 i = 0; i < cpLength; ++i) {
if (deficit[i] > 0) {
ChainPath storage cp = chainPaths[i];
// credits = credits + deficit + remaining allocation based on weight
uint256 amtToCredit = deficit[i].add(excessCredit.mul(cp.weight).div(totalWeight));
spent = spent.add(amtToCredit);
cp.credits = cp.credits.add(amtToCredit);
}
}
} else {
// totalDeficit <= deltaCredit but not running fullMode
// credit chainPaths as is if any deficit, not using all deltaCredit
for (uint256 i = 0; i < cpLength; ++i) {
if (deficit[i] > 0) {
ChainPath storage cp = chainPaths[i];
uint256 amtToCredit = deficit[i];
spent = spent.add(amtToCredit);
cp.credits = cp.credits.add(amtToCredit);
}
}
}
} else {
// totalDeficit > deltaCredit, fullMode or not, normalize the deficit by deltaCredit
for (uint256 i = 0; i < cpLength; ++i) {
if (deficit[i] > 0) {
ChainPath storage cp = chainPaths[i];
uint256 proportionalDeficit = deficit[i].mul(deltaCredit).div(totalDeficit);
spent = spent.add(proportionalDeficit);
cp.credits = cp.credits.add(proportionalDeficit);
}
}
}
// deduct the amount of credit sent
deltaCredit = deltaCredit.sub(spent);
}
}
function _mintLocal(
address _to,
uint256 _amountLD,
bool _feesEnabled,
bool _creditDelta
) internal returns (uint256 amountSD) {
require(totalWeight > 0, "Stargate: No ChainPaths exist");
amountSD = amountLDtoSD(_amountLD);
uint256 mintFeeSD = 0;
if (_feesEnabled) {
mintFeeSD = amountSD.mul(mintFeeBP).div(BP_DENOMINATOR);
amountSD = amountSD.sub(mintFeeSD);
mintFeeBalance = mintFeeBalance.add(mintFeeSD);
}
if (_creditDelta) {
deltaCredit = deltaCredit.add(amountSD);
}
uint256 amountLPTokens = amountSD;
if (totalSupply != 0) {
amountLPTokens = amountSD.mul(totalSupply).div(totalLiquidity);
}
totalLiquidity = totalLiquidity.add(amountSD);
_mint(_to, amountLPTokens);
emit Mint(_to, amountLPTokens, amountSD, mintFeeSD);
// add to credits and call delta. short circuit to save gas
if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) {
_delta(defaultLPMode);
}
}
function _safeTransfer(
address _token,
address _to,
uint256 _value
) private {
(bool success, bytes memory data) = _token.call(abi.encodeWithSelector(SELECTOR, _to, _value));
require(success && (data.length == 0 || abi.decode(data, (bool))), "Stargate: TRANSFER_FAILED");
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.7.6;
pragma abicoder v2;
import "../Pool.sol";
interface IStargateFeeLibrary {
function getFees(
uint256 _srcPoolId,
uint256 _dstPoolId,
uint16 _dstChainId,
address _from,
uint256 _amountSD
) external returns (Pool.SwapObj memory s);
function getVersion() external view returns (string memory);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.7.6 <=0.8.4;
interface IStargateReceiver {
function sgReceive(
uint16 _chainId,
bytes memory _srcAddress,
uint256 _nonce,
address _token,
uint256 amountLD,
bytes memory payload
) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.7.6 <=0.8.4;
pragma abicoder v2;
interface IStargateRouter {
struct lzTxObj {
uint256 dstGasForCall;
uint256 dstNativeAmount;
bytes dstNativeAddr;
}
function addLiquidity(
uint256 _poolId,
uint256 _amountLD,
address _to
) external;
function swap(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLD,
uint256 _minAmountLD,
lzTxObj memory _lzTxParams,
bytes calldata _to,
bytes calldata _payload
) external payable;
function redeemRemote(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLP,
uint256 _minAmountLD,
bytes calldata _to,
lzTxObj memory _lzTxParams
) external payable;
function instantRedeemLocal(
uint16 _srcPoolId,
uint256 _amountLP,
address _to
) external returns (uint256);
function redeemLocal(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress,
uint256 _amountLP,
bytes calldata _to,
lzTxObj memory _lzTxParams
) external payable;
function sendCredits(
uint16 _dstChainId,
uint256 _srcPoolId,
uint256 _dstPoolId,
address payable _refundAddress
) external payable;
function quoteLayerZeroFee(
uint16 _dstChainId,
uint8 _functionType,
bytes calldata _toAddress,
bytes calldata _transferAndCallPayload,
lzTxObj memory _lzTxParams
) external view returns (uint256, uint256);
}{
"evmVersion": "istanbul",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountLD","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes","name":"payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"}],"name":"CachedSwapSaved","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":"uint16","name":"srcChainId","type":"uint16"},{"indexed":true,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"srcPoolId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dstPoolId","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintAmountSD","type":"uint256"}],"name":"RedeemLocalCallback","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"bridgeFunctionType","type":"uint8"},{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"Revert","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"to","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"redeemAmountSD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintAmountSD","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"bytes","name":"srcAddress","type":"bytes"}],"name":"RevertRedeemLocal","type":"event"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"}],"name":"activateChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint256","name":"_amountLD","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"addLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract Bridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"cachedSwapLookup","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"payload","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"bool","name":"_fullMode","type":"bool"}],"name":"callDelta","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"clearCachedSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_weight","type":"uint256"}],"name":"createChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint8","name":"_sharedDecimals","type":"uint8"},{"internalType":"uint8","name":"_localDecimals","type":"uint8"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"createPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"components":[{"internalType":"uint256","name":"credits","type":"uint256"},{"internalType":"uint256","name":"idealBalance","type":"uint256"}],"internalType":"struct Pool.CreditObj","name":"_c","type":"tuple"}],"name":"creditChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcPoolId","type":"uint16"},{"internalType":"uint256","name":"_amountLP","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"instantRedeemLocal","outputs":[{"internalType":"uint256","name":"amountSD","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintFeeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint8","name":"_functionType","type":"uint8"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"bytes","name":"_transferAndCallPayload","type":"bytes"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"quoteLayerZeroFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"uint256","name":"_amountLP","type":"uint256"},{"internalType":"bytes","name":"_to","type":"bytes"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"redeemLocal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amountSD","type":"uint256"},{"internalType":"uint256","name":"_mintAmountSD","type":"uint256"}],"name":"redeemLocalCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_amountSD","type":"uint256"},{"internalType":"bytes","name":"_to","type":"bytes"}],"name":"redeemLocalCheckOnRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"uint256","name":"_amountLP","type":"uint256"},{"internalType":"uint256","name":"_minAmountLD","type":"uint256"},{"internalType":"bytes","name":"_to","type":"bytes"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"redeemRemote","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"retryRevert","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"revertLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"revertRedeemLocal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"}],"name":"sendCredits","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract Bridge","name":"_bridge","type":"address"},{"internalType":"contract Factory","name":"_factory","type":"address"}],"name":"setBridgeAndFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"bool","name":"_batched","type":"bool"},{"internalType":"uint256","name":"_swapDeltaBP","type":"uint256"},{"internalType":"uint256","name":"_lpDeltaBP","type":"uint256"},{"internalType":"bool","name":"_defaultSwapMode","type":"bool"},{"internalType":"bool","name":"_defaultLPMode","type":"bool"}],"name":"setDeltaParam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_feeLibraryAddr","type":"address"}],"name":"setFeeLibrary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint256","name":"_mintFeeBP","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setMintFeeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setProtocolFeeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"bool","name":"_swapStop","type":"bool"}],"name":"setSwapStop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint16","name":"_weight","type":"uint16"}],"name":"setWeightForChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"uint256","name":"_amountLD","type":"uint256"},{"internalType":"uint256","name":"_minAmountLD","type":"uint256"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"},{"internalType":"bytes","name":"_to","type":"bytes"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"swap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstGasForCall","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"eqFee","type":"uint256"},{"internalType":"uint256","name":"eqReward","type":"uint256"},{"internalType":"uint256","name":"lpFee","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"uint256","name":"lkbRemove","type":"uint256"}],"internalType":"struct Pool.SwapObj","name":"_s","type":"tuple"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"swapRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawMintFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawProtocolFee","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b5060006200001e62000072565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001805562000076565b3390565b6151c980620000866000396000f3fe60806040526004361061021a5760003560e01c806387b21efc11610123578063c45a0155116100ab578063cefbdde21161006f578063cefbdde2146105dd578063da133a06146105fd578063e78cea921461062a578063f2fde38b1461063f578063fba6e2801461065f5761021a565b8063c45a01551461053b578063c4de93a514610550578063c6a276241461057d578063c7d968e31461059d578063c8adf12d146105bd5761021a565b80639ba3aa74116100f25780639ba3aa74146104cb5780639fbf10fc146104de578063a18fa804146104f1578063a96fbed414610511578063af640d82146105265761021a565b806387b21efc146104635780638da5cb5b146104835780638f2e1d181461049857806398e391a1146104ab5761021a565b806343a30630116101a6578063715018a611610175578063715018a6146103ce5780637af935a1146103e35780637b84d287146104105780637f7212981461043057806384d0dba3146104505761021a565b806343a30630146103685780635500585c1461038857806360a3b95c146103a85780636a7982da146103bb5761021a565b806323fd4647116101ed57806323fd4647146102b85780632f925555146102e857806334aba41014610308578063403a9f7a14610328578063424c9119146103485761021a565b80630403bce51461021f5780630a512369146102415780630b78f9c01461027857806316fb60f514610298575b600080fd5b34801561022b57600080fd5b5061023f61023a366004613b12565b61067f565b005b34801561024d57600080fd5b5061026161025c366004613ed5565b6108eb565b60405161026f929190614f2c565b60405180910390f35b34801561028457600080fd5b5061023f610293366004614193565b61098b565b3480156102a457600080fd5b5061023f6102b3366004614159565b610a5e565b3480156102c457600080fd5b506102d86102d336600461390f565b610b2c565b60405161026f94939291906144e3565b3480156102f457600080fd5b5061023f6103033660046139f1565b610c0b565b34801561031457600080fd5b5061023f610323366004613737565b610c46565b34801561033457600080fd5b5061023f610343366004613825565b610cf0565b34801561035457600080fd5b5061023f61036336600461378b565b610f23565b34801561037457600080fd5b5061023f61038336600461407a565b61103d565b34801561039457600080fd5b5061023f6103a3366004613f9f565b61111c565b61023f6103b6366004613825565b611180565b61023f6103c936600461387c565b6113fd565b3480156103da57600080fd5b5061023f6116ae565b3480156103ef57600080fd5b506104036103fe366004613fc3565b61175a565b60405161026f919061442b565b34801561041c57600080fd5b5061023f61042b366004614114565b61187d565b34801561043c57600080fd5b5061023f61044b366004613963565b61191d565b61023f61045e366004613cda565b611961565b34801561046f57600080fd5b5061023f61047e3660046141d7565b611c96565b34801561048f57600080fd5b50610403611e81565b61023f6104a6366004613c35565b611e90565b3480156104b757600080fd5b5061023f6104c6366004614056565b6120b1565b61023f6104d9366004613bee565b61214d565b61023f6104ec366004613d79565b6122c5565b3480156104fd57600080fd5b5061023f61050c366004613e59565b61261a565b34801561051d57600080fd5b50610403612682565b34801561053257600080fd5b50610403612691565b34801561054757600080fd5b506104036126a0565b34801561055c57600080fd5b5061057061056b366004613baf565b6126af565b60405161026f9190614ed6565b34801561058957600080fd5b5061023f610598366004613f9f565b6127ba565b3480156105a957600080fd5b5061023f6105b83660046140e0565b612856565b3480156105c957600080fd5b5061023f6105d8366004613f9f565b612922565b3480156105e957600080fd5b5061023f6105f8366004613737565b612986565b34801561060957600080fd5b5061061d61061836600461390f565b612a30565b60405161026f919061454a565b34801561063657600080fd5b50610403612aed565b34801561064b57600080fd5b5061023f61065a366004613737565b612afc565b34801561066b57600080fd5b5061023f61067a366004614056565b612bfe565b6005546001600160a01b031633146106b25760405162461bcd60e51b81526004016106a99061462b565b60405180910390fd5b60006106bd85612c38565b604051637544f15560e11b81529091506001600160a01b0382169063ea89e2aa906106f0908c908a908990600401614c2c565b6040805180830381600087803b15801561070957600080fd5b505af1925050508015610739575060408051601f3d908101601f19168201909252610736918101906141b4565b60015b6108025760018686600087878760405160200161075c9796959493929190614fa7565b60408051601f1981840301815282825261ffff8c166000908152600660205291909120909161078c908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906107be9291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60018a8a8a6040516107f59493929190614f3a565b60405180910390a16108e0565b6001888884848989604051602001610820979695949392919061502e565b60408051601f1981840301815282825261ffff8e1660009081526006602052919091209091610850908d9061440f565b908152602001604051809103902060008b815260200190815260200160002090805190602001906108829291906134af565b5089604051610891919061440f565b6040518091039020897f6ace246fa15cf1d5decabf654b1e8581a4422e0fcf4c1ed4bf83f41687caec198d8b8b8a8a89896040516108d59796959493929190614e48565b60405180910390a350505b505050505050505050565b600554604051630a51236960e01b815260009182916001600160a01b0390911690630a5123699061092c908c908c908c908c908c908c908c90600401614e88565b604080518083038186803b15801561094357600080fd5b505afa158015610957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097b91906141b4565b9150915097509795505050505050565b610993612ce6565b6001600160a01b03166109a4611e81565b6001600160a01b0316146109ed576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006109f883612c38565b6040516369fe0e2d60e01b81529091506001600160a01b038216906369fe0e2d90610a27908590600401614ed6565b600060405180830381600087803b158015610a4157600080fd5b505af1158015610a55573d6000803e3d6000fd5b50505050505050565b610a66612ce6565b6001600160a01b0316610a77611e81565b6001600160a01b031614610ac0576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6000610acb85612c38565b6040516320d6bc7560e01b81529091506001600160a01b038216906320d6bc7590610afe90879087908790600401614c2c565b600060405180830381600087803b158015610b1857600080fd5b505af11580156108e0573d6000803e3d6000fd5b600760209081526000938452604080852084518086018401805192815290840195840195909520945292815290835291819020805460018083015460028085015460038601805488516101009682161596909602600019011692909204601f81018990048902850189019097528684526001600160a01b03948516979296941694939091830182828015610c015780601f10610bd657610100808354040283529160200191610c01565b820191906000526020600020905b815481529060010190602001808311610be457829003601f168201915b5050505050905084565b6005546001600160a01b03163314610c355760405162461bcd60e51b81526004016106a99061462b565b6108e0898989898989898989612cea565b610c4e612ce6565b6001600160a01b0316610c5f611e81565b6001600160a01b031614610ca8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116610cce5760405162461bcd60e51b81526004016106a99061483c565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61ffff84166000908152600760205260408082209051610d1390869086906143ff565b9081526040805160209281900383018120600086815290845282902060808201835280546001600160a01b039081168352600180830154868501526002808401549092168486015260038301805486516101009382161593909302600019011692909204601f810187900487028201870190955284815292949193606086019392830182828015610de55780601f10610dba57610100808354040283529160200191610de5565b820191906000526020600020905b815481529060010190602001808311610dc857829003601f168201915b5050509190925250505060408101519091506001600160a01b0316610e1c5760405162461bcd60e51b81526004016106a990614873565b604080516080810182526000808252602080830182905282840182905283518082018552828152606084015261ffff89168252600790528290209151909190610e6890879087906143ff565b90815260408051602092819003830190206000868152908352819020835181546001600160a01b03199081166001600160a01b0392831617835585850151600184015592850151600283018054909416911617909155606083015180519192610ed9926003850192909101906134af565b505050604080820151825160208401516060850151935163ab8236f360e01b81526001600160a01b039093169363ab8236f393610afe938b938b938b938b939291906004016149e0565b610f2b612ce6565b6001600160a01b0316610f3c611e81565b6001600160a01b031614610f85576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6005546001600160a01b0316158015610fa757506002546001600160a01b0316155b610fc35760405162461bcd60e51b81526004016106a99061455d565b6001600160a01b038216610fe95760405162461bcd60e51b81526004016106a990614775565b6001600160a01b03811661100f5760405162461bcd60e51b81526004016106a990614707565b600580546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b611045612ce6565b6001600160a01b0316611056611e81565b6001600160a01b03161461109f576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006110aa87612c38565b60405163e065608b60e01b81529091506001600160a01b0382169063e065608b906110e19089908990899089908990600401614521565b600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b5050505050505050505050565b6004546001600160a01b031633146111465760405162461bcd60e51b81526004016106a990614662565b600061115183612c38565b60405163011dbbf960e61b81529091506001600160a01b0382169063476efe4090610a2790859060040161442b565b61ffff841660009081526006602052604080822090516111a390869086906143ff565b90815260408051602092819003830181206000868152908452829020805460026001821615610100026000190190911604601f8101859004850283018501909352828252909290919083018282801561123d5780601f106112125761010080835404028352916020019161123d565b820191906000526020600020905b81548152906001019060200180831161122057829003601f168201915b5050505050905060008151116112655760405162461bcd60e51b81526004016106a990614699565b6040805160208082018352600080835261ffff891681526006909152829020915190919061129690879087906143ff565b9081526020016040518091039020600084815260200190815260200160002090805190602001906112c89291906134af565b50602081015160ff811660021415611353576000806000806000868060200190518101906112f69190614204565b95509550955095509550506113498b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508a9150899050888888613166565b50505050506113f5565b60ff8116600314156113dd576000806000806000808780602001905181019061137c9190614263565b965096509650965096509650506113d28c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508b91508a905089898989612cea565b5050505050506113f5565b60405162461bcd60e51b81526004016106a9906148e1565b505050505050565b6001600160a01b0382166114235760405162461bcd60e51b81526004016106a99061494f565b61ffff8616600090815260066020526040808220905161144690889088906143ff565b90815260408051602092819003830181206000888152908452829020805460026001821615610100026000190190911604601f810185900485028301850190935282825290929091908301828280156114e05780601f106114b5576101008083540402835291602001916114e0565b820191906000526020600020905b8154815290600101906020018083116114c357829003601f168201915b5050505050905060008151116115085760405162461bcd60e51b81526004016106a990614699565b602081015160ff81166001146115305760405162461bcd60e51b81526004016106a9906148e1565b506040805160208082018352600080835261ffff8b1681526006909152829020915190919061156290899089906143ff565b9081526020016040518091039020600086815260200190815260200160002090805190602001906115949291906134af565b50604081015160608201516115a761353b565b60006115b283612c38565b604051630474ec6160e11b81529091506001600160a01b038216906308e9d8c2906115e3908e908890600401614b0e565b6040805180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163491906137c3565b6005546040516396aae4af60e01b81529193506001600160a01b031691506396aae4af903490611670908e908b9087908c908c90600401614995565b6000604051808303818588803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050505050505050505050505050565b6116b6612ce6565b6001600160a01b03166116c7611e81565b6001600160a01b031614611710576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000611764612ce6565b6001600160a01b0316611775611e81565b6001600160a01b0316146117be576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b0386166117e45760405162461bcd60e51b81526004016106a9906145ad565b600254604051637af935a160e01b81526001600160a01b0390911690637af935a19061181e908a908a908a908a908a908a90600401614edf565b602060405180830381600087803b15801561183857600080fd5b505af115801561184c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118709190613753565b90505b9695505050505050565b611885612ce6565b6001600160a01b0316611896611e81565b6001600160a01b0316146118df576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006118ea85612c38565b60405163a985565f60e01b81529091506001600160a01b0382169063a985565f90610afe90879087908790600401614c0e565b6005546001600160a01b031633146119475760405162461bcd60e51b81526004016106a99061462b565b6119578888888888888888613166565b5050505050505050565b600260015414156119a7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0386166119d25760405162461bcd60e51b81526004016106a99061494f565b600085116119f25760405162461bcd60e51b81526004016106a9906145e4565b6119fa613555565b611a0261353b565b6000611a0d8b612c38565b90506000816001600160a01b031663f6cd35ee8a6040518263ffffffff1660e01b8152600401611a3d9190614ed6565b60206040518083038186803b158015611a5557600080fd5b505afa158015611a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8d9190613f87565b9050816001600160a01b0316631b7319b68e8d33858d60006040518763ffffffff1660e01b8152600401611ac696959493929190614b4c565b60c060405180830381600087803b158015611ae057600080fd5b505af1158015611af4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b18919061380a565b9350816001600160a01b0316637298a5dc8e8d338d6040518563ffffffff1660e01b8152600401611b4c9493929190614b22565b600060405180830381600087803b158015611b6657600080fd5b505af1158015611b7a573d6000803e3d6000fd5b50505050816001600160a01b03166308e9d8c28e8d6040518363ffffffff1660e01b8152600401611bac929190614b0e565b6040805180830381600087803b158015611bc557600080fd5b505af1158015611bd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfd91906137c3565b92505050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348d8d8d8d87898b8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d11565b6000604051808303818588803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b5050600180555050505050505050505050505050565b60026001541415611cdc576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556000611cec84612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613f87565b9050611d7781611d7186826132f8565b90613361565b9350611df5826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611db557600080fd5b505afa158015611dc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ded9190613753565b3384876133c1565b6040516340c10f1960e01b81526001600160a01b038316906340c10f1990611e2390869088906004016144ca565b602060405180830381600087803b158015611e3d57600080fd5b505af1158015611e51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e759190613f87565b50506001805550505050565b6000546001600160a01b031690565b60026001541415611ed6576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b038516611f015760405162461bcd60e51b81526004016106a99061494f565b6000611f0c88612c38565b905060008511611f2e5760405162461bcd60e51b81526004016106a9906147ac565b604051632c3eac2f60e21b81526000906001600160a01b0383169063b0fab0bc90611f679033908a908f908e908c908c90600401614462565b602060405180830381600087803b158015611f8157600080fd5b505af1158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb99190613f87565b905060008111611fdb5760405162461bcd60e51b81526004016106a9906147ed565b604051630474ec6160e11b81526000906001600160a01b038416906308e9d8c29061200c908e908d90600401614b0e565b6040805180830381600087803b15801561202557600080fd5b505af1158015612039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205d91906137c3565b9050600560009054906101000a90046001600160a01b03166001600160a01b0316633cef94b9348d8d8d8d87898e8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d9d565b6120b9612ce6565b6001600160a01b03166120ca611e81565b6001600160a01b031614612113576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061211e83612c38565b60405163ac2cc36b60e01b81529091506001600160a01b0382169063ac2cc36b90610a27908590600401614516565b60026001541415612193576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0381166121be5760405162461bcd60e51b81526004016106a99061494f565b60006121c984612c38565b90506000816001600160a01b03166308e9d8c287866040518363ffffffff1660e01b81526004016121fb929190614b0e565b6040805180830381600087803b15801561221457600080fd5b505af1158015612228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224c91906137c3565b600554604051632fa7502b60e21b81529192506001600160a01b03169063be9d40ac903490612287908a908a908a908a908990600401614c48565b6000604051808303818588803b1580156122a057600080fd5b505af11580156122b4573d6000803e3d6000fd5b505060018055505050505050505050565b6002600154141561230b576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001558661232d5760405162461bcd60e51b81526004016106a9906148aa565b6001600160a01b0388166123535760405162461bcd60e51b81526004016106a99061494f565b61235b613555565b61236361353b565b600061236e8d612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b1580156123ab57600080fd5b505afa1580156123bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e39190613f87565b90506123f381611d718d826132f8565b9a5050806001600160a01b0316631b7319b68f8e338e8e60016040518763ffffffff1660e01b815260040161242d96959493929190614b4c565b60c060405180830381600087803b15801561244757600080fd5b505af115801561245b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247f919061380a565b92506124fd816001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124bd57600080fd5b505afa1580156124d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f59190613753565b33838d6133c1565b806001600160a01b03166308e9d8c28f8e6040518363ffffffff1660e01b815260040161252b929190614b0e565b6040805180830381600087803b15801561254457600080fd5b505af1158015612558573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257c91906137c3565b915050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348f8f8f8f87898f8f8f8f8f6040518d63ffffffff1660e01b81526004016125d59b9a99989796959493929190614c7d565b6000604051808303818588803b1580156125ee57600080fd5b505af1158015612602573d6000803e3d6000fd5b50506001805550505050505050505050505050505050565b6005546001600160a01b031633146126445760405162461bcd60e51b81526004016106a99061462b565b600061264f83612c38565b60405163b6addec760e01b81529091506001600160a01b0382169063b6addec790610afe90889088908790600401614bef565b6003546001600160a01b031681565b6004546001600160a01b031681565b6002546001600160a01b031681565b6000600260015414156126f7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b6002600155826127195760405162461bcd60e51b81526004016106a9906147ac565b60006127288561ffff16612c38565b6040516304c35b0d60e11b81529091506001600160a01b03821690630986b61a9061275b9033908890889060040161443f565b602060405180830381600087803b15801561277557600080fd5b505af1158015612789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ad9190613f87565b6001805595945050505050565b6127c2612ce6565b6001600160a01b03166127d3611e81565b6001600160a01b03161461281c576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061282783612c38565b6040516312d72b2f60e21b81529091506001600160a01b03821690634b5cacbc90610a2790859060040161442b565b61285e612ce6565b6001600160a01b031661286f611e81565b6001600160a01b0316146128b8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006128c384612c38565b6040516345ec368560e11b81529091506001600160a01b03821690638bd86d0a906128f49086908690600401614b0e565b600060405180830381600087803b15801561290e57600080fd5b505af1158015611957573d6000803e3d6000fd5b6003546001600160a01b0316331461294c5760405162461bcd60e51b81526004016106a99061473e565b600061295783612c38565b604051632f8c40a560e21b81529091506001600160a01b0382169063be31029490610a2790859060040161442b565b61298e612ce6565b6001600160a01b031661299f611e81565b6001600160a01b0316146129e8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612a0e5760405162461bcd60e51b81526004016106a99061483c565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6006602090815260009384526040808520845180860184018051928152908401958401959095209452928152908352918190208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015612ae55780601f10612aba57610100808354040283529160200191612ae5565b820191906000526020600020905b815481529060010190602001808311612ac857829003601f168201915b505050505081565b6005546001600160a01b031681565b612b04612ce6565b6001600160a01b0316612b15611e81565b6001600160a01b031614612b5e576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612ba35760405162461bcd60e51b815260040180806020018281038252602681526020018061512d6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612c0983612c38565b604051637fb6526560e01b81529091506001600160a01b03821690637fb6526590610a27908590600401614516565b60025460405163068bcd8d60e01b81526000916001600160a01b03169063068bcd8d90612c69908590600401614ed6565b60206040518083038186803b158015612c8157600080fd5b505afa158015612c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb99190613753565b90506001600160a01b038116612ce15760405162461bcd60e51b81526004016106a990614918565b919050565b3390565b6000612cf586612c38565b60405163902b8ab760e01b81529091506001600160a01b0382169063902b8ab790612d2a908d908b9089908990600401614b85565b602060405180830381600087803b158015612d4457600080fd5b505af1925050508015612d74575060408051601f3d908101601f19168201909252612d7191810190613f87565b60015b612e3c576003878787878787604051602001612d969796959493929190614fdf565b60408051601f1981840301815282825261ffff8d1660009081526006602052919091209091612dc6908c9061440f565b908152602001604051809103902060008a81526020019081526020016000209080519060200190612df89291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60038b8b8b604051612e2f9493929190614f3a565b60405180910390a161315a565b612e45856134a9565b8015612e52575060008351115b1561110f57846001600160a01b031663ab8236f3878d8d8d876001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ea357600080fd5b505afa158015612eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612edb9190613753565b878a6040518863ffffffff1660e01b8152600401612efe96959493929190614ab5565b600060405180830381600088803b158015612f1857600080fd5b5087f193505050508015612f2a575060015b61110f573d808015612f58576040519150601f19603f3d011682016040523d82523d6000602084013e612f5d565b606091505b506040518060800160405280846001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa257600080fd5b505afa158015612fb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fda9190613753565b6001600160a01b03168152602001838152602001876001600160a01b0316815260200185815250600760008e61ffff1661ffff1681526020019081526020016000208c60405161302a919061440f565b908152604080516020928190038301902060008e8152908352819020835181546001600160a01b03199081166001600160a01b039283161783558585015160018401559285015160028301805490941691161790915560608301518051919261309b926003850192909101906134af565b509050507f8186389e97ff190cd5e17304ed8188a4a98a6c8add46e6df94462ac7f7e8dd348c8c8c866001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156130fc57600080fd5b505afa158015613110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131349190613753565b868b8a8860405161314c989796959493929190614a3b565b60405180910390a15061110f565b50505050505050505050565b600061317185612c38565b604051632cc36bab60e21b81529091506001600160a01b0382169063b30daeac906131a8908c908a90899089908990600401614bbd565b600060405180830381600087803b1580156131c257600080fd5b505af19250505080156131d3575060015b61329557600286868686866040516020016131f396959493929190614f71565b60408051601f1981840301815282825261ffff8c1660009081526006602052919091209091613223908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906132559291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60028a8a8a60405161328c9493929190614f3a565b60405180910390a15b86886040516132a4919061440f565b60405180910390207fc7379a02e530fbd0a46ea1ce6fd91987e96535798231a796bdc0e1a688a508738b89898989896040516132e596959493929190614e11565b60405180910390a3505050505050505050565b600080821161334e576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161335757fe5b0490505b92915050565b6000826133705750600061335b565b8282028284828161337d57fe5b04146133ba5760405162461bcd60e51b81526004018080602001828103825260218152602001806151536021913960400191505060405180910390fd5b9392505050565b600080856001600160a01b03166323b872dd8686866040516024016133e8939291906144a6565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051613421919061440f565b6000604051808303816000865af19150503d806000811461345e576040519150601f19603f3d011682016040523d82523d6000602084013e613463565b606091505b509150915081801561348d57508051158061348d57508080602001905181019061348d919061376f565b6113f55760405162461bcd60e51b81526004016106a9906146d0565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826134e5576000855561352b565b82601f106134fe57805160ff191683800117855561352b565b8280016001018555821561352b579182015b8281111561352b578251825591602001919060010190613510565b5061353792915061358b565b5090565b604051806040016040528060008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b80821115613537576000815560010161358c565b8035612ce1816150d7565b60008083601f8401126135bc578182fd5b5081356001600160401b038111156135d2578182fd5b6020830191508360208285010111156135ea57600080fd5b9250929050565b600082601f830112613601578081fd5b813561361461360f82615086565b615063565b818152846020838601011115613628578283fd5b816020850160208301379081016020019190915292915050565b600060c08284031215613653578081fd5b60405160c081018181106001600160401b038211171561366f57fe5b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201525092915050565b6000606082840312156136c5578081fd5b604051606081016001600160401b0382821081831117156136e257fe5b816040528293508435835260208501356020840152604085013591508082111561370b57600080fd5b50613718858286016135f1565b6040830152505092915050565b803561ffff81168114612ce157600080fd5b600060208284031215613748578081fd5b81356133ba816150d7565b600060208284031215613764578081fd5b81516133ba816150d7565b600060208284031215613780578081fd5b81516133ba816150ef565b6000806040838503121561379d578081fd5b82356137a8816150d7565b915060208301356137b8816150d7565b809150509250929050565b6000604082840312156137d4578081fd5b604051604081018181106001600160401b03821117156137f057fe5b604052825181526020928301519281019290925250919050565b600060c0828403121561381b578081fd5b6133ba8383613642565b6000806000806060858703121561383a578182fd5b61384385613725565b935060208501356001600160401b0381111561385d578283fd5b613869878288016135ab565b9598909750949560400135949350505050565b60008060008060008060a08789031215613894578384fd5b61389d87613725565b955060208701356001600160401b03808211156138b8578586fd5b6138c48a838b016135ab565b909750955060408901359450606089013591506138e0826150d7565b909250608088013590808211156138f5578283fd5b5061390289828a016136b4565b9150509295509295509295565b600080600060608486031215613923578081fd5b61392c84613725565b925060208401356001600160401b03811115613946578182fd5b613952868287016135f1565b925050604084013590509250925092565b600080600080600080600080610100898b03121561397f578586fd5b61398889613725565b975060208901356001600160401b038111156139a2578687fd5b6139ae8b828c016135f1565b97505060408901359550606089013594506080890135935060a08901356139d4816150d7565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806000806000806000898b036101c0811215613a10578384fd5b613a198b613725565b995060208b01356001600160401b0380821115613a34578586fd5b613a408e838f016135f1565b9a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d01359150613a6e826150d7565b81955060c060df1984011215613a82578384fd5b604051925060c0830191508282108183111715613a9b57fe5b8160405260e08d013583526101008d013560208401526101208d013560408401526101408d013560608401526101608d013560808401526101808d013560a08401528294506101a08d0135925080831115613af4578384fd5b5050613b028c828d016135f1565b9150509295985092959850929598565b60008060008060008060008060e0898b031215613b2d578182fd5b613b3689613725565b975060208901356001600160401b0380821115613b51578384fd5b613b5d8c838d016135f1565b985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135915080821115613b8e578384fd5b50613b9b8b828c016135ab565b999c989b5096995094979396929594505050565b600080600060608486031215613bc3578081fd5b613bcc84613725565b9250602084013591506040840135613be3816150d7565b809150509250925092565b60008060008060808587031215613c03578182fd5b613c0c85613725565b935060208501359250604085013591506060850135613c2a816150d7565b939692955090935050565b60008060008060008060008060e0898b031215613c50578182fd5b613c5989613725565b975060208901359650604089013595506060890135613c77816150d7565b94506080890135935060a08901356001600160401b0380821115613c99578384fd5b613ca58c838d016135ab565b909550935060c08b0135915080821115613cbd578283fd5b50613cca8b828c016136b4565b9150509295985092959890939650565b60008060008060008060008060006101008a8c031215613cf8578283fd5b613d018a613725565b985060208a0135975060408a0135965060608a0135613d1f816150d7565b955060808a0135945060a08a0135935060c08a01356001600160401b0380821115613d48578485fd5b613d548d838e016135ab565b909550935060e08c0135915080821115613d6c578283fd5b50613b028c828d016136b4565b60008060008060008060008060008060006101208c8e031215613d9a578485fd5b613da38c613725565b9a5060208c0135995060408c01359850613dbf60608d016135a0565b975060808c0135965060a08c013595506001600160401b038060c08e01351115613de7578586fd5b613df78e60c08f01358f016136b4565b95508060e08e01351115613e09578283fd5b613e198e60e08f01358f016135ab565b90955093506101008d0135811015613e2f578283fd5b50613e418d6101008e01358e016135ab565b81935080925050509295989b509295989b9093969950565b60008060008084860360a0811215613e6f578283fd5b613e7886613725565b9450602086013593506040808701359350605f1982011215613e98578182fd5b50604051604081018181106001600160401b0382111715613eb557fe5b604052606086013581526080909501356020860152509194909350909190565b600080600080600080600060a0888a031215613eef578081fd5b613ef888613725565b96506020880135613f08816150fd565b955060408801356001600160401b0380821115613f23578283fd5b613f2f8b838c016135ab565b909750955060608a0135915080821115613f47578283fd5b613f538b838c016135ab565b909550935060808a0135915080821115613f6b578283fd5b50613f788a828b016136b4565b91505092959891949750929550565b600060208284031215613f98578081fd5b5051919050565b60008060408385031215613fb1578182fd5b8235915060208301356137b8816150d7565b60008060008060008060c08789031215613fdb578384fd5b863595506020870135613fed816150d7565b94506040870135613ffd816150fd565b9350606087013561400d816150fd565b925060808701356001600160401b0380821115614028578384fd5b6140348a838b016135f1565b935060a0890135915080821115614049578283fd5b5061390289828a016135f1565b60008060408385031215614068578182fd5b8235915060208301356137b8816150ef565b60008060008060008060c08789031215614092578384fd5b8635955060208701356140a4816150ef565b9450604087013593506060870135925060808701356140c2816150ef565b915060a08701356140d2816150ef565b809150509295509295509295565b6000806000606084860312156140f4578081fd5b8335925061410460208501613725565b9150604084013590509250925092565b60008060008060808587031215614129578182fd5b8435935061413960208601613725565b92506040850135915061414e60608601613725565b905092959194509250565b6000806000806080858703121561416e578182fd5b8435935061417e60208601613725565b93969395505050506040820135916060013590565b600080604083850312156141a5578182fd5b50508035926020909101359150565b600080604083850312156141c6578182fd5b505080516020909101519092909150565b6000806000606084860312156141eb578081fd5b83359250602084013591506040840135613be3816150d7565b60008060008060008060c0878903121561421c578384fd5b8651614227816150fd565b8096505060208701519450604087015193506060870151614247816150d7565b809350506080870151915060a087015190509295509295509295565b6000806000806000806000610180888a03121561427e578081fd5b8751614289816150fd565b8097505060208801519550604088015194506060880151935060808801516142b0816150d7565b92506142bf8960a08a01613642565b91506101608801516001600160401b038111156142da578182fd5b8801601f81018a136142ea578182fd5b80516142f861360f82615086565b8181528b602083850101111561430c578384fd5b61431d8260208301602086016150a7565b80935050505092959891949750929550565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526143718160208601602086016150a7565b601f01601f19169290920160200192915050565b80518252602090810151910152565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b600081518352602082015160208401526040820151606060408501526143f76060850182614359565b949350505050565b6000828483379101908152919050565b600082516144218184602087016150a7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b600060018060a01b038816825286602083015261ffff8616604083015284606083015260a0608083015261449a60a08301848661432f565b98975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038581168252602082018590528316604082015260806060820181905260009061187390830184614359565b901515815260200190565b941515855260208501939093526040840191909152151560608301521515608082015260a00190565b6000602082526133ba6020830184614359565b60208082526030908201527f53746172676174653a2062726964676520616e6420666163746f727920616c7260408201526f1958591e481a5b9a5d1a585b1a5e995960821b606082015260800190565b6020808252601e908201527f53746172676174653a205f746f6b656e2063616e6e6f74206265203078300000604082015260600190565b60208082526027908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152666d52656d6f746560c81b606082015260800190565b6020808252601e908201527f4272696467653a2063616c6c6572206d757374206265204272696467652e0000604082015260600190565b6020808252601b908201527f53746172676174653a206f6e6c79206d696e744665654f776e65720000000000604082015260600190565b60208082526019908201527f53746172676174653a206e6f2072657472792072657665727400000000000000604082015260600190565b6020808252601e908201527f53746172676174653a205452414e534645525f46524f4d5f4641494c45440000604082015260600190565b6020808252601d908201527f53746172676174653a20666163746f72792063616e7420626520307830000000604082015260600190565b6020808252601f908201527f53746172676174653a206f6e6c792070726f746f636f6c4665654f776e657200604082015260600190565b6020808252601c908201527f53746172676174653a206272696467652063616e742062652030783000000000604082015260600190565b60208082526021908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152606d60f81b606082015260800190565b6020808252602f908201527f53746172676174653a206e6f7420656e6f756768206c7020746f20726564656560408201526e1b481dda5d1a08185b5bdd5b9d14d1608a1b606082015260800190565b6020808252601e908201527f53746172676174653a205f6f776e65722063616e6e6f74206265203078300000604082015260600190565b6020808252601f908201527f53746172676174653a20636163686520616c726561647920636c656172656400604082015260600190565b60208082526017908201527f53746172676174653a2063616e6e6f7420737761702030000000000000000000604082015260600190565b6020808252601f908201527f53746172676174653a20696e76616c69642066756e6374696f6e207479706500604082015260600190565b6020808252601d908201527f53746172676174653a20506f6f6c20646f6573206e6f74206578697374000000604082015260600190565b60208082526026908201527f53746172676174653a205f726566756e64416464726573732063616e6e6f742060408201526506265203078360d41b606082015260800190565b61ffff861681526001600160a01b038516602082015260006149ba6040830186614385565b60c060808301526149ce60c08301856143ce565b82810360a084015261449a8185614359565b600061ffff8916825260c060208301526149fe60c08301888a61432f565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614a2d8185614359565b9a9950505050505050505050565b600061010061ffff8b168352806020840152614a598184018b614359565b604084018a90526001600160a01b03898116606086015260808501899052871660a085015283810360c08501529050614a928186614359565b905082810360e0840152614aa68185614359565b9b9a5050505050505050505050565b600061ffff8816825260c06020830152614ad260c0830188614359565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614b018185614359565b9998505050505050505050565b61ffff929092168252602082015260400190565b61ffff94909416845260208401929092526001600160a01b03166040830152606082015260800190565b61ffff96909616865260208601949094526001600160a01b0392909216604085015260608401526080830152151560a082015260c00190565b61ffff85168152602081018490526001600160a01b03831660408201526101208101614bb46060830184614394565b95945050505050565b61ffff95909516855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b61ffff8416815260208101839052608081016143f76040830184614385565b61ffff93841681526020810192909252909116604082015260600190565b61ffff9390931683526020830191909152604082015260600190565b61ffff8616815260208101859052604081018490526001600160a01b038316606082015260c081016118736080830184614385565b61ffff8c168152602081018b9052604081018a90526001600160a01b038916606082015260006101e0614cb3608084018b614385565b614cc060c084018a614394565b80610180840152614cd3818401896143ce565b90508281036101a0840152614ce981878961432f565b90508281036101c0840152614cff81858761432f565b9e9d5050505050505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b038716606082015260006101e0614d476080840189614385565b614d5460c0840188614394565b80610180840152614d67818401876143ce565b90508281036101a0840152614d7d81858761432f565b8381036101c0909401939093525081526020019998505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b03871660608201526000610120614dd36080840189614385565b8660c08401528060e0840152614dec818401868861432f565b9050828103610100840152614e0181856143ce565b9c9b505050505050505050505050565b61ffff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600061ffff8916825287602083015286604083015260c06060830152614e7260c08301868861432f565b60808301949094525060a0015295945050505050565b600061ffff8916825260ff8816602083015260a06040830152614eaf60a08301878961432f565b8281036060840152614ec281868861432f565b90508281036080840152614a2d81856143ce565b90815260200190565b8681526001600160a01b038616602082015260ff85811660408301528416606082015260c060808201819052600090614f1a90830185614359565b82810360a0840152614b018185614359565b918252602082015260400190565b600060ff8616825261ffff8516602083015260806040830152614f606080830185614359565b905082606083015295945050505050565b60ff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600060ff8916825287602083015286604083015260ff8616606083015284608083015260c060a0830152614b0160c08301848661432f565b60ff881681526020810187905260408101869052606081018590526001600160a01b0384166080820152600061018061501b60a0840186614394565b80610160840152614a2d81840185614359565b600060ff8916825287602083015286604083015285606083015284608083015260c060a0830152614b0160c08301848661432f565b6040518181016001600160401b038111828210171561507e57fe5b604052919050565b60006001600160401b0382111561509957fe5b50601f01601f191660200190565b60005b838110156150c25781810151838201526020016150aa565b838111156150d1576000848401525b50505050565b6001600160a01b03811681146150ec57600080fd5b50565b80151581146150ec57600080fd5b60ff811681146150ec57600080fdfe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220b89436695caad3985f272b448f782edff88be8a5379e9cecc029bae8ee505ddc64736f6c63430007060033
Deployed Bytecode
0x60806040526004361061021a5760003560e01c806387b21efc11610123578063c45a0155116100ab578063cefbdde21161006f578063cefbdde2146105dd578063da133a06146105fd578063e78cea921461062a578063f2fde38b1461063f578063fba6e2801461065f5761021a565b8063c45a01551461053b578063c4de93a514610550578063c6a276241461057d578063c7d968e31461059d578063c8adf12d146105bd5761021a565b80639ba3aa74116100f25780639ba3aa74146104cb5780639fbf10fc146104de578063a18fa804146104f1578063a96fbed414610511578063af640d82146105265761021a565b806387b21efc146104635780638da5cb5b146104835780638f2e1d181461049857806398e391a1146104ab5761021a565b806343a30630116101a6578063715018a611610175578063715018a6146103ce5780637af935a1146103e35780637b84d287146104105780637f7212981461043057806384d0dba3146104505761021a565b806343a30630146103685780635500585c1461038857806360a3b95c146103a85780636a7982da146103bb5761021a565b806323fd4647116101ed57806323fd4647146102b85780632f925555146102e857806334aba41014610308578063403a9f7a14610328578063424c9119146103485761021a565b80630403bce51461021f5780630a512369146102415780630b78f9c01461027857806316fb60f514610298575b600080fd5b34801561022b57600080fd5b5061023f61023a366004613b12565b61067f565b005b34801561024d57600080fd5b5061026161025c366004613ed5565b6108eb565b60405161026f929190614f2c565b60405180910390f35b34801561028457600080fd5b5061023f610293366004614193565b61098b565b3480156102a457600080fd5b5061023f6102b3366004614159565b610a5e565b3480156102c457600080fd5b506102d86102d336600461390f565b610b2c565b60405161026f94939291906144e3565b3480156102f457600080fd5b5061023f6103033660046139f1565b610c0b565b34801561031457600080fd5b5061023f610323366004613737565b610c46565b34801561033457600080fd5b5061023f610343366004613825565b610cf0565b34801561035457600080fd5b5061023f61036336600461378b565b610f23565b34801561037457600080fd5b5061023f61038336600461407a565b61103d565b34801561039457600080fd5b5061023f6103a3366004613f9f565b61111c565b61023f6103b6366004613825565b611180565b61023f6103c936600461387c565b6113fd565b3480156103da57600080fd5b5061023f6116ae565b3480156103ef57600080fd5b506104036103fe366004613fc3565b61175a565b60405161026f919061442b565b34801561041c57600080fd5b5061023f61042b366004614114565b61187d565b34801561043c57600080fd5b5061023f61044b366004613963565b61191d565b61023f61045e366004613cda565b611961565b34801561046f57600080fd5b5061023f61047e3660046141d7565b611c96565b34801561048f57600080fd5b50610403611e81565b61023f6104a6366004613c35565b611e90565b3480156104b757600080fd5b5061023f6104c6366004614056565b6120b1565b61023f6104d9366004613bee565b61214d565b61023f6104ec366004613d79565b6122c5565b3480156104fd57600080fd5b5061023f61050c366004613e59565b61261a565b34801561051d57600080fd5b50610403612682565b34801561053257600080fd5b50610403612691565b34801561054757600080fd5b506104036126a0565b34801561055c57600080fd5b5061057061056b366004613baf565b6126af565b60405161026f9190614ed6565b34801561058957600080fd5b5061023f610598366004613f9f565b6127ba565b3480156105a957600080fd5b5061023f6105b83660046140e0565b612856565b3480156105c957600080fd5b5061023f6105d8366004613f9f565b612922565b3480156105e957600080fd5b5061023f6105f8366004613737565b612986565b34801561060957600080fd5b5061061d61061836600461390f565b612a30565b60405161026f919061454a565b34801561063657600080fd5b50610403612aed565b34801561064b57600080fd5b5061023f61065a366004613737565b612afc565b34801561066b57600080fd5b5061023f61067a366004614056565b612bfe565b6005546001600160a01b031633146106b25760405162461bcd60e51b81526004016106a99061462b565b60405180910390fd5b60006106bd85612c38565b604051637544f15560e11b81529091506001600160a01b0382169063ea89e2aa906106f0908c908a908990600401614c2c565b6040805180830381600087803b15801561070957600080fd5b505af1925050508015610739575060408051601f3d908101601f19168201909252610736918101906141b4565b60015b6108025760018686600087878760405160200161075c9796959493929190614fa7565b60408051601f1981840301815282825261ffff8c166000908152600660205291909120909161078c908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906107be9291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60018a8a8a6040516107f59493929190614f3a565b60405180910390a16108e0565b6001888884848989604051602001610820979695949392919061502e565b60408051601f1981840301815282825261ffff8e1660009081526006602052919091209091610850908d9061440f565b908152602001604051809103902060008b815260200190815260200160002090805190602001906108829291906134af565b5089604051610891919061440f565b6040518091039020897f6ace246fa15cf1d5decabf654b1e8581a4422e0fcf4c1ed4bf83f41687caec198d8b8b8a8a89896040516108d59796959493929190614e48565b60405180910390a350505b505050505050505050565b600554604051630a51236960e01b815260009182916001600160a01b0390911690630a5123699061092c908c908c908c908c908c908c908c90600401614e88565b604080518083038186803b15801561094357600080fd5b505afa158015610957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097b91906141b4565b9150915097509795505050505050565b610993612ce6565b6001600160a01b03166109a4611e81565b6001600160a01b0316146109ed576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006109f883612c38565b6040516369fe0e2d60e01b81529091506001600160a01b038216906369fe0e2d90610a27908590600401614ed6565b600060405180830381600087803b158015610a4157600080fd5b505af1158015610a55573d6000803e3d6000fd5b50505050505050565b610a66612ce6565b6001600160a01b0316610a77611e81565b6001600160a01b031614610ac0576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6000610acb85612c38565b6040516320d6bc7560e01b81529091506001600160a01b038216906320d6bc7590610afe90879087908790600401614c2c565b600060405180830381600087803b158015610b1857600080fd5b505af11580156108e0573d6000803e3d6000fd5b600760209081526000938452604080852084518086018401805192815290840195840195909520945292815290835291819020805460018083015460028085015460038601805488516101009682161596909602600019011692909204601f81018990048902850189019097528684526001600160a01b03948516979296941694939091830182828015610c015780601f10610bd657610100808354040283529160200191610c01565b820191906000526020600020905b815481529060010190602001808311610be457829003601f168201915b5050505050905084565b6005546001600160a01b03163314610c355760405162461bcd60e51b81526004016106a99061462b565b6108e0898989898989898989612cea565b610c4e612ce6565b6001600160a01b0316610c5f611e81565b6001600160a01b031614610ca8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116610cce5760405162461bcd60e51b81526004016106a99061483c565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61ffff84166000908152600760205260408082209051610d1390869086906143ff565b9081526040805160209281900383018120600086815290845282902060808201835280546001600160a01b039081168352600180830154868501526002808401549092168486015260038301805486516101009382161593909302600019011692909204601f810187900487028201870190955284815292949193606086019392830182828015610de55780601f10610dba57610100808354040283529160200191610de5565b820191906000526020600020905b815481529060010190602001808311610dc857829003601f168201915b5050509190925250505060408101519091506001600160a01b0316610e1c5760405162461bcd60e51b81526004016106a990614873565b604080516080810182526000808252602080830182905282840182905283518082018552828152606084015261ffff89168252600790528290209151909190610e6890879087906143ff565b90815260408051602092819003830190206000868152908352819020835181546001600160a01b03199081166001600160a01b0392831617835585850151600184015592850151600283018054909416911617909155606083015180519192610ed9926003850192909101906134af565b505050604080820151825160208401516060850151935163ab8236f360e01b81526001600160a01b039093169363ab8236f393610afe938b938b938b938b939291906004016149e0565b610f2b612ce6565b6001600160a01b0316610f3c611e81565b6001600160a01b031614610f85576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6005546001600160a01b0316158015610fa757506002546001600160a01b0316155b610fc35760405162461bcd60e51b81526004016106a99061455d565b6001600160a01b038216610fe95760405162461bcd60e51b81526004016106a990614775565b6001600160a01b03811661100f5760405162461bcd60e51b81526004016106a990614707565b600580546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b611045612ce6565b6001600160a01b0316611056611e81565b6001600160a01b03161461109f576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006110aa87612c38565b60405163e065608b60e01b81529091506001600160a01b0382169063e065608b906110e19089908990899089908990600401614521565b600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b5050505050505050505050565b6004546001600160a01b031633146111465760405162461bcd60e51b81526004016106a990614662565b600061115183612c38565b60405163011dbbf960e61b81529091506001600160a01b0382169063476efe4090610a2790859060040161442b565b61ffff841660009081526006602052604080822090516111a390869086906143ff565b90815260408051602092819003830181206000868152908452829020805460026001821615610100026000190190911604601f8101859004850283018501909352828252909290919083018282801561123d5780601f106112125761010080835404028352916020019161123d565b820191906000526020600020905b81548152906001019060200180831161122057829003601f168201915b5050505050905060008151116112655760405162461bcd60e51b81526004016106a990614699565b6040805160208082018352600080835261ffff891681526006909152829020915190919061129690879087906143ff565b9081526020016040518091039020600084815260200190815260200160002090805190602001906112c89291906134af565b50602081015160ff811660021415611353576000806000806000868060200190518101906112f69190614204565b95509550955095509550506113498b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508a9150899050888888613166565b50505050506113f5565b60ff8116600314156113dd576000806000806000808780602001905181019061137c9190614263565b965096509650965096509650506113d28c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508b91508a905089898989612cea565b5050505050506113f5565b60405162461bcd60e51b81526004016106a9906148e1565b505050505050565b6001600160a01b0382166114235760405162461bcd60e51b81526004016106a99061494f565b61ffff8616600090815260066020526040808220905161144690889088906143ff565b90815260408051602092819003830181206000888152908452829020805460026001821615610100026000190190911604601f810185900485028301850190935282825290929091908301828280156114e05780601f106114b5576101008083540402835291602001916114e0565b820191906000526020600020905b8154815290600101906020018083116114c357829003601f168201915b5050505050905060008151116115085760405162461bcd60e51b81526004016106a990614699565b602081015160ff81166001146115305760405162461bcd60e51b81526004016106a9906148e1565b506040805160208082018352600080835261ffff8b1681526006909152829020915190919061156290899089906143ff565b9081526020016040518091039020600086815260200190815260200160002090805190602001906115949291906134af565b50604081015160608201516115a761353b565b60006115b283612c38565b604051630474ec6160e11b81529091506001600160a01b038216906308e9d8c2906115e3908e908890600401614b0e565b6040805180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163491906137c3565b6005546040516396aae4af60e01b81529193506001600160a01b031691506396aae4af903490611670908e908b9087908c908c90600401614995565b6000604051808303818588803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050505050505050505050505050565b6116b6612ce6565b6001600160a01b03166116c7611e81565b6001600160a01b031614611710576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000611764612ce6565b6001600160a01b0316611775611e81565b6001600160a01b0316146117be576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b0386166117e45760405162461bcd60e51b81526004016106a9906145ad565b600254604051637af935a160e01b81526001600160a01b0390911690637af935a19061181e908a908a908a908a908a908a90600401614edf565b602060405180830381600087803b15801561183857600080fd5b505af115801561184c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118709190613753565b90505b9695505050505050565b611885612ce6565b6001600160a01b0316611896611e81565b6001600160a01b0316146118df576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006118ea85612c38565b60405163a985565f60e01b81529091506001600160a01b0382169063a985565f90610afe90879087908790600401614c0e565b6005546001600160a01b031633146119475760405162461bcd60e51b81526004016106a99061462b565b6119578888888888888888613166565b5050505050505050565b600260015414156119a7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0386166119d25760405162461bcd60e51b81526004016106a99061494f565b600085116119f25760405162461bcd60e51b81526004016106a9906145e4565b6119fa613555565b611a0261353b565b6000611a0d8b612c38565b90506000816001600160a01b031663f6cd35ee8a6040518263ffffffff1660e01b8152600401611a3d9190614ed6565b60206040518083038186803b158015611a5557600080fd5b505afa158015611a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8d9190613f87565b9050816001600160a01b0316631b7319b68e8d33858d60006040518763ffffffff1660e01b8152600401611ac696959493929190614b4c565b60c060405180830381600087803b158015611ae057600080fd5b505af1158015611af4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b18919061380a565b9350816001600160a01b0316637298a5dc8e8d338d6040518563ffffffff1660e01b8152600401611b4c9493929190614b22565b600060405180830381600087803b158015611b6657600080fd5b505af1158015611b7a573d6000803e3d6000fd5b50505050816001600160a01b03166308e9d8c28e8d6040518363ffffffff1660e01b8152600401611bac929190614b0e565b6040805180830381600087803b158015611bc557600080fd5b505af1158015611bd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfd91906137c3565b92505050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348d8d8d8d87898b8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d11565b6000604051808303818588803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b5050600180555050505050505050505050505050565b60026001541415611cdc576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556000611cec84612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613f87565b9050611d7781611d7186826132f8565b90613361565b9350611df5826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611db557600080fd5b505afa158015611dc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ded9190613753565b3384876133c1565b6040516340c10f1960e01b81526001600160a01b038316906340c10f1990611e2390869088906004016144ca565b602060405180830381600087803b158015611e3d57600080fd5b505af1158015611e51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e759190613f87565b50506001805550505050565b6000546001600160a01b031690565b60026001541415611ed6576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b038516611f015760405162461bcd60e51b81526004016106a99061494f565b6000611f0c88612c38565b905060008511611f2e5760405162461bcd60e51b81526004016106a9906147ac565b604051632c3eac2f60e21b81526000906001600160a01b0383169063b0fab0bc90611f679033908a908f908e908c908c90600401614462565b602060405180830381600087803b158015611f8157600080fd5b505af1158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb99190613f87565b905060008111611fdb5760405162461bcd60e51b81526004016106a9906147ed565b604051630474ec6160e11b81526000906001600160a01b038416906308e9d8c29061200c908e908d90600401614b0e565b6040805180830381600087803b15801561202557600080fd5b505af1158015612039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205d91906137c3565b9050600560009054906101000a90046001600160a01b03166001600160a01b0316633cef94b9348d8d8d8d87898e8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d9d565b6120b9612ce6565b6001600160a01b03166120ca611e81565b6001600160a01b031614612113576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061211e83612c38565b60405163ac2cc36b60e01b81529091506001600160a01b0382169063ac2cc36b90610a27908590600401614516565b60026001541415612193576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0381166121be5760405162461bcd60e51b81526004016106a99061494f565b60006121c984612c38565b90506000816001600160a01b03166308e9d8c287866040518363ffffffff1660e01b81526004016121fb929190614b0e565b6040805180830381600087803b15801561221457600080fd5b505af1158015612228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224c91906137c3565b600554604051632fa7502b60e21b81529192506001600160a01b03169063be9d40ac903490612287908a908a908a908a908990600401614c48565b6000604051808303818588803b1580156122a057600080fd5b505af11580156122b4573d6000803e3d6000fd5b505060018055505050505050505050565b6002600154141561230b576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001558661232d5760405162461bcd60e51b81526004016106a9906148aa565b6001600160a01b0388166123535760405162461bcd60e51b81526004016106a99061494f565b61235b613555565b61236361353b565b600061236e8d612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b1580156123ab57600080fd5b505afa1580156123bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e39190613f87565b90506123f381611d718d826132f8565b9a5050806001600160a01b0316631b7319b68f8e338e8e60016040518763ffffffff1660e01b815260040161242d96959493929190614b4c565b60c060405180830381600087803b15801561244757600080fd5b505af115801561245b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247f919061380a565b92506124fd816001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124bd57600080fd5b505afa1580156124d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f59190613753565b33838d6133c1565b806001600160a01b03166308e9d8c28f8e6040518363ffffffff1660e01b815260040161252b929190614b0e565b6040805180830381600087803b15801561254457600080fd5b505af1158015612558573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257c91906137c3565b915050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348f8f8f8f87898f8f8f8f8f6040518d63ffffffff1660e01b81526004016125d59b9a99989796959493929190614c7d565b6000604051808303818588803b1580156125ee57600080fd5b505af1158015612602573d6000803e3d6000fd5b50506001805550505050505050505050505050505050565b6005546001600160a01b031633146126445760405162461bcd60e51b81526004016106a99061462b565b600061264f83612c38565b60405163b6addec760e01b81529091506001600160a01b0382169063b6addec790610afe90889088908790600401614bef565b6003546001600160a01b031681565b6004546001600160a01b031681565b6002546001600160a01b031681565b6000600260015414156126f7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b6002600155826127195760405162461bcd60e51b81526004016106a9906147ac565b60006127288561ffff16612c38565b6040516304c35b0d60e11b81529091506001600160a01b03821690630986b61a9061275b9033908890889060040161443f565b602060405180830381600087803b15801561277557600080fd5b505af1158015612789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ad9190613f87565b6001805595945050505050565b6127c2612ce6565b6001600160a01b03166127d3611e81565b6001600160a01b03161461281c576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061282783612c38565b6040516312d72b2f60e21b81529091506001600160a01b03821690634b5cacbc90610a2790859060040161442b565b61285e612ce6565b6001600160a01b031661286f611e81565b6001600160a01b0316146128b8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006128c384612c38565b6040516345ec368560e11b81529091506001600160a01b03821690638bd86d0a906128f49086908690600401614b0e565b600060405180830381600087803b15801561290e57600080fd5b505af1158015611957573d6000803e3d6000fd5b6003546001600160a01b0316331461294c5760405162461bcd60e51b81526004016106a99061473e565b600061295783612c38565b604051632f8c40a560e21b81529091506001600160a01b0382169063be31029490610a2790859060040161442b565b61298e612ce6565b6001600160a01b031661299f611e81565b6001600160a01b0316146129e8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612a0e5760405162461bcd60e51b81526004016106a99061483c565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6006602090815260009384526040808520845180860184018051928152908401958401959095209452928152908352918190208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015612ae55780601f10612aba57610100808354040283529160200191612ae5565b820191906000526020600020905b815481529060010190602001808311612ac857829003601f168201915b505050505081565b6005546001600160a01b031681565b612b04612ce6565b6001600160a01b0316612b15611e81565b6001600160a01b031614612b5e576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612ba35760405162461bcd60e51b815260040180806020018281038252602681526020018061512d6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612c0983612c38565b604051637fb6526560e01b81529091506001600160a01b03821690637fb6526590610a27908590600401614516565b60025460405163068bcd8d60e01b81526000916001600160a01b03169063068bcd8d90612c69908590600401614ed6565b60206040518083038186803b158015612c8157600080fd5b505afa158015612c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb99190613753565b90506001600160a01b038116612ce15760405162461bcd60e51b81526004016106a990614918565b919050565b3390565b6000612cf586612c38565b60405163902b8ab760e01b81529091506001600160a01b0382169063902b8ab790612d2a908d908b9089908990600401614b85565b602060405180830381600087803b158015612d4457600080fd5b505af1925050508015612d74575060408051601f3d908101601f19168201909252612d7191810190613f87565b60015b612e3c576003878787878787604051602001612d969796959493929190614fdf565b60408051601f1981840301815282825261ffff8d1660009081526006602052919091209091612dc6908c9061440f565b908152602001604051809103902060008a81526020019081526020016000209080519060200190612df89291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60038b8b8b604051612e2f9493929190614f3a565b60405180910390a161315a565b612e45856134a9565b8015612e52575060008351115b1561110f57846001600160a01b031663ab8236f3878d8d8d876001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ea357600080fd5b505afa158015612eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612edb9190613753565b878a6040518863ffffffff1660e01b8152600401612efe96959493929190614ab5565b600060405180830381600088803b158015612f1857600080fd5b5087f193505050508015612f2a575060015b61110f573d808015612f58576040519150601f19603f3d011682016040523d82523d6000602084013e612f5d565b606091505b506040518060800160405280846001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa257600080fd5b505afa158015612fb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fda9190613753565b6001600160a01b03168152602001838152602001876001600160a01b0316815260200185815250600760008e61ffff1661ffff1681526020019081526020016000208c60405161302a919061440f565b908152604080516020928190038301902060008e8152908352819020835181546001600160a01b03199081166001600160a01b039283161783558585015160018401559285015160028301805490941691161790915560608301518051919261309b926003850192909101906134af565b509050507f8186389e97ff190cd5e17304ed8188a4a98a6c8add46e6df94462ac7f7e8dd348c8c8c866001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156130fc57600080fd5b505afa158015613110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131349190613753565b868b8a8860405161314c989796959493929190614a3b565b60405180910390a15061110f565b50505050505050505050565b600061317185612c38565b604051632cc36bab60e21b81529091506001600160a01b0382169063b30daeac906131a8908c908a90899089908990600401614bbd565b600060405180830381600087803b1580156131c257600080fd5b505af19250505080156131d3575060015b61329557600286868686866040516020016131f396959493929190614f71565b60408051601f1981840301815282825261ffff8c1660009081526006602052919091209091613223908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906132559291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60028a8a8a60405161328c9493929190614f3a565b60405180910390a15b86886040516132a4919061440f565b60405180910390207fc7379a02e530fbd0a46ea1ce6fd91987e96535798231a796bdc0e1a688a508738b89898989896040516132e596959493929190614e11565b60405180910390a3505050505050505050565b600080821161334e576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161335757fe5b0490505b92915050565b6000826133705750600061335b565b8282028284828161337d57fe5b04146133ba5760405162461bcd60e51b81526004018080602001828103825260218152602001806151536021913960400191505060405180910390fd5b9392505050565b600080856001600160a01b03166323b872dd8686866040516024016133e8939291906144a6565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051613421919061440f565b6000604051808303816000865af19150503d806000811461345e576040519150601f19603f3d011682016040523d82523d6000602084013e613463565b606091505b509150915081801561348d57508051158061348d57508080602001905181019061348d919061376f565b6113f55760405162461bcd60e51b81526004016106a9906146d0565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826134e5576000855561352b565b82601f106134fe57805160ff191683800117855561352b565b8280016001018555821561352b579182015b8281111561352b578251825591602001919060010190613510565b5061353792915061358b565b5090565b604051806040016040528060008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b80821115613537576000815560010161358c565b8035612ce1816150d7565b60008083601f8401126135bc578182fd5b5081356001600160401b038111156135d2578182fd5b6020830191508360208285010111156135ea57600080fd5b9250929050565b600082601f830112613601578081fd5b813561361461360f82615086565b615063565b818152846020838601011115613628578283fd5b816020850160208301379081016020019190915292915050565b600060c08284031215613653578081fd5b60405160c081018181106001600160401b038211171561366f57fe5b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201525092915050565b6000606082840312156136c5578081fd5b604051606081016001600160401b0382821081831117156136e257fe5b816040528293508435835260208501356020840152604085013591508082111561370b57600080fd5b50613718858286016135f1565b6040830152505092915050565b803561ffff81168114612ce157600080fd5b600060208284031215613748578081fd5b81356133ba816150d7565b600060208284031215613764578081fd5b81516133ba816150d7565b600060208284031215613780578081fd5b81516133ba816150ef565b6000806040838503121561379d578081fd5b82356137a8816150d7565b915060208301356137b8816150d7565b809150509250929050565b6000604082840312156137d4578081fd5b604051604081018181106001600160401b03821117156137f057fe5b604052825181526020928301519281019290925250919050565b600060c0828403121561381b578081fd5b6133ba8383613642565b6000806000806060858703121561383a578182fd5b61384385613725565b935060208501356001600160401b0381111561385d578283fd5b613869878288016135ab565b9598909750949560400135949350505050565b60008060008060008060a08789031215613894578384fd5b61389d87613725565b955060208701356001600160401b03808211156138b8578586fd5b6138c48a838b016135ab565b909750955060408901359450606089013591506138e0826150d7565b909250608088013590808211156138f5578283fd5b5061390289828a016136b4565b9150509295509295509295565b600080600060608486031215613923578081fd5b61392c84613725565b925060208401356001600160401b03811115613946578182fd5b613952868287016135f1565b925050604084013590509250925092565b600080600080600080600080610100898b03121561397f578586fd5b61398889613725565b975060208901356001600160401b038111156139a2578687fd5b6139ae8b828c016135f1565b97505060408901359550606089013594506080890135935060a08901356139d4816150d7565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806000806000806000898b036101c0811215613a10578384fd5b613a198b613725565b995060208b01356001600160401b0380821115613a34578586fd5b613a408e838f016135f1565b9a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d01359150613a6e826150d7565b81955060c060df1984011215613a82578384fd5b604051925060c0830191508282108183111715613a9b57fe5b8160405260e08d013583526101008d013560208401526101208d013560408401526101408d013560608401526101608d013560808401526101808d013560a08401528294506101a08d0135925080831115613af4578384fd5b5050613b028c828d016135f1565b9150509295985092959850929598565b60008060008060008060008060e0898b031215613b2d578182fd5b613b3689613725565b975060208901356001600160401b0380821115613b51578384fd5b613b5d8c838d016135f1565b985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135915080821115613b8e578384fd5b50613b9b8b828c016135ab565b999c989b5096995094979396929594505050565b600080600060608486031215613bc3578081fd5b613bcc84613725565b9250602084013591506040840135613be3816150d7565b809150509250925092565b60008060008060808587031215613c03578182fd5b613c0c85613725565b935060208501359250604085013591506060850135613c2a816150d7565b939692955090935050565b60008060008060008060008060e0898b031215613c50578182fd5b613c5989613725565b975060208901359650604089013595506060890135613c77816150d7565b94506080890135935060a08901356001600160401b0380821115613c99578384fd5b613ca58c838d016135ab565b909550935060c08b0135915080821115613cbd578283fd5b50613cca8b828c016136b4565b9150509295985092959890939650565b60008060008060008060008060006101008a8c031215613cf8578283fd5b613d018a613725565b985060208a0135975060408a0135965060608a0135613d1f816150d7565b955060808a0135945060a08a0135935060c08a01356001600160401b0380821115613d48578485fd5b613d548d838e016135ab565b909550935060e08c0135915080821115613d6c578283fd5b50613b028c828d016136b4565b60008060008060008060008060008060006101208c8e031215613d9a578485fd5b613da38c613725565b9a5060208c0135995060408c01359850613dbf60608d016135a0565b975060808c0135965060a08c013595506001600160401b038060c08e01351115613de7578586fd5b613df78e60c08f01358f016136b4565b95508060e08e01351115613e09578283fd5b613e198e60e08f01358f016135ab565b90955093506101008d0135811015613e2f578283fd5b50613e418d6101008e01358e016135ab565b81935080925050509295989b509295989b9093969950565b60008060008084860360a0811215613e6f578283fd5b613e7886613725565b9450602086013593506040808701359350605f1982011215613e98578182fd5b50604051604081018181106001600160401b0382111715613eb557fe5b604052606086013581526080909501356020860152509194909350909190565b600080600080600080600060a0888a031215613eef578081fd5b613ef888613725565b96506020880135613f08816150fd565b955060408801356001600160401b0380821115613f23578283fd5b613f2f8b838c016135ab565b909750955060608a0135915080821115613f47578283fd5b613f538b838c016135ab565b909550935060808a0135915080821115613f6b578283fd5b50613f788a828b016136b4565b91505092959891949750929550565b600060208284031215613f98578081fd5b5051919050565b60008060408385031215613fb1578182fd5b8235915060208301356137b8816150d7565b60008060008060008060c08789031215613fdb578384fd5b863595506020870135613fed816150d7565b94506040870135613ffd816150fd565b9350606087013561400d816150fd565b925060808701356001600160401b0380821115614028578384fd5b6140348a838b016135f1565b935060a0890135915080821115614049578283fd5b5061390289828a016135f1565b60008060408385031215614068578182fd5b8235915060208301356137b8816150ef565b60008060008060008060c08789031215614092578384fd5b8635955060208701356140a4816150ef565b9450604087013593506060870135925060808701356140c2816150ef565b915060a08701356140d2816150ef565b809150509295509295509295565b6000806000606084860312156140f4578081fd5b8335925061410460208501613725565b9150604084013590509250925092565b60008060008060808587031215614129578182fd5b8435935061413960208601613725565b92506040850135915061414e60608601613725565b905092959194509250565b6000806000806080858703121561416e578182fd5b8435935061417e60208601613725565b93969395505050506040820135916060013590565b600080604083850312156141a5578182fd5b50508035926020909101359150565b600080604083850312156141c6578182fd5b505080516020909101519092909150565b6000806000606084860312156141eb578081fd5b83359250602084013591506040840135613be3816150d7565b60008060008060008060c0878903121561421c578384fd5b8651614227816150fd565b8096505060208701519450604087015193506060870151614247816150d7565b809350506080870151915060a087015190509295509295509295565b6000806000806000806000610180888a03121561427e578081fd5b8751614289816150fd565b8097505060208801519550604088015194506060880151935060808801516142b0816150d7565b92506142bf8960a08a01613642565b91506101608801516001600160401b038111156142da578182fd5b8801601f81018a136142ea578182fd5b80516142f861360f82615086565b8181528b602083850101111561430c578384fd5b61431d8260208301602086016150a7565b80935050505092959891949750929550565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526143718160208601602086016150a7565b601f01601f19169290920160200192915050565b80518252602090810151910152565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b600081518352602082015160208401526040820151606060408501526143f76060850182614359565b949350505050565b6000828483379101908152919050565b600082516144218184602087016150a7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b600060018060a01b038816825286602083015261ffff8616604083015284606083015260a0608083015261449a60a08301848661432f565b98975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038581168252602082018590528316604082015260806060820181905260009061187390830184614359565b901515815260200190565b941515855260208501939093526040840191909152151560608301521515608082015260a00190565b6000602082526133ba6020830184614359565b60208082526030908201527f53746172676174653a2062726964676520616e6420666163746f727920616c7260408201526f1958591e481a5b9a5d1a585b1a5e995960821b606082015260800190565b6020808252601e908201527f53746172676174653a205f746f6b656e2063616e6e6f74206265203078300000604082015260600190565b60208082526027908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152666d52656d6f746560c81b606082015260800190565b6020808252601e908201527f4272696467653a2063616c6c6572206d757374206265204272696467652e0000604082015260600190565b6020808252601b908201527f53746172676174653a206f6e6c79206d696e744665654f776e65720000000000604082015260600190565b60208082526019908201527f53746172676174653a206e6f2072657472792072657665727400000000000000604082015260600190565b6020808252601e908201527f53746172676174653a205452414e534645525f46524f4d5f4641494c45440000604082015260600190565b6020808252601d908201527f53746172676174653a20666163746f72792063616e7420626520307830000000604082015260600190565b6020808252601f908201527f53746172676174653a206f6e6c792070726f746f636f6c4665654f776e657200604082015260600190565b6020808252601c908201527f53746172676174653a206272696467652063616e742062652030783000000000604082015260600190565b60208082526021908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152606d60f81b606082015260800190565b6020808252602f908201527f53746172676174653a206e6f7420656e6f756768206c7020746f20726564656560408201526e1b481dda5d1a08185b5bdd5b9d14d1608a1b606082015260800190565b6020808252601e908201527f53746172676174653a205f6f776e65722063616e6e6f74206265203078300000604082015260600190565b6020808252601f908201527f53746172676174653a20636163686520616c726561647920636c656172656400604082015260600190565b60208082526017908201527f53746172676174653a2063616e6e6f7420737761702030000000000000000000604082015260600190565b6020808252601f908201527f53746172676174653a20696e76616c69642066756e6374696f6e207479706500604082015260600190565b6020808252601d908201527f53746172676174653a20506f6f6c20646f6573206e6f74206578697374000000604082015260600190565b60208082526026908201527f53746172676174653a205f726566756e64416464726573732063616e6e6f742060408201526506265203078360d41b606082015260800190565b61ffff861681526001600160a01b038516602082015260006149ba6040830186614385565b60c060808301526149ce60c08301856143ce565b82810360a084015261449a8185614359565b600061ffff8916825260c060208301526149fe60c08301888a61432f565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614a2d8185614359565b9a9950505050505050505050565b600061010061ffff8b168352806020840152614a598184018b614359565b604084018a90526001600160a01b03898116606086015260808501899052871660a085015283810360c08501529050614a928186614359565b905082810360e0840152614aa68185614359565b9b9a5050505050505050505050565b600061ffff8816825260c06020830152614ad260c0830188614359565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614b018185614359565b9998505050505050505050565b61ffff929092168252602082015260400190565b61ffff94909416845260208401929092526001600160a01b03166040830152606082015260800190565b61ffff96909616865260208601949094526001600160a01b0392909216604085015260608401526080830152151560a082015260c00190565b61ffff85168152602081018490526001600160a01b03831660408201526101208101614bb46060830184614394565b95945050505050565b61ffff95909516855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b61ffff8416815260208101839052608081016143f76040830184614385565b61ffff93841681526020810192909252909116604082015260600190565b61ffff9390931683526020830191909152604082015260600190565b61ffff8616815260208101859052604081018490526001600160a01b038316606082015260c081016118736080830184614385565b61ffff8c168152602081018b9052604081018a90526001600160a01b038916606082015260006101e0614cb3608084018b614385565b614cc060c084018a614394565b80610180840152614cd3818401896143ce565b90508281036101a0840152614ce981878961432f565b90508281036101c0840152614cff81858761432f565b9e9d5050505050505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b038716606082015260006101e0614d476080840189614385565b614d5460c0840188614394565b80610180840152614d67818401876143ce565b90508281036101a0840152614d7d81858761432f565b8381036101c0909401939093525081526020019998505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b03871660608201526000610120614dd36080840189614385565b8660c08401528060e0840152614dec818401868861432f565b9050828103610100840152614e0181856143ce565b9c9b505050505050505050505050565b61ffff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600061ffff8916825287602083015286604083015260c06060830152614e7260c08301868861432f565b60808301949094525060a0015295945050505050565b600061ffff8916825260ff8816602083015260a06040830152614eaf60a08301878961432f565b8281036060840152614ec281868861432f565b90508281036080840152614a2d81856143ce565b90815260200190565b8681526001600160a01b038616602082015260ff85811660408301528416606082015260c060808201819052600090614f1a90830185614359565b82810360a0840152614b018185614359565b918252602082015260400190565b600060ff8616825261ffff8516602083015260806040830152614f606080830185614359565b905082606083015295945050505050565b60ff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600060ff8916825287602083015286604083015260ff8616606083015284608083015260c060a0830152614b0160c08301848661432f565b60ff881681526020810187905260408101869052606081018590526001600160a01b0384166080820152600061018061501b60a0840186614394565b80610160840152614a2d81840185614359565b600060ff8916825287602083015286604083015285606083015284608083015260c060a0830152614b0160c08301848661432f565b6040518181016001600160401b038111828210171561507e57fe5b604052919050565b60006001600160401b0382111561509957fe5b50601f01601f191660200190565b60005b838110156150c25781810151838201526020016150aa565b838111156150d1576000848401525b50505050565b6001600160a01b03811681146150ec57600080fd5b50565b80151581146150ec57600080fd5b60ff811681146150ec57600080fdfe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220b89436695caad3985f272b448f782edff88be8a5379e9cecc029bae8ee505ddc64736f6c63430007060033
Net Worth in USD
Net Worth in MNT
Token Allocations
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 95.46% | $2,953.84 | 4.193 | $12,385.47 | |
| ETH | 0.47% | $2,953.84 | 0.0206 | $60.84 | |
| ETH | 0.04% | $0.173991 | 27.2621 | $4.74 | |
| POL | 1.44% | $0.173968 | 1,070.2572 | $186.19 | |
| POL | 0.11% | $0.998389 | 14.0102 | $13.99 | |
| BASE | 0.83% | $2,953.85 | 0.0363 | $107.2 | |
| BASE | <0.01% | $0.00 | 0.00005 | $0.00 | |
| BERA | 0.71% | $4,175.51 | 0.022 | $91.86 | |
| AVAX | 0.39% | $0.173822 | 293.1423 | $50.95 | |
| AVAX | 0.08% | $0.998489 | 10 | $9.98 | |
| BSC | 0.21% | $2,953.01 | 0.0090814 | $26.82 | |
| BSC | 0.06% | $0.173984 | 41.9294 | $7.3 | |
| BSC | <0.01% | $0.99973 | 0.11 | $0.1099 | |
| OP | 0.13% | $0.173822 | 100 | $17.38 | |
| OP | <0.01% | $0.00 | 2 | $0.00 | |
| ARB | 0.05% | $7.24 | 0.8086 | $5.85 | |
| ARB | 0.03% | $0.173914 | 20.6494 | $3.59 | |
| ARB | <0.01% | $2,954.1 | 0.000038 | $0.1122 | |
| GNO | 0.01% | $0.999653 | 1.4499 | $1.45 | |
| CELO | <0.01% | $0.115758 | 0.2506 | $0.029014 |
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.