More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 369,278 transactions (+16 Pending)
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x27a6ed8e976659692fc66f72e5fe6f32e76feccbb0eac96237b0fcb05e133c45 | - | (pending) | 3 hrs ago | IN | 0 ETH | (Pending) | |||
0xe06417252a6aec008f43f128d64c6feac255669c7dcbedbed46599eca5e42eca | - | (pending) | 5 hrs ago | IN | 0.0000575627 ETH | (Pending) | |||
0x007f79268c8ac2695a6d9f9ab0242a53959cd88acce571d5a4b2fcde57ab2d70 | - | (pending) | 2 days ago | IN | 0.0000123018 ETH | (Pending) | |||
0xa458d0febee929095a216f800634f6b3653c6a4ef87b5c6fa673d0d76e4e5701 | - | (pending) | 2 days ago | IN | 0.0000094629 ETH | (Pending) | |||
0x3d1dc2bc0453819a346b4abb99da7237b3c44ca096550f3a6f409187bf7caf73 | - | (pending) | 4 days ago | IN | 0.0000094629 ETH | (Pending) | |||
0x511ea5d7bf6d2b36480c27eb871382618d974f828e41bc348cb1e6a78888b9d0 | - | (pending) | 6 days ago | IN | 0.0000833438 ETH | (Pending) | |||
0xf70719b8364a95993d86d7403b86d770f27b19681133f9b4a840123b015e71e8 | - | (pending) | 7 days ago | IN | 0 ETH | (Pending) | |||
0xd1450ab4007e16cde0fa9c42492267810f2c20fe3aa5dae29b06bb450aab0f0c | - | (pending) | 7 days ago | IN | 0 ETH | (Pending) | |||
0x94d368bdfb5ef8a04a19c7086e31e887b8b6eb7a393ebfd5276fd6a3ef87fc63 | - | (pending) | 7 days ago | IN | 0.0000094629 ETH | (Pending) | |||
0xabfd381e211ea5a0bb8897287683aacda455d6c05e5b32f9db08ab75a2fc2cd8 | - | (pending) | 7 days ago | IN | 0.0000094629 ETH | (Pending) | |||
0x9c9a4a62d186d6c4d0b47a77288bb9aed6bcd15d3d87df31bba489ff26f03b86 | - | (pending) | 8 days ago | IN | 0.0000730664 ETH | (Pending) | |||
0x3c7fb477b309fa4c853b7cff3f9908c18c5ace3aa269cdbc3c4b2de650e5c6d3 | - | (pending) | 8 days ago | IN | 0 ETH | (Pending) | |||
0xfb037ef41fdeb095cfeb7e4fa481600d6b2b2affe5966fcb131e7a207f2c8582 | - | (pending) | 9 days ago | IN | 0 ETH | (Pending) | |||
0x1972619fe6656c1eb834fc904d9f2dd84571f54029362d94c58c34cd54898130 | - | (pending) | 12 days ago | IN | 0 ETH | (Pending) | |||
0x7f5b4728a58dc625c255d00bb9c86eac408f8dbce02d7d674633b87c830fa4f4 | - | (pending) | 14 days ago | IN | 0 ETH | (Pending) | |||
0x6961dd0c970b91af12db056318df5607cdd33681589e511848ac456a9f350c5a | - | (pending) | 14 days ago | IN | 0 ETH | (Pending) | |||
Redeem Local | 12967836 | 1 min ago | IN | 0.00005756 ETH | 0.00001342 | ||||
Redeem Local | 12967808 | 1 min ago | IN | 0.00005756 ETH | 0.00001327 | ||||
Redeem Local | 12967804 | 2 mins ago | IN | 0.00005756 ETH | 0.00001351 | ||||
Redeem Remote | 12967785 | 2 mins ago | IN | 0.00000893 ETH | 0.00001529 | ||||
Redeem Remote | 12967785 | 2 mins ago | IN | 0.00004427 ETH | 0.00001512 | ||||
Redeem Remote | 12967784 | 2 mins ago | IN | 0.00000893 ETH | 0.0000154 | ||||
Redeem Remote | 12967784 | 2 mins ago | IN | 0.00010313 ETH | 0.00015228 | ||||
Redeem Remote | 12967776 | 3 mins ago | IN | 0.00000893 ETH | 0.000152 | ||||
Redeem Remote | 12967775 | 3 mins ago | IN | 0.00000893 ETH | 0.00001532 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
12967851 | 29 secs ago | 0 ETH | ||||
12967851 | 29 secs ago | 0 ETH | ||||
12967851 | 29 secs ago | 0 ETH | ||||
12967851 | 29 secs ago | 0 ETH | ||||
12967851 | 29 secs ago | 0 ETH | ||||
12967851 | 29 secs ago | 0 ETH | ||||
12967847 | 37 secs ago | 0 ETH | ||||
12967847 | 37 secs ago | 0 ETH | ||||
12967847 | 37 secs ago | 0 ETH | ||||
12967847 | 37 secs ago | 0 ETH | ||||
12967847 | 37 secs ago | 0 ETH | ||||
12967847 | 37 secs ago | 0 ETH | ||||
12967836 | 1 min ago | 0.00005756 ETH | ||||
12967836 | 1 min ago | 0 ETH | ||||
12967836 | 1 min ago | 0 ETH | ||||
12967836 | 1 min ago | 0 ETH | ||||
12967808 | 1 min ago | 0.00005756 ETH | ||||
12967808 | 1 min ago | 0 ETH | ||||
12967808 | 1 min ago | 0 ETH | ||||
12967808 | 1 min ago | 0 ETH | ||||
12967804 | 2 mins ago | 0.00005756 ETH | ||||
12967804 | 2 mins ago | 0 ETH | ||||
12967804 | 2 mins ago | 0 ETH | ||||
12967804 | 2 mins ago | 0 ETH | ||||
12967785 | 2 mins ago | 0.00000893 ETH |
Loading...
Loading
Contract Name:
Router
Compiler Version
v0.7.6+commit.7338295f
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/layerzero-core/contracts/interfaces/ILayerZeroReceiver.sol"; import "@layerzerolabs/layerzero-core/contracts/interfaces/ILayerZeroEndpoint.sol"; import "@layerzerolabs/layerzero-core/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; 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; 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", "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
[{"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
60806040523480156200001157600080fd5b5060006200001e62000072565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001805562000076565b3390565b6151c980620000866000396000f3fe60806040526004361061021a5760003560e01c806387b21efc11610123578063c45a0155116100ab578063cefbdde21161006f578063cefbdde2146105dd578063da133a06146105fd578063e78cea921461062a578063f2fde38b1461063f578063fba6e2801461065f5761021a565b8063c45a01551461053b578063c4de93a514610550578063c6a276241461057d578063c7d968e31461059d578063c8adf12d146105bd5761021a565b80639ba3aa74116100f25780639ba3aa74146104cb5780639fbf10fc146104de578063a18fa804146104f1578063a96fbed414610511578063af640d82146105265761021a565b806387b21efc146104635780638da5cb5b146104835780638f2e1d181461049857806398e391a1146104ab5761021a565b806343a30630116101a6578063715018a611610175578063715018a6146103ce5780637af935a1146103e35780637b84d287146104105780637f7212981461043057806384d0dba3146104505761021a565b806343a30630146103685780635500585c1461038857806360a3b95c146103a85780636a7982da146103bb5761021a565b806323fd4647116101ed57806323fd4647146102b85780632f925555146102e857806334aba41014610308578063403a9f7a14610328578063424c9119146103485761021a565b80630403bce51461021f5780630a512369146102415780630b78f9c01461027857806316fb60f514610298575b600080fd5b34801561022b57600080fd5b5061023f61023a366004613b12565b61067f565b005b34801561024d57600080fd5b5061026161025c366004613ed5565b6108eb565b60405161026f929190614f2c565b60405180910390f35b34801561028457600080fd5b5061023f610293366004614193565b61098b565b3480156102a457600080fd5b5061023f6102b3366004614159565b610a5e565b3480156102c457600080fd5b506102d86102d336600461390f565b610b2c565b60405161026f94939291906144e3565b3480156102f457600080fd5b5061023f6103033660046139f1565b610c0b565b34801561031457600080fd5b5061023f610323366004613737565b610c46565b34801561033457600080fd5b5061023f610343366004613825565b610cf0565b34801561035457600080fd5b5061023f61036336600461378b565b610f23565b34801561037457600080fd5b5061023f61038336600461407a565b61103d565b34801561039457600080fd5b5061023f6103a3366004613f9f565b61111c565b61023f6103b6366004613825565b611180565b61023f6103c936600461387c565b6113fd565b3480156103da57600080fd5b5061023f6116ae565b3480156103ef57600080fd5b506104036103fe366004613fc3565b61175a565b60405161026f919061442b565b34801561041c57600080fd5b5061023f61042b366004614114565b61187d565b34801561043c57600080fd5b5061023f61044b366004613963565b61191d565b61023f61045e366004613cda565b611961565b34801561046f57600080fd5b5061023f61047e3660046141d7565b611c96565b34801561048f57600080fd5b50610403611e81565b61023f6104a6366004613c35565b611e90565b3480156104b757600080fd5b5061023f6104c6366004614056565b6120b1565b61023f6104d9366004613bee565b61214d565b61023f6104ec366004613d79565b6122c5565b3480156104fd57600080fd5b5061023f61050c366004613e59565b61261a565b34801561051d57600080fd5b50610403612682565b34801561053257600080fd5b50610403612691565b34801561054757600080fd5b506104036126a0565b34801561055c57600080fd5b5061057061056b366004613baf565b6126af565b60405161026f9190614ed6565b34801561058957600080fd5b5061023f610598366004613f9f565b6127ba565b3480156105a957600080fd5b5061023f6105b83660046140e0565b612856565b3480156105c957600080fd5b5061023f6105d8366004613f9f565b612922565b3480156105e957600080fd5b5061023f6105f8366004613737565b612986565b34801561060957600080fd5b5061061d61061836600461390f565b612a30565b60405161026f919061454a565b34801561063657600080fd5b50610403612aed565b34801561064b57600080fd5b5061023f61065a366004613737565b612afc565b34801561066b57600080fd5b5061023f61067a366004614056565b612bfe565b6005546001600160a01b031633146106b25760405162461bcd60e51b81526004016106a99061462b565b60405180910390fd5b60006106bd85612c38565b604051637544f15560e11b81529091506001600160a01b0382169063ea89e2aa906106f0908c908a908990600401614c2c565b6040805180830381600087803b15801561070957600080fd5b505af1925050508015610739575060408051601f3d908101601f19168201909252610736918101906141b4565b60015b6108025760018686600087878760405160200161075c9796959493929190614fa7565b60408051601f1981840301815282825261ffff8c166000908152600660205291909120909161078c908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906107be9291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60018a8a8a6040516107f59493929190614f3a565b60405180910390a16108e0565b6001888884848989604051602001610820979695949392919061502e565b60408051601f1981840301815282825261ffff8e1660009081526006602052919091209091610850908d9061440f565b908152602001604051809103902060008b815260200190815260200160002090805190602001906108829291906134af565b5089604051610891919061440f565b6040518091039020897f6ace246fa15cf1d5decabf654b1e8581a4422e0fcf4c1ed4bf83f41687caec198d8b8b8a8a89896040516108d59796959493929190614e48565b60405180910390a350505b505050505050505050565b600554604051630a51236960e01b815260009182916001600160a01b0390911690630a5123699061092c908c908c908c908c908c908c908c90600401614e88565b604080518083038186803b15801561094357600080fd5b505afa158015610957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097b91906141b4565b9150915097509795505050505050565b610993612ce6565b6001600160a01b03166109a4611e81565b6001600160a01b0316146109ed576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006109f883612c38565b6040516369fe0e2d60e01b81529091506001600160a01b038216906369fe0e2d90610a27908590600401614ed6565b600060405180830381600087803b158015610a4157600080fd5b505af1158015610a55573d6000803e3d6000fd5b50505050505050565b610a66612ce6565b6001600160a01b0316610a77611e81565b6001600160a01b031614610ac0576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6000610acb85612c38565b6040516320d6bc7560e01b81529091506001600160a01b038216906320d6bc7590610afe90879087908790600401614c2c565b600060405180830381600087803b158015610b1857600080fd5b505af11580156108e0573d6000803e3d6000fd5b600760209081526000938452604080852084518086018401805192815290840195840195909520945292815290835291819020805460018083015460028085015460038601805488516101009682161596909602600019011692909204601f81018990048902850189019097528684526001600160a01b03948516979296941694939091830182828015610c015780601f10610bd657610100808354040283529160200191610c01565b820191906000526020600020905b815481529060010190602001808311610be457829003601f168201915b5050505050905084565b6005546001600160a01b03163314610c355760405162461bcd60e51b81526004016106a99061462b565b6108e0898989898989898989612cea565b610c4e612ce6565b6001600160a01b0316610c5f611e81565b6001600160a01b031614610ca8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116610cce5760405162461bcd60e51b81526004016106a99061483c565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61ffff84166000908152600760205260408082209051610d1390869086906143ff565b9081526040805160209281900383018120600086815290845282902060808201835280546001600160a01b039081168352600180830154868501526002808401549092168486015260038301805486516101009382161593909302600019011692909204601f810187900487028201870190955284815292949193606086019392830182828015610de55780601f10610dba57610100808354040283529160200191610de5565b820191906000526020600020905b815481529060010190602001808311610dc857829003601f168201915b5050509190925250505060408101519091506001600160a01b0316610e1c5760405162461bcd60e51b81526004016106a990614873565b604080516080810182526000808252602080830182905282840182905283518082018552828152606084015261ffff89168252600790528290209151909190610e6890879087906143ff565b90815260408051602092819003830190206000868152908352819020835181546001600160a01b03199081166001600160a01b0392831617835585850151600184015592850151600283018054909416911617909155606083015180519192610ed9926003850192909101906134af565b505050604080820151825160208401516060850151935163ab8236f360e01b81526001600160a01b039093169363ab8236f393610afe938b938b938b938b939291906004016149e0565b610f2b612ce6565b6001600160a01b0316610f3c611e81565b6001600160a01b031614610f85576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6005546001600160a01b0316158015610fa757506002546001600160a01b0316155b610fc35760405162461bcd60e51b81526004016106a99061455d565b6001600160a01b038216610fe95760405162461bcd60e51b81526004016106a990614775565b6001600160a01b03811661100f5760405162461bcd60e51b81526004016106a990614707565b600580546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b611045612ce6565b6001600160a01b0316611056611e81565b6001600160a01b03161461109f576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006110aa87612c38565b60405163e065608b60e01b81529091506001600160a01b0382169063e065608b906110e19089908990899089908990600401614521565b600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b5050505050505050505050565b6004546001600160a01b031633146111465760405162461bcd60e51b81526004016106a990614662565b600061115183612c38565b60405163011dbbf960e61b81529091506001600160a01b0382169063476efe4090610a2790859060040161442b565b61ffff841660009081526006602052604080822090516111a390869086906143ff565b90815260408051602092819003830181206000868152908452829020805460026001821615610100026000190190911604601f8101859004850283018501909352828252909290919083018282801561123d5780601f106112125761010080835404028352916020019161123d565b820191906000526020600020905b81548152906001019060200180831161122057829003601f168201915b5050505050905060008151116112655760405162461bcd60e51b81526004016106a990614699565b6040805160208082018352600080835261ffff891681526006909152829020915190919061129690879087906143ff565b9081526020016040518091039020600084815260200190815260200160002090805190602001906112c89291906134af565b50602081015160ff811660021415611353576000806000806000868060200190518101906112f69190614204565b95509550955095509550506113498b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508a9150899050888888613166565b50505050506113f5565b60ff8116600314156113dd576000806000806000808780602001905181019061137c9190614263565b965096509650965096509650506113d28c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508b91508a905089898989612cea565b5050505050506113f5565b60405162461bcd60e51b81526004016106a9906148e1565b505050505050565b6001600160a01b0382166114235760405162461bcd60e51b81526004016106a99061494f565b61ffff8616600090815260066020526040808220905161144690889088906143ff565b90815260408051602092819003830181206000888152908452829020805460026001821615610100026000190190911604601f810185900485028301850190935282825290929091908301828280156114e05780601f106114b5576101008083540402835291602001916114e0565b820191906000526020600020905b8154815290600101906020018083116114c357829003601f168201915b5050505050905060008151116115085760405162461bcd60e51b81526004016106a990614699565b602081015160ff81166001146115305760405162461bcd60e51b81526004016106a9906148e1565b506040805160208082018352600080835261ffff8b1681526006909152829020915190919061156290899089906143ff565b9081526020016040518091039020600086815260200190815260200160002090805190602001906115949291906134af565b50604081015160608201516115a761353b565b60006115b283612c38565b604051630474ec6160e11b81529091506001600160a01b038216906308e9d8c2906115e3908e908890600401614b0e565b6040805180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163491906137c3565b6005546040516396aae4af60e01b81529193506001600160a01b031691506396aae4af903490611670908e908b9087908c908c90600401614995565b6000604051808303818588803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050505050505050505050505050565b6116b6612ce6565b6001600160a01b03166116c7611e81565b6001600160a01b031614611710576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000611764612ce6565b6001600160a01b0316611775611e81565b6001600160a01b0316146117be576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b0386166117e45760405162461bcd60e51b81526004016106a9906145ad565b600254604051637af935a160e01b81526001600160a01b0390911690637af935a19061181e908a908a908a908a908a908a90600401614edf565b602060405180830381600087803b15801561183857600080fd5b505af115801561184c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118709190613753565b90505b9695505050505050565b611885612ce6565b6001600160a01b0316611896611e81565b6001600160a01b0316146118df576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006118ea85612c38565b60405163a985565f60e01b81529091506001600160a01b0382169063a985565f90610afe90879087908790600401614c0e565b6005546001600160a01b031633146119475760405162461bcd60e51b81526004016106a99061462b565b6119578888888888888888613166565b5050505050505050565b600260015414156119a7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0386166119d25760405162461bcd60e51b81526004016106a99061494f565b600085116119f25760405162461bcd60e51b81526004016106a9906145e4565b6119fa613555565b611a0261353b565b6000611a0d8b612c38565b90506000816001600160a01b031663f6cd35ee8a6040518263ffffffff1660e01b8152600401611a3d9190614ed6565b60206040518083038186803b158015611a5557600080fd5b505afa158015611a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8d9190613f87565b9050816001600160a01b0316631b7319b68e8d33858d60006040518763ffffffff1660e01b8152600401611ac696959493929190614b4c565b60c060405180830381600087803b158015611ae057600080fd5b505af1158015611af4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b18919061380a565b9350816001600160a01b0316637298a5dc8e8d338d6040518563ffffffff1660e01b8152600401611b4c9493929190614b22565b600060405180830381600087803b158015611b6657600080fd5b505af1158015611b7a573d6000803e3d6000fd5b50505050816001600160a01b03166308e9d8c28e8d6040518363ffffffff1660e01b8152600401611bac929190614b0e565b6040805180830381600087803b158015611bc557600080fd5b505af1158015611bd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfd91906137c3565b92505050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348d8d8d8d87898b8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d11565b6000604051808303818588803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b5050600180555050505050505050505050505050565b60026001541415611cdc576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556000611cec84612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613f87565b9050611d7781611d7186826132f8565b90613361565b9350611df5826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611db557600080fd5b505afa158015611dc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ded9190613753565b3384876133c1565b6040516340c10f1960e01b81526001600160a01b038316906340c10f1990611e2390869088906004016144ca565b602060405180830381600087803b158015611e3d57600080fd5b505af1158015611e51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e759190613f87565b50506001805550505050565b6000546001600160a01b031690565b60026001541415611ed6576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b038516611f015760405162461bcd60e51b81526004016106a99061494f565b6000611f0c88612c38565b905060008511611f2e5760405162461bcd60e51b81526004016106a9906147ac565b604051632c3eac2f60e21b81526000906001600160a01b0383169063b0fab0bc90611f679033908a908f908e908c908c90600401614462565b602060405180830381600087803b158015611f8157600080fd5b505af1158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb99190613f87565b905060008111611fdb5760405162461bcd60e51b81526004016106a9906147ed565b604051630474ec6160e11b81526000906001600160a01b038416906308e9d8c29061200c908e908d90600401614b0e565b6040805180830381600087803b15801561202557600080fd5b505af1158015612039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205d91906137c3565b9050600560009054906101000a90046001600160a01b03166001600160a01b0316633cef94b9348d8d8d8d87898e8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d9d565b6120b9612ce6565b6001600160a01b03166120ca611e81565b6001600160a01b031614612113576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061211e83612c38565b60405163ac2cc36b60e01b81529091506001600160a01b0382169063ac2cc36b90610a27908590600401614516565b60026001541415612193576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0381166121be5760405162461bcd60e51b81526004016106a99061494f565b60006121c984612c38565b90506000816001600160a01b03166308e9d8c287866040518363ffffffff1660e01b81526004016121fb929190614b0e565b6040805180830381600087803b15801561221457600080fd5b505af1158015612228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224c91906137c3565b600554604051632fa7502b60e21b81529192506001600160a01b03169063be9d40ac903490612287908a908a908a908a908990600401614c48565b6000604051808303818588803b1580156122a057600080fd5b505af11580156122b4573d6000803e3d6000fd5b505060018055505050505050505050565b6002600154141561230b576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001558661232d5760405162461bcd60e51b81526004016106a9906148aa565b6001600160a01b0388166123535760405162461bcd60e51b81526004016106a99061494f565b61235b613555565b61236361353b565b600061236e8d612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b1580156123ab57600080fd5b505afa1580156123bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e39190613f87565b90506123f381611d718d826132f8565b9a5050806001600160a01b0316631b7319b68f8e338e8e60016040518763ffffffff1660e01b815260040161242d96959493929190614b4c565b60c060405180830381600087803b15801561244757600080fd5b505af115801561245b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247f919061380a565b92506124fd816001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124bd57600080fd5b505afa1580156124d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f59190613753565b33838d6133c1565b806001600160a01b03166308e9d8c28f8e6040518363ffffffff1660e01b815260040161252b929190614b0e565b6040805180830381600087803b15801561254457600080fd5b505af1158015612558573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257c91906137c3565b915050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348f8f8f8f87898f8f8f8f8f6040518d63ffffffff1660e01b81526004016125d59b9a99989796959493929190614c7d565b6000604051808303818588803b1580156125ee57600080fd5b505af1158015612602573d6000803e3d6000fd5b50506001805550505050505050505050505050505050565b6005546001600160a01b031633146126445760405162461bcd60e51b81526004016106a99061462b565b600061264f83612c38565b60405163b6addec760e01b81529091506001600160a01b0382169063b6addec790610afe90889088908790600401614bef565b6003546001600160a01b031681565b6004546001600160a01b031681565b6002546001600160a01b031681565b6000600260015414156126f7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b6002600155826127195760405162461bcd60e51b81526004016106a9906147ac565b60006127288561ffff16612c38565b6040516304c35b0d60e11b81529091506001600160a01b03821690630986b61a9061275b9033908890889060040161443f565b602060405180830381600087803b15801561277557600080fd5b505af1158015612789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ad9190613f87565b6001805595945050505050565b6127c2612ce6565b6001600160a01b03166127d3611e81565b6001600160a01b03161461281c576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061282783612c38565b6040516312d72b2f60e21b81529091506001600160a01b03821690634b5cacbc90610a2790859060040161442b565b61285e612ce6565b6001600160a01b031661286f611e81565b6001600160a01b0316146128b8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006128c384612c38565b6040516345ec368560e11b81529091506001600160a01b03821690638bd86d0a906128f49086908690600401614b0e565b600060405180830381600087803b15801561290e57600080fd5b505af1158015611957573d6000803e3d6000fd5b6003546001600160a01b0316331461294c5760405162461bcd60e51b81526004016106a99061473e565b600061295783612c38565b604051632f8c40a560e21b81529091506001600160a01b0382169063be31029490610a2790859060040161442b565b61298e612ce6565b6001600160a01b031661299f611e81565b6001600160a01b0316146129e8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612a0e5760405162461bcd60e51b81526004016106a99061483c565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6006602090815260009384526040808520845180860184018051928152908401958401959095209452928152908352918190208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015612ae55780601f10612aba57610100808354040283529160200191612ae5565b820191906000526020600020905b815481529060010190602001808311612ac857829003601f168201915b505050505081565b6005546001600160a01b031681565b612b04612ce6565b6001600160a01b0316612b15611e81565b6001600160a01b031614612b5e576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612ba35760405162461bcd60e51b815260040180806020018281038252602681526020018061512d6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612c0983612c38565b604051637fb6526560e01b81529091506001600160a01b03821690637fb6526590610a27908590600401614516565b60025460405163068bcd8d60e01b81526000916001600160a01b03169063068bcd8d90612c69908590600401614ed6565b60206040518083038186803b158015612c8157600080fd5b505afa158015612c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb99190613753565b90506001600160a01b038116612ce15760405162461bcd60e51b81526004016106a990614918565b919050565b3390565b6000612cf586612c38565b60405163902b8ab760e01b81529091506001600160a01b0382169063902b8ab790612d2a908d908b9089908990600401614b85565b602060405180830381600087803b158015612d4457600080fd5b505af1925050508015612d74575060408051601f3d908101601f19168201909252612d7191810190613f87565b60015b612e3c576003878787878787604051602001612d969796959493929190614fdf565b60408051601f1981840301815282825261ffff8d1660009081526006602052919091209091612dc6908c9061440f565b908152602001604051809103902060008a81526020019081526020016000209080519060200190612df89291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60038b8b8b604051612e2f9493929190614f3a565b60405180910390a161315a565b612e45856134a9565b8015612e52575060008351115b1561110f57846001600160a01b031663ab8236f3878d8d8d876001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ea357600080fd5b505afa158015612eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612edb9190613753565b878a6040518863ffffffff1660e01b8152600401612efe96959493929190614ab5565b600060405180830381600088803b158015612f1857600080fd5b5087f193505050508015612f2a575060015b61110f573d808015612f58576040519150601f19603f3d011682016040523d82523d6000602084013e612f5d565b606091505b506040518060800160405280846001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa257600080fd5b505afa158015612fb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fda9190613753565b6001600160a01b03168152602001838152602001876001600160a01b0316815260200185815250600760008e61ffff1661ffff1681526020019081526020016000208c60405161302a919061440f565b908152604080516020928190038301902060008e8152908352819020835181546001600160a01b03199081166001600160a01b039283161783558585015160018401559285015160028301805490941691161790915560608301518051919261309b926003850192909101906134af565b509050507f8186389e97ff190cd5e17304ed8188a4a98a6c8add46e6df94462ac7f7e8dd348c8c8c866001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156130fc57600080fd5b505afa158015613110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131349190613753565b868b8a8860405161314c989796959493929190614a3b565b60405180910390a15061110f565b50505050505050505050565b600061317185612c38565b604051632cc36bab60e21b81529091506001600160a01b0382169063b30daeac906131a8908c908a90899089908990600401614bbd565b600060405180830381600087803b1580156131c257600080fd5b505af19250505080156131d3575060015b61329557600286868686866040516020016131f396959493929190614f71565b60408051601f1981840301815282825261ffff8c1660009081526006602052919091209091613223908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906132559291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60028a8a8a60405161328c9493929190614f3a565b60405180910390a15b86886040516132a4919061440f565b60405180910390207fc7379a02e530fbd0a46ea1ce6fd91987e96535798231a796bdc0e1a688a508738b89898989896040516132e596959493929190614e11565b60405180910390a3505050505050505050565b600080821161334e576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161335757fe5b0490505b92915050565b6000826133705750600061335b565b8282028284828161337d57fe5b04146133ba5760405162461bcd60e51b81526004018080602001828103825260218152602001806151536021913960400191505060405180910390fd5b9392505050565b600080856001600160a01b03166323b872dd8686866040516024016133e8939291906144a6565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051613421919061440f565b6000604051808303816000865af19150503d806000811461345e576040519150601f19603f3d011682016040523d82523d6000602084013e613463565b606091505b509150915081801561348d57508051158061348d57508080602001905181019061348d919061376f565b6113f55760405162461bcd60e51b81526004016106a9906146d0565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826134e5576000855561352b565b82601f106134fe57805160ff191683800117855561352b565b8280016001018555821561352b579182015b8281111561352b578251825591602001919060010190613510565b5061353792915061358b565b5090565b604051806040016040528060008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b80821115613537576000815560010161358c565b8035612ce1816150d7565b60008083601f8401126135bc578182fd5b5081356001600160401b038111156135d2578182fd5b6020830191508360208285010111156135ea57600080fd5b9250929050565b600082601f830112613601578081fd5b813561361461360f82615086565b615063565b818152846020838601011115613628578283fd5b816020850160208301379081016020019190915292915050565b600060c08284031215613653578081fd5b60405160c081018181106001600160401b038211171561366f57fe5b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201525092915050565b6000606082840312156136c5578081fd5b604051606081016001600160401b0382821081831117156136e257fe5b816040528293508435835260208501356020840152604085013591508082111561370b57600080fd5b50613718858286016135f1565b6040830152505092915050565b803561ffff81168114612ce157600080fd5b600060208284031215613748578081fd5b81356133ba816150d7565b600060208284031215613764578081fd5b81516133ba816150d7565b600060208284031215613780578081fd5b81516133ba816150ef565b6000806040838503121561379d578081fd5b82356137a8816150d7565b915060208301356137b8816150d7565b809150509250929050565b6000604082840312156137d4578081fd5b604051604081018181106001600160401b03821117156137f057fe5b604052825181526020928301519281019290925250919050565b600060c0828403121561381b578081fd5b6133ba8383613642565b6000806000806060858703121561383a578182fd5b61384385613725565b935060208501356001600160401b0381111561385d578283fd5b613869878288016135ab565b9598909750949560400135949350505050565b60008060008060008060a08789031215613894578384fd5b61389d87613725565b955060208701356001600160401b03808211156138b8578586fd5b6138c48a838b016135ab565b909750955060408901359450606089013591506138e0826150d7565b909250608088013590808211156138f5578283fd5b5061390289828a016136b4565b9150509295509295509295565b600080600060608486031215613923578081fd5b61392c84613725565b925060208401356001600160401b03811115613946578182fd5b613952868287016135f1565b925050604084013590509250925092565b600080600080600080600080610100898b03121561397f578586fd5b61398889613725565b975060208901356001600160401b038111156139a2578687fd5b6139ae8b828c016135f1565b97505060408901359550606089013594506080890135935060a08901356139d4816150d7565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806000806000806000898b036101c0811215613a10578384fd5b613a198b613725565b995060208b01356001600160401b0380821115613a34578586fd5b613a408e838f016135f1565b9a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d01359150613a6e826150d7565b81955060c060df1984011215613a82578384fd5b604051925060c0830191508282108183111715613a9b57fe5b8160405260e08d013583526101008d013560208401526101208d013560408401526101408d013560608401526101608d013560808401526101808d013560a08401528294506101a08d0135925080831115613af4578384fd5b5050613b028c828d016135f1565b9150509295985092959850929598565b60008060008060008060008060e0898b031215613b2d578182fd5b613b3689613725565b975060208901356001600160401b0380821115613b51578384fd5b613b5d8c838d016135f1565b985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135915080821115613b8e578384fd5b50613b9b8b828c016135ab565b999c989b5096995094979396929594505050565b600080600060608486031215613bc3578081fd5b613bcc84613725565b9250602084013591506040840135613be3816150d7565b809150509250925092565b60008060008060808587031215613c03578182fd5b613c0c85613725565b935060208501359250604085013591506060850135613c2a816150d7565b939692955090935050565b60008060008060008060008060e0898b031215613c50578182fd5b613c5989613725565b975060208901359650604089013595506060890135613c77816150d7565b94506080890135935060a08901356001600160401b0380821115613c99578384fd5b613ca58c838d016135ab565b909550935060c08b0135915080821115613cbd578283fd5b50613cca8b828c016136b4565b9150509295985092959890939650565b60008060008060008060008060006101008a8c031215613cf8578283fd5b613d018a613725565b985060208a0135975060408a0135965060608a0135613d1f816150d7565b955060808a0135945060a08a0135935060c08a01356001600160401b0380821115613d48578485fd5b613d548d838e016135ab565b909550935060e08c0135915080821115613d6c578283fd5b50613b028c828d016136b4565b60008060008060008060008060008060006101208c8e031215613d9a578485fd5b613da38c613725565b9a5060208c0135995060408c01359850613dbf60608d016135a0565b975060808c0135965060a08c013595506001600160401b038060c08e01351115613de7578586fd5b613df78e60c08f01358f016136b4565b95508060e08e01351115613e09578283fd5b613e198e60e08f01358f016135ab565b90955093506101008d0135811015613e2f578283fd5b50613e418d6101008e01358e016135ab565b81935080925050509295989b509295989b9093969950565b60008060008084860360a0811215613e6f578283fd5b613e7886613725565b9450602086013593506040808701359350605f1982011215613e98578182fd5b50604051604081018181106001600160401b0382111715613eb557fe5b604052606086013581526080909501356020860152509194909350909190565b600080600080600080600060a0888a031215613eef578081fd5b613ef888613725565b96506020880135613f08816150fd565b955060408801356001600160401b0380821115613f23578283fd5b613f2f8b838c016135ab565b909750955060608a0135915080821115613f47578283fd5b613f538b838c016135ab565b909550935060808a0135915080821115613f6b578283fd5b50613f788a828b016136b4565b91505092959891949750929550565b600060208284031215613f98578081fd5b5051919050565b60008060408385031215613fb1578182fd5b8235915060208301356137b8816150d7565b60008060008060008060c08789031215613fdb578384fd5b863595506020870135613fed816150d7565b94506040870135613ffd816150fd565b9350606087013561400d816150fd565b925060808701356001600160401b0380821115614028578384fd5b6140348a838b016135f1565b935060a0890135915080821115614049578283fd5b5061390289828a016135f1565b60008060408385031215614068578182fd5b8235915060208301356137b8816150ef565b60008060008060008060c08789031215614092578384fd5b8635955060208701356140a4816150ef565b9450604087013593506060870135925060808701356140c2816150ef565b915060a08701356140d2816150ef565b809150509295509295509295565b6000806000606084860312156140f4578081fd5b8335925061410460208501613725565b9150604084013590509250925092565b60008060008060808587031215614129578182fd5b8435935061413960208601613725565b92506040850135915061414e60608601613725565b905092959194509250565b6000806000806080858703121561416e578182fd5b8435935061417e60208601613725565b93969395505050506040820135916060013590565b600080604083850312156141a5578182fd5b50508035926020909101359150565b600080604083850312156141c6578182fd5b505080516020909101519092909150565b6000806000606084860312156141eb578081fd5b83359250602084013591506040840135613be3816150d7565b60008060008060008060c0878903121561421c578384fd5b8651614227816150fd565b8096505060208701519450604087015193506060870151614247816150d7565b809350506080870151915060a087015190509295509295509295565b6000806000806000806000610180888a03121561427e578081fd5b8751614289816150fd565b8097505060208801519550604088015194506060880151935060808801516142b0816150d7565b92506142bf8960a08a01613642565b91506101608801516001600160401b038111156142da578182fd5b8801601f81018a136142ea578182fd5b80516142f861360f82615086565b8181528b602083850101111561430c578384fd5b61431d8260208301602086016150a7565b80935050505092959891949750929550565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526143718160208601602086016150a7565b601f01601f19169290920160200192915050565b80518252602090810151910152565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b600081518352602082015160208401526040820151606060408501526143f76060850182614359565b949350505050565b6000828483379101908152919050565b600082516144218184602087016150a7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b600060018060a01b038816825286602083015261ffff8616604083015284606083015260a0608083015261449a60a08301848661432f565b98975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038581168252602082018590528316604082015260806060820181905260009061187390830184614359565b901515815260200190565b941515855260208501939093526040840191909152151560608301521515608082015260a00190565b6000602082526133ba6020830184614359565b60208082526030908201527f53746172676174653a2062726964676520616e6420666163746f727920616c7260408201526f1958591e481a5b9a5d1a585b1a5e995960821b606082015260800190565b6020808252601e908201527f53746172676174653a205f746f6b656e2063616e6e6f74206265203078300000604082015260600190565b60208082526027908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152666d52656d6f746560c81b606082015260800190565b6020808252601e908201527f4272696467653a2063616c6c6572206d757374206265204272696467652e0000604082015260600190565b6020808252601b908201527f53746172676174653a206f6e6c79206d696e744665654f776e65720000000000604082015260600190565b60208082526019908201527f53746172676174653a206e6f2072657472792072657665727400000000000000604082015260600190565b6020808252601e908201527f53746172676174653a205452414e534645525f46524f4d5f4641494c45440000604082015260600190565b6020808252601d908201527f53746172676174653a20666163746f72792063616e7420626520307830000000604082015260600190565b6020808252601f908201527f53746172676174653a206f6e6c792070726f746f636f6c4665654f776e657200604082015260600190565b6020808252601c908201527f53746172676174653a206272696467652063616e742062652030783000000000604082015260600190565b60208082526021908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152606d60f81b606082015260800190565b6020808252602f908201527f53746172676174653a206e6f7420656e6f756768206c7020746f20726564656560408201526e1b481dda5d1a08185b5bdd5b9d14d1608a1b606082015260800190565b6020808252601e908201527f53746172676174653a205f6f776e65722063616e6e6f74206265203078300000604082015260600190565b6020808252601f908201527f53746172676174653a20636163686520616c726561647920636c656172656400604082015260600190565b60208082526017908201527f53746172676174653a2063616e6e6f7420737761702030000000000000000000604082015260600190565b6020808252601f908201527f53746172676174653a20696e76616c69642066756e6374696f6e207479706500604082015260600190565b6020808252601d908201527f53746172676174653a20506f6f6c20646f6573206e6f74206578697374000000604082015260600190565b60208082526026908201527f53746172676174653a205f726566756e64416464726573732063616e6e6f742060408201526506265203078360d41b606082015260800190565b61ffff861681526001600160a01b038516602082015260006149ba6040830186614385565b60c060808301526149ce60c08301856143ce565b82810360a084015261449a8185614359565b600061ffff8916825260c060208301526149fe60c08301888a61432f565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614a2d8185614359565b9a9950505050505050505050565b600061010061ffff8b168352806020840152614a598184018b614359565b604084018a90526001600160a01b03898116606086015260808501899052871660a085015283810360c08501529050614a928186614359565b905082810360e0840152614aa68185614359565b9b9a5050505050505050505050565b600061ffff8816825260c06020830152614ad260c0830188614359565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614b018185614359565b9998505050505050505050565b61ffff929092168252602082015260400190565b61ffff94909416845260208401929092526001600160a01b03166040830152606082015260800190565b61ffff96909616865260208601949094526001600160a01b0392909216604085015260608401526080830152151560a082015260c00190565b61ffff85168152602081018490526001600160a01b03831660408201526101208101614bb46060830184614394565b95945050505050565b61ffff95909516855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b61ffff8416815260208101839052608081016143f76040830184614385565b61ffff93841681526020810192909252909116604082015260600190565b61ffff9390931683526020830191909152604082015260600190565b61ffff8616815260208101859052604081018490526001600160a01b038316606082015260c081016118736080830184614385565b61ffff8c168152602081018b9052604081018a90526001600160a01b038916606082015260006101e0614cb3608084018b614385565b614cc060c084018a614394565b80610180840152614cd3818401896143ce565b90508281036101a0840152614ce981878961432f565b90508281036101c0840152614cff81858761432f565b9e9d5050505050505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b038716606082015260006101e0614d476080840189614385565b614d5460c0840188614394565b80610180840152614d67818401876143ce565b90508281036101a0840152614d7d81858761432f565b8381036101c0909401939093525081526020019998505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b03871660608201526000610120614dd36080840189614385565b8660c08401528060e0840152614dec818401868861432f565b9050828103610100840152614e0181856143ce565b9c9b505050505050505050505050565b61ffff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600061ffff8916825287602083015286604083015260c06060830152614e7260c08301868861432f565b60808301949094525060a0015295945050505050565b600061ffff8916825260ff8816602083015260a06040830152614eaf60a08301878961432f565b8281036060840152614ec281868861432f565b90508281036080840152614a2d81856143ce565b90815260200190565b8681526001600160a01b038616602082015260ff85811660408301528416606082015260c060808201819052600090614f1a90830185614359565b82810360a0840152614b018185614359565b918252602082015260400190565b600060ff8616825261ffff8516602083015260806040830152614f606080830185614359565b905082606083015295945050505050565b60ff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600060ff8916825287602083015286604083015260ff8616606083015284608083015260c060a0830152614b0160c08301848661432f565b60ff881681526020810187905260408101869052606081018590526001600160a01b0384166080820152600061018061501b60a0840186614394565b80610160840152614a2d81840185614359565b600060ff8916825287602083015286604083015285606083015284608083015260c060a0830152614b0160c08301848661432f565b6040518181016001600160401b038111828210171561507e57fe5b604052919050565b60006001600160401b0382111561509957fe5b50601f01601f191660200190565b60005b838110156150c25781810151838201526020016150aa565b838111156150d1576000848401525b50505050565b6001600160a01b03811681146150ec57600080fd5b50565b80151581146150ec57600080fd5b60ff811681146150ec57600080fdfe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220d86582ffb411c85869be51806318cb203c2835996c58fcb8521dd7b53c5baece64736f6c63430007060033
Deployed Bytecode
0x60806040526004361061021a5760003560e01c806387b21efc11610123578063c45a0155116100ab578063cefbdde21161006f578063cefbdde2146105dd578063da133a06146105fd578063e78cea921461062a578063f2fde38b1461063f578063fba6e2801461065f5761021a565b8063c45a01551461053b578063c4de93a514610550578063c6a276241461057d578063c7d968e31461059d578063c8adf12d146105bd5761021a565b80639ba3aa74116100f25780639ba3aa74146104cb5780639fbf10fc146104de578063a18fa804146104f1578063a96fbed414610511578063af640d82146105265761021a565b806387b21efc146104635780638da5cb5b146104835780638f2e1d181461049857806398e391a1146104ab5761021a565b806343a30630116101a6578063715018a611610175578063715018a6146103ce5780637af935a1146103e35780637b84d287146104105780637f7212981461043057806384d0dba3146104505761021a565b806343a30630146103685780635500585c1461038857806360a3b95c146103a85780636a7982da146103bb5761021a565b806323fd4647116101ed57806323fd4647146102b85780632f925555146102e857806334aba41014610308578063403a9f7a14610328578063424c9119146103485761021a565b80630403bce51461021f5780630a512369146102415780630b78f9c01461027857806316fb60f514610298575b600080fd5b34801561022b57600080fd5b5061023f61023a366004613b12565b61067f565b005b34801561024d57600080fd5b5061026161025c366004613ed5565b6108eb565b60405161026f929190614f2c565b60405180910390f35b34801561028457600080fd5b5061023f610293366004614193565b61098b565b3480156102a457600080fd5b5061023f6102b3366004614159565b610a5e565b3480156102c457600080fd5b506102d86102d336600461390f565b610b2c565b60405161026f94939291906144e3565b3480156102f457600080fd5b5061023f6103033660046139f1565b610c0b565b34801561031457600080fd5b5061023f610323366004613737565b610c46565b34801561033457600080fd5b5061023f610343366004613825565b610cf0565b34801561035457600080fd5b5061023f61036336600461378b565b610f23565b34801561037457600080fd5b5061023f61038336600461407a565b61103d565b34801561039457600080fd5b5061023f6103a3366004613f9f565b61111c565b61023f6103b6366004613825565b611180565b61023f6103c936600461387c565b6113fd565b3480156103da57600080fd5b5061023f6116ae565b3480156103ef57600080fd5b506104036103fe366004613fc3565b61175a565b60405161026f919061442b565b34801561041c57600080fd5b5061023f61042b366004614114565b61187d565b34801561043c57600080fd5b5061023f61044b366004613963565b61191d565b61023f61045e366004613cda565b611961565b34801561046f57600080fd5b5061023f61047e3660046141d7565b611c96565b34801561048f57600080fd5b50610403611e81565b61023f6104a6366004613c35565b611e90565b3480156104b757600080fd5b5061023f6104c6366004614056565b6120b1565b61023f6104d9366004613bee565b61214d565b61023f6104ec366004613d79565b6122c5565b3480156104fd57600080fd5b5061023f61050c366004613e59565b61261a565b34801561051d57600080fd5b50610403612682565b34801561053257600080fd5b50610403612691565b34801561054757600080fd5b506104036126a0565b34801561055c57600080fd5b5061057061056b366004613baf565b6126af565b60405161026f9190614ed6565b34801561058957600080fd5b5061023f610598366004613f9f565b6127ba565b3480156105a957600080fd5b5061023f6105b83660046140e0565b612856565b3480156105c957600080fd5b5061023f6105d8366004613f9f565b612922565b3480156105e957600080fd5b5061023f6105f8366004613737565b612986565b34801561060957600080fd5b5061061d61061836600461390f565b612a30565b60405161026f919061454a565b34801561063657600080fd5b50610403612aed565b34801561064b57600080fd5b5061023f61065a366004613737565b612afc565b34801561066b57600080fd5b5061023f61067a366004614056565b612bfe565b6005546001600160a01b031633146106b25760405162461bcd60e51b81526004016106a99061462b565b60405180910390fd5b60006106bd85612c38565b604051637544f15560e11b81529091506001600160a01b0382169063ea89e2aa906106f0908c908a908990600401614c2c565b6040805180830381600087803b15801561070957600080fd5b505af1925050508015610739575060408051601f3d908101601f19168201909252610736918101906141b4565b60015b6108025760018686600087878760405160200161075c9796959493929190614fa7565b60408051601f1981840301815282825261ffff8c166000908152600660205291909120909161078c908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906107be9291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60018a8a8a6040516107f59493929190614f3a565b60405180910390a16108e0565b6001888884848989604051602001610820979695949392919061502e565b60408051601f1981840301815282825261ffff8e1660009081526006602052919091209091610850908d9061440f565b908152602001604051809103902060008b815260200190815260200160002090805190602001906108829291906134af565b5089604051610891919061440f565b6040518091039020897f6ace246fa15cf1d5decabf654b1e8581a4422e0fcf4c1ed4bf83f41687caec198d8b8b8a8a89896040516108d59796959493929190614e48565b60405180910390a350505b505050505050505050565b600554604051630a51236960e01b815260009182916001600160a01b0390911690630a5123699061092c908c908c908c908c908c908c908c90600401614e88565b604080518083038186803b15801561094357600080fd5b505afa158015610957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097b91906141b4565b9150915097509795505050505050565b610993612ce6565b6001600160a01b03166109a4611e81565b6001600160a01b0316146109ed576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006109f883612c38565b6040516369fe0e2d60e01b81529091506001600160a01b038216906369fe0e2d90610a27908590600401614ed6565b600060405180830381600087803b158015610a4157600080fd5b505af1158015610a55573d6000803e3d6000fd5b50505050505050565b610a66612ce6565b6001600160a01b0316610a77611e81565b6001600160a01b031614610ac0576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6000610acb85612c38565b6040516320d6bc7560e01b81529091506001600160a01b038216906320d6bc7590610afe90879087908790600401614c2c565b600060405180830381600087803b158015610b1857600080fd5b505af11580156108e0573d6000803e3d6000fd5b600760209081526000938452604080852084518086018401805192815290840195840195909520945292815290835291819020805460018083015460028085015460038601805488516101009682161596909602600019011692909204601f81018990048902850189019097528684526001600160a01b03948516979296941694939091830182828015610c015780601f10610bd657610100808354040283529160200191610c01565b820191906000526020600020905b815481529060010190602001808311610be457829003601f168201915b5050505050905084565b6005546001600160a01b03163314610c355760405162461bcd60e51b81526004016106a99061462b565b6108e0898989898989898989612cea565b610c4e612ce6565b6001600160a01b0316610c5f611e81565b6001600160a01b031614610ca8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116610cce5760405162461bcd60e51b81526004016106a99061483c565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61ffff84166000908152600760205260408082209051610d1390869086906143ff565b9081526040805160209281900383018120600086815290845282902060808201835280546001600160a01b039081168352600180830154868501526002808401549092168486015260038301805486516101009382161593909302600019011692909204601f810187900487028201870190955284815292949193606086019392830182828015610de55780601f10610dba57610100808354040283529160200191610de5565b820191906000526020600020905b815481529060010190602001808311610dc857829003601f168201915b5050509190925250505060408101519091506001600160a01b0316610e1c5760405162461bcd60e51b81526004016106a990614873565b604080516080810182526000808252602080830182905282840182905283518082018552828152606084015261ffff89168252600790528290209151909190610e6890879087906143ff565b90815260408051602092819003830190206000868152908352819020835181546001600160a01b03199081166001600160a01b0392831617835585850151600184015592850151600283018054909416911617909155606083015180519192610ed9926003850192909101906134af565b505050604080820151825160208401516060850151935163ab8236f360e01b81526001600160a01b039093169363ab8236f393610afe938b938b938b938b939291906004016149e0565b610f2b612ce6565b6001600160a01b0316610f3c611e81565b6001600160a01b031614610f85576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6005546001600160a01b0316158015610fa757506002546001600160a01b0316155b610fc35760405162461bcd60e51b81526004016106a99061455d565b6001600160a01b038216610fe95760405162461bcd60e51b81526004016106a990614775565b6001600160a01b03811661100f5760405162461bcd60e51b81526004016106a990614707565b600580546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b611045612ce6565b6001600160a01b0316611056611e81565b6001600160a01b03161461109f576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006110aa87612c38565b60405163e065608b60e01b81529091506001600160a01b0382169063e065608b906110e19089908990899089908990600401614521565b600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b5050505050505050505050565b6004546001600160a01b031633146111465760405162461bcd60e51b81526004016106a990614662565b600061115183612c38565b60405163011dbbf960e61b81529091506001600160a01b0382169063476efe4090610a2790859060040161442b565b61ffff841660009081526006602052604080822090516111a390869086906143ff565b90815260408051602092819003830181206000868152908452829020805460026001821615610100026000190190911604601f8101859004850283018501909352828252909290919083018282801561123d5780601f106112125761010080835404028352916020019161123d565b820191906000526020600020905b81548152906001019060200180831161122057829003601f168201915b5050505050905060008151116112655760405162461bcd60e51b81526004016106a990614699565b6040805160208082018352600080835261ffff891681526006909152829020915190919061129690879087906143ff565b9081526020016040518091039020600084815260200190815260200160002090805190602001906112c89291906134af565b50602081015160ff811660021415611353576000806000806000868060200190518101906112f69190614204565b95509550955095509550506113498b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508a9150899050888888613166565b50505050506113f5565b60ff8116600314156113dd576000806000806000808780602001905181019061137c9190614263565b965096509650965096509650506113d28c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508b91508a905089898989612cea565b5050505050506113f5565b60405162461bcd60e51b81526004016106a9906148e1565b505050505050565b6001600160a01b0382166114235760405162461bcd60e51b81526004016106a99061494f565b61ffff8616600090815260066020526040808220905161144690889088906143ff565b90815260408051602092819003830181206000888152908452829020805460026001821615610100026000190190911604601f810185900485028301850190935282825290929091908301828280156114e05780601f106114b5576101008083540402835291602001916114e0565b820191906000526020600020905b8154815290600101906020018083116114c357829003601f168201915b5050505050905060008151116115085760405162461bcd60e51b81526004016106a990614699565b602081015160ff81166001146115305760405162461bcd60e51b81526004016106a9906148e1565b506040805160208082018352600080835261ffff8b1681526006909152829020915190919061156290899089906143ff565b9081526020016040518091039020600086815260200190815260200160002090805190602001906115949291906134af565b50604081015160608201516115a761353b565b60006115b283612c38565b604051630474ec6160e11b81529091506001600160a01b038216906308e9d8c2906115e3908e908890600401614b0e565b6040805180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163491906137c3565b6005546040516396aae4af60e01b81529193506001600160a01b031691506396aae4af903490611670908e908b9087908c908c90600401614995565b6000604051808303818588803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050505050505050505050505050565b6116b6612ce6565b6001600160a01b03166116c7611e81565b6001600160a01b031614611710576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000611764612ce6565b6001600160a01b0316611775611e81565b6001600160a01b0316146117be576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b0386166117e45760405162461bcd60e51b81526004016106a9906145ad565b600254604051637af935a160e01b81526001600160a01b0390911690637af935a19061181e908a908a908a908a908a908a90600401614edf565b602060405180830381600087803b15801561183857600080fd5b505af115801561184c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118709190613753565b90505b9695505050505050565b611885612ce6565b6001600160a01b0316611896611e81565b6001600160a01b0316146118df576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006118ea85612c38565b60405163a985565f60e01b81529091506001600160a01b0382169063a985565f90610afe90879087908790600401614c0e565b6005546001600160a01b031633146119475760405162461bcd60e51b81526004016106a99061462b565b6119578888888888888888613166565b5050505050505050565b600260015414156119a7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0386166119d25760405162461bcd60e51b81526004016106a99061494f565b600085116119f25760405162461bcd60e51b81526004016106a9906145e4565b6119fa613555565b611a0261353b565b6000611a0d8b612c38565b90506000816001600160a01b031663f6cd35ee8a6040518263ffffffff1660e01b8152600401611a3d9190614ed6565b60206040518083038186803b158015611a5557600080fd5b505afa158015611a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8d9190613f87565b9050816001600160a01b0316631b7319b68e8d33858d60006040518763ffffffff1660e01b8152600401611ac696959493929190614b4c565b60c060405180830381600087803b158015611ae057600080fd5b505af1158015611af4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b18919061380a565b9350816001600160a01b0316637298a5dc8e8d338d6040518563ffffffff1660e01b8152600401611b4c9493929190614b22565b600060405180830381600087803b158015611b6657600080fd5b505af1158015611b7a573d6000803e3d6000fd5b50505050816001600160a01b03166308e9d8c28e8d6040518363ffffffff1660e01b8152600401611bac929190614b0e565b6040805180830381600087803b158015611bc557600080fd5b505af1158015611bd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfd91906137c3565b92505050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348d8d8d8d87898b8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d11565b6000604051808303818588803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b5050600180555050505050505050505050505050565b60026001541415611cdc576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556000611cec84612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613f87565b9050611d7781611d7186826132f8565b90613361565b9350611df5826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611db557600080fd5b505afa158015611dc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ded9190613753565b3384876133c1565b6040516340c10f1960e01b81526001600160a01b038316906340c10f1990611e2390869088906004016144ca565b602060405180830381600087803b158015611e3d57600080fd5b505af1158015611e51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e759190613f87565b50506001805550505050565b6000546001600160a01b031690565b60026001541415611ed6576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b038516611f015760405162461bcd60e51b81526004016106a99061494f565b6000611f0c88612c38565b905060008511611f2e5760405162461bcd60e51b81526004016106a9906147ac565b604051632c3eac2f60e21b81526000906001600160a01b0383169063b0fab0bc90611f679033908a908f908e908c908c90600401614462565b602060405180830381600087803b158015611f8157600080fd5b505af1158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb99190613f87565b905060008111611fdb5760405162461bcd60e51b81526004016106a9906147ed565b604051630474ec6160e11b81526000906001600160a01b038416906308e9d8c29061200c908e908d90600401614b0e565b6040805180830381600087803b15801561202557600080fd5b505af1158015612039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205d91906137c3565b9050600560009054906101000a90046001600160a01b03166001600160a01b0316633cef94b9348d8d8d8d87898e8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d9d565b6120b9612ce6565b6001600160a01b03166120ca611e81565b6001600160a01b031614612113576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061211e83612c38565b60405163ac2cc36b60e01b81529091506001600160a01b0382169063ac2cc36b90610a27908590600401614516565b60026001541415612193576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0381166121be5760405162461bcd60e51b81526004016106a99061494f565b60006121c984612c38565b90506000816001600160a01b03166308e9d8c287866040518363ffffffff1660e01b81526004016121fb929190614b0e565b6040805180830381600087803b15801561221457600080fd5b505af1158015612228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224c91906137c3565b600554604051632fa7502b60e21b81529192506001600160a01b03169063be9d40ac903490612287908a908a908a908a908990600401614c48565b6000604051808303818588803b1580156122a057600080fd5b505af11580156122b4573d6000803e3d6000fd5b505060018055505050505050505050565b6002600154141561230b576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001558661232d5760405162461bcd60e51b81526004016106a9906148aa565b6001600160a01b0388166123535760405162461bcd60e51b81526004016106a99061494f565b61235b613555565b61236361353b565b600061236e8d612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b1580156123ab57600080fd5b505afa1580156123bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e39190613f87565b90506123f381611d718d826132f8565b9a5050806001600160a01b0316631b7319b68f8e338e8e60016040518763ffffffff1660e01b815260040161242d96959493929190614b4c565b60c060405180830381600087803b15801561244757600080fd5b505af115801561245b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247f919061380a565b92506124fd816001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124bd57600080fd5b505afa1580156124d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f59190613753565b33838d6133c1565b806001600160a01b03166308e9d8c28f8e6040518363ffffffff1660e01b815260040161252b929190614b0e565b6040805180830381600087803b15801561254457600080fd5b505af1158015612558573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257c91906137c3565b915050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348f8f8f8f87898f8f8f8f8f6040518d63ffffffff1660e01b81526004016125d59b9a99989796959493929190614c7d565b6000604051808303818588803b1580156125ee57600080fd5b505af1158015612602573d6000803e3d6000fd5b50506001805550505050505050505050505050505050565b6005546001600160a01b031633146126445760405162461bcd60e51b81526004016106a99061462b565b600061264f83612c38565b60405163b6addec760e01b81529091506001600160a01b0382169063b6addec790610afe90889088908790600401614bef565b6003546001600160a01b031681565b6004546001600160a01b031681565b6002546001600160a01b031681565b6000600260015414156126f7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b6002600155826127195760405162461bcd60e51b81526004016106a9906147ac565b60006127288561ffff16612c38565b6040516304c35b0d60e11b81529091506001600160a01b03821690630986b61a9061275b9033908890889060040161443f565b602060405180830381600087803b15801561277557600080fd5b505af1158015612789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ad9190613f87565b6001805595945050505050565b6127c2612ce6565b6001600160a01b03166127d3611e81565b6001600160a01b03161461281c576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061282783612c38565b6040516312d72b2f60e21b81529091506001600160a01b03821690634b5cacbc90610a2790859060040161442b565b61285e612ce6565b6001600160a01b031661286f611e81565b6001600160a01b0316146128b8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006128c384612c38565b6040516345ec368560e11b81529091506001600160a01b03821690638bd86d0a906128f49086908690600401614b0e565b600060405180830381600087803b15801561290e57600080fd5b505af1158015611957573d6000803e3d6000fd5b6003546001600160a01b0316331461294c5760405162461bcd60e51b81526004016106a99061473e565b600061295783612c38565b604051632f8c40a560e21b81529091506001600160a01b0382169063be31029490610a2790859060040161442b565b61298e612ce6565b6001600160a01b031661299f611e81565b6001600160a01b0316146129e8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612a0e5760405162461bcd60e51b81526004016106a99061483c565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6006602090815260009384526040808520845180860184018051928152908401958401959095209452928152908352918190208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015612ae55780601f10612aba57610100808354040283529160200191612ae5565b820191906000526020600020905b815481529060010190602001808311612ac857829003601f168201915b505050505081565b6005546001600160a01b031681565b612b04612ce6565b6001600160a01b0316612b15611e81565b6001600160a01b031614612b5e576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612ba35760405162461bcd60e51b815260040180806020018281038252602681526020018061512d6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612c0983612c38565b604051637fb6526560e01b81529091506001600160a01b03821690637fb6526590610a27908590600401614516565b60025460405163068bcd8d60e01b81526000916001600160a01b03169063068bcd8d90612c69908590600401614ed6565b60206040518083038186803b158015612c8157600080fd5b505afa158015612c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb99190613753565b90506001600160a01b038116612ce15760405162461bcd60e51b81526004016106a990614918565b919050565b3390565b6000612cf586612c38565b60405163902b8ab760e01b81529091506001600160a01b0382169063902b8ab790612d2a908d908b9089908990600401614b85565b602060405180830381600087803b158015612d4457600080fd5b505af1925050508015612d74575060408051601f3d908101601f19168201909252612d7191810190613f87565b60015b612e3c576003878787878787604051602001612d969796959493929190614fdf565b60408051601f1981840301815282825261ffff8d1660009081526006602052919091209091612dc6908c9061440f565b908152602001604051809103902060008a81526020019081526020016000209080519060200190612df89291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60038b8b8b604051612e2f9493929190614f3a565b60405180910390a161315a565b612e45856134a9565b8015612e52575060008351115b1561110f57846001600160a01b031663ab8236f3878d8d8d876001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ea357600080fd5b505afa158015612eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612edb9190613753565b878a6040518863ffffffff1660e01b8152600401612efe96959493929190614ab5565b600060405180830381600088803b158015612f1857600080fd5b5087f193505050508015612f2a575060015b61110f573d808015612f58576040519150601f19603f3d011682016040523d82523d6000602084013e612f5d565b606091505b506040518060800160405280846001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa257600080fd5b505afa158015612fb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fda9190613753565b6001600160a01b03168152602001838152602001876001600160a01b0316815260200185815250600760008e61ffff1661ffff1681526020019081526020016000208c60405161302a919061440f565b908152604080516020928190038301902060008e8152908352819020835181546001600160a01b03199081166001600160a01b039283161783558585015160018401559285015160028301805490941691161790915560608301518051919261309b926003850192909101906134af565b509050507f8186389e97ff190cd5e17304ed8188a4a98a6c8add46e6df94462ac7f7e8dd348c8c8c866001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156130fc57600080fd5b505afa158015613110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131349190613753565b868b8a8860405161314c989796959493929190614a3b565b60405180910390a15061110f565b50505050505050505050565b600061317185612c38565b604051632cc36bab60e21b81529091506001600160a01b0382169063b30daeac906131a8908c908a90899089908990600401614bbd565b600060405180830381600087803b1580156131c257600080fd5b505af19250505080156131d3575060015b61329557600286868686866040516020016131f396959493929190614f71565b60408051601f1981840301815282825261ffff8c1660009081526006602052919091209091613223908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906132559291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60028a8a8a60405161328c9493929190614f3a565b60405180910390a15b86886040516132a4919061440f565b60405180910390207fc7379a02e530fbd0a46ea1ce6fd91987e96535798231a796bdc0e1a688a508738b89898989896040516132e596959493929190614e11565b60405180910390a3505050505050505050565b600080821161334e576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161335757fe5b0490505b92915050565b6000826133705750600061335b565b8282028284828161337d57fe5b04146133ba5760405162461bcd60e51b81526004018080602001828103825260218152602001806151536021913960400191505060405180910390fd5b9392505050565b600080856001600160a01b03166323b872dd8686866040516024016133e8939291906144a6565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051613421919061440f565b6000604051808303816000865af19150503d806000811461345e576040519150601f19603f3d011682016040523d82523d6000602084013e613463565b606091505b509150915081801561348d57508051158061348d57508080602001905181019061348d919061376f565b6113f55760405162461bcd60e51b81526004016106a9906146d0565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826134e5576000855561352b565b82601f106134fe57805160ff191683800117855561352b565b8280016001018555821561352b579182015b8281111561352b578251825591602001919060010190613510565b5061353792915061358b565b5090565b604051806040016040528060008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b80821115613537576000815560010161358c565b8035612ce1816150d7565b60008083601f8401126135bc578182fd5b5081356001600160401b038111156135d2578182fd5b6020830191508360208285010111156135ea57600080fd5b9250929050565b600082601f830112613601578081fd5b813561361461360f82615086565b615063565b818152846020838601011115613628578283fd5b816020850160208301379081016020019190915292915050565b600060c08284031215613653578081fd5b60405160c081018181106001600160401b038211171561366f57fe5b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201525092915050565b6000606082840312156136c5578081fd5b604051606081016001600160401b0382821081831117156136e257fe5b816040528293508435835260208501356020840152604085013591508082111561370b57600080fd5b50613718858286016135f1565b6040830152505092915050565b803561ffff81168114612ce157600080fd5b600060208284031215613748578081fd5b81356133ba816150d7565b600060208284031215613764578081fd5b81516133ba816150d7565b600060208284031215613780578081fd5b81516133ba816150ef565b6000806040838503121561379d578081fd5b82356137a8816150d7565b915060208301356137b8816150d7565b809150509250929050565b6000604082840312156137d4578081fd5b604051604081018181106001600160401b03821117156137f057fe5b604052825181526020928301519281019290925250919050565b600060c0828403121561381b578081fd5b6133ba8383613642565b6000806000806060858703121561383a578182fd5b61384385613725565b935060208501356001600160401b0381111561385d578283fd5b613869878288016135ab565b9598909750949560400135949350505050565b60008060008060008060a08789031215613894578384fd5b61389d87613725565b955060208701356001600160401b03808211156138b8578586fd5b6138c48a838b016135ab565b909750955060408901359450606089013591506138e0826150d7565b909250608088013590808211156138f5578283fd5b5061390289828a016136b4565b9150509295509295509295565b600080600060608486031215613923578081fd5b61392c84613725565b925060208401356001600160401b03811115613946578182fd5b613952868287016135f1565b925050604084013590509250925092565b600080600080600080600080610100898b03121561397f578586fd5b61398889613725565b975060208901356001600160401b038111156139a2578687fd5b6139ae8b828c016135f1565b97505060408901359550606089013594506080890135935060a08901356139d4816150d7565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806000806000806000898b036101c0811215613a10578384fd5b613a198b613725565b995060208b01356001600160401b0380821115613a34578586fd5b613a408e838f016135f1565b9a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d01359150613a6e826150d7565b81955060c060df1984011215613a82578384fd5b604051925060c0830191508282108183111715613a9b57fe5b8160405260e08d013583526101008d013560208401526101208d013560408401526101408d013560608401526101608d013560808401526101808d013560a08401528294506101a08d0135925080831115613af4578384fd5b5050613b028c828d016135f1565b9150509295985092959850929598565b60008060008060008060008060e0898b031215613b2d578182fd5b613b3689613725565b975060208901356001600160401b0380821115613b51578384fd5b613b5d8c838d016135f1565b985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135915080821115613b8e578384fd5b50613b9b8b828c016135ab565b999c989b5096995094979396929594505050565b600080600060608486031215613bc3578081fd5b613bcc84613725565b9250602084013591506040840135613be3816150d7565b809150509250925092565b60008060008060808587031215613c03578182fd5b613c0c85613725565b935060208501359250604085013591506060850135613c2a816150d7565b939692955090935050565b60008060008060008060008060e0898b031215613c50578182fd5b613c5989613725565b975060208901359650604089013595506060890135613c77816150d7565b94506080890135935060a08901356001600160401b0380821115613c99578384fd5b613ca58c838d016135ab565b909550935060c08b0135915080821115613cbd578283fd5b50613cca8b828c016136b4565b9150509295985092959890939650565b60008060008060008060008060006101008a8c031215613cf8578283fd5b613d018a613725565b985060208a0135975060408a0135965060608a0135613d1f816150d7565b955060808a0135945060a08a0135935060c08a01356001600160401b0380821115613d48578485fd5b613d548d838e016135ab565b909550935060e08c0135915080821115613d6c578283fd5b50613b028c828d016136b4565b60008060008060008060008060008060006101208c8e031215613d9a578485fd5b613da38c613725565b9a5060208c0135995060408c01359850613dbf60608d016135a0565b975060808c0135965060a08c013595506001600160401b038060c08e01351115613de7578586fd5b613df78e60c08f01358f016136b4565b95508060e08e01351115613e09578283fd5b613e198e60e08f01358f016135ab565b90955093506101008d0135811015613e2f578283fd5b50613e418d6101008e01358e016135ab565b81935080925050509295989b509295989b9093969950565b60008060008084860360a0811215613e6f578283fd5b613e7886613725565b9450602086013593506040808701359350605f1982011215613e98578182fd5b50604051604081018181106001600160401b0382111715613eb557fe5b604052606086013581526080909501356020860152509194909350909190565b600080600080600080600060a0888a031215613eef578081fd5b613ef888613725565b96506020880135613f08816150fd565b955060408801356001600160401b0380821115613f23578283fd5b613f2f8b838c016135ab565b909750955060608a0135915080821115613f47578283fd5b613f538b838c016135ab565b909550935060808a0135915080821115613f6b578283fd5b50613f788a828b016136b4565b91505092959891949750929550565b600060208284031215613f98578081fd5b5051919050565b60008060408385031215613fb1578182fd5b8235915060208301356137b8816150d7565b60008060008060008060c08789031215613fdb578384fd5b863595506020870135613fed816150d7565b94506040870135613ffd816150fd565b9350606087013561400d816150fd565b925060808701356001600160401b0380821115614028578384fd5b6140348a838b016135f1565b935060a0890135915080821115614049578283fd5b5061390289828a016135f1565b60008060408385031215614068578182fd5b8235915060208301356137b8816150ef565b60008060008060008060c08789031215614092578384fd5b8635955060208701356140a4816150ef565b9450604087013593506060870135925060808701356140c2816150ef565b915060a08701356140d2816150ef565b809150509295509295509295565b6000806000606084860312156140f4578081fd5b8335925061410460208501613725565b9150604084013590509250925092565b60008060008060808587031215614129578182fd5b8435935061413960208601613725565b92506040850135915061414e60608601613725565b905092959194509250565b6000806000806080858703121561416e578182fd5b8435935061417e60208601613725565b93969395505050506040820135916060013590565b600080604083850312156141a5578182fd5b50508035926020909101359150565b600080604083850312156141c6578182fd5b505080516020909101519092909150565b6000806000606084860312156141eb578081fd5b83359250602084013591506040840135613be3816150d7565b60008060008060008060c0878903121561421c578384fd5b8651614227816150fd565b8096505060208701519450604087015193506060870151614247816150d7565b809350506080870151915060a087015190509295509295509295565b6000806000806000806000610180888a03121561427e578081fd5b8751614289816150fd565b8097505060208801519550604088015194506060880151935060808801516142b0816150d7565b92506142bf8960a08a01613642565b91506101608801516001600160401b038111156142da578182fd5b8801601f81018a136142ea578182fd5b80516142f861360f82615086565b8181528b602083850101111561430c578384fd5b61431d8260208301602086016150a7565b80935050505092959891949750929550565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526143718160208601602086016150a7565b601f01601f19169290920160200192915050565b80518252602090810151910152565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b600081518352602082015160208401526040820151606060408501526143f76060850182614359565b949350505050565b6000828483379101908152919050565b600082516144218184602087016150a7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b600060018060a01b038816825286602083015261ffff8616604083015284606083015260a0608083015261449a60a08301848661432f565b98975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038581168252602082018590528316604082015260806060820181905260009061187390830184614359565b901515815260200190565b941515855260208501939093526040840191909152151560608301521515608082015260a00190565b6000602082526133ba6020830184614359565b60208082526030908201527f53746172676174653a2062726964676520616e6420666163746f727920616c7260408201526f1958591e481a5b9a5d1a585b1a5e995960821b606082015260800190565b6020808252601e908201527f53746172676174653a205f746f6b656e2063616e6e6f74206265203078300000604082015260600190565b60208082526027908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152666d52656d6f746560c81b606082015260800190565b6020808252601e908201527f4272696467653a2063616c6c6572206d757374206265204272696467652e0000604082015260600190565b6020808252601b908201527f53746172676174653a206f6e6c79206d696e744665654f776e65720000000000604082015260600190565b60208082526019908201527f53746172676174653a206e6f2072657472792072657665727400000000000000604082015260600190565b6020808252601e908201527f53746172676174653a205452414e534645525f46524f4d5f4641494c45440000604082015260600190565b6020808252601d908201527f53746172676174653a20666163746f72792063616e7420626520307830000000604082015260600190565b6020808252601f908201527f53746172676174653a206f6e6c792070726f746f636f6c4665654f776e657200604082015260600190565b6020808252601c908201527f53746172676174653a206272696467652063616e742062652030783000000000604082015260600190565b60208082526021908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152606d60f81b606082015260800190565b6020808252602f908201527f53746172676174653a206e6f7420656e6f756768206c7020746f20726564656560408201526e1b481dda5d1a08185b5bdd5b9d14d1608a1b606082015260800190565b6020808252601e908201527f53746172676174653a205f6f776e65722063616e6e6f74206265203078300000604082015260600190565b6020808252601f908201527f53746172676174653a20636163686520616c726561647920636c656172656400604082015260600190565b60208082526017908201527f53746172676174653a2063616e6e6f7420737761702030000000000000000000604082015260600190565b6020808252601f908201527f53746172676174653a20696e76616c69642066756e6374696f6e207479706500604082015260600190565b6020808252601d908201527f53746172676174653a20506f6f6c20646f6573206e6f74206578697374000000604082015260600190565b60208082526026908201527f53746172676174653a205f726566756e64416464726573732063616e6e6f742060408201526506265203078360d41b606082015260800190565b61ffff861681526001600160a01b038516602082015260006149ba6040830186614385565b60c060808301526149ce60c08301856143ce565b82810360a084015261449a8185614359565b600061ffff8916825260c060208301526149fe60c08301888a61432f565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614a2d8185614359565b9a9950505050505050505050565b600061010061ffff8b168352806020840152614a598184018b614359565b604084018a90526001600160a01b03898116606086015260808501899052871660a085015283810360c08501529050614a928186614359565b905082810360e0840152614aa68185614359565b9b9a5050505050505050505050565b600061ffff8816825260c06020830152614ad260c0830188614359565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614b018185614359565b9998505050505050505050565b61ffff929092168252602082015260400190565b61ffff94909416845260208401929092526001600160a01b03166040830152606082015260800190565b61ffff96909616865260208601949094526001600160a01b0392909216604085015260608401526080830152151560a082015260c00190565b61ffff85168152602081018490526001600160a01b03831660408201526101208101614bb46060830184614394565b95945050505050565b61ffff95909516855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b61ffff8416815260208101839052608081016143f76040830184614385565b61ffff93841681526020810192909252909116604082015260600190565b61ffff9390931683526020830191909152604082015260600190565b61ffff8616815260208101859052604081018490526001600160a01b038316606082015260c081016118736080830184614385565b61ffff8c168152602081018b9052604081018a90526001600160a01b038916606082015260006101e0614cb3608084018b614385565b614cc060c084018a614394565b80610180840152614cd3818401896143ce565b90508281036101a0840152614ce981878961432f565b90508281036101c0840152614cff81858761432f565b9e9d5050505050505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b038716606082015260006101e0614d476080840189614385565b614d5460c0840188614394565b80610180840152614d67818401876143ce565b90508281036101a0840152614d7d81858761432f565b8381036101c0909401939093525081526020019998505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b03871660608201526000610120614dd36080840189614385565b8660c08401528060e0840152614dec818401868861432f565b9050828103610100840152614e0181856143ce565b9c9b505050505050505050505050565b61ffff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600061ffff8916825287602083015286604083015260c06060830152614e7260c08301868861432f565b60808301949094525060a0015295945050505050565b600061ffff8916825260ff8816602083015260a06040830152614eaf60a08301878961432f565b8281036060840152614ec281868861432f565b90508281036080840152614a2d81856143ce565b90815260200190565b8681526001600160a01b038616602082015260ff85811660408301528416606082015260c060808201819052600090614f1a90830185614359565b82810360a0840152614b018185614359565b918252602082015260400190565b600060ff8616825261ffff8516602083015260806040830152614f606080830185614359565b905082606083015295945050505050565b60ff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600060ff8916825287602083015286604083015260ff8616606083015284608083015260c060a0830152614b0160c08301848661432f565b60ff881681526020810187905260408101869052606081018590526001600160a01b0384166080820152600061018061501b60a0840186614394565b80610160840152614a2d81840185614359565b600060ff8916825287602083015286604083015285606083015284608083015260c060a0830152614b0160c08301848661432f565b6040518181016001600160401b038111828210171561507e57fe5b604052919050565b60006001600160401b0382111561509957fe5b50601f01601f191660200190565b60005b838110156150c25781810151838201526020016150aa565b838111156150d1576000848401525b50505050565b6001600160a01b03811681146150ec57600080fd5b50565b80151581146150ec57600080fd5b60ff811681146150ec57600080fdfe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220d86582ffb411c85869be51806318cb203c2835996c58fcb8521dd7b53c5baece64736f6c63430007060033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 90.16% | $3,861.07 | 1.8265 | $7,052.37 | |
ETH | 0.15% | $0.432809 | 27.2621 | $11.8 | |
POL | 5.88% | $0.434603 | 1,058.7662 | $460.14 | |
POL | 0.18% | $0.99929 | 14.0102 | $14 | |
AVAX | 1.62% | $0.434995 | 292.1423 | $127.08 | |
AVAX | 0.13% | $1 | 10 | $10 | |
OP | 0.55% | $0.433247 | 100 | $43.32 | |
OP | 0.07% | $2.54 | 2 | $5.09 | |
ZKSYNC | 0.48% | $3,854.47 | 0.00964514 | $37.18 | |
FTM | 0.41% | $0.433412 | 74.0013 | $32.07 | |
BSC | 0.23% | $0.433322 | 41.9294 | $18.17 | |
ARB | 0.11% | $0.433118 | 20.6494 | $8.94 | |
GNO | 0.02% | $1 | 1.4499 | $1.45 | |
CELO | <0.01% | $1 | 0.2506 | $0.250796 |
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.