Overview
S Balance
0 S
S Value
-More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 47 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Trigger_close Tr... | 1029038 | 1 hr ago | IN | 1 wei | 0.00716422 | ||||
Trigger_open Tra... | 1016266 | 4 hrs ago | IN | 1 wei | 0.00096229 | ||||
Trigger_close Tr... | 991896 | 8 hrs ago | IN | 1 wei | 0.00062325 | ||||
Trigger_open Tra... | 941369 | 15 hrs ago | IN | 1 wei | 0.00077761 | ||||
Allow Trigger Ac... | 885754 | 24 hrs ago | IN | 0 S | 0.00008262 | ||||
Allow Trigger Ac... | 885751 | 24 hrs ago | IN | 0 S | 0.00008262 | ||||
Allow Trigger Ac... | 885745 | 24 hrs ago | IN | 0 S | 0.00008262 | ||||
Allow Trigger Ac... | 885741 | 24 hrs ago | IN | 0 S | 0.00008262 | ||||
Allow Trigger Ac... | 885736 | 24 hrs ago | IN | 0 S | 0.00008262 | ||||
Allow Trigger Ac... | 885732 | 24 hrs ago | IN | 0 S | 0.00008262 | ||||
Allow Trigger Ac... | 885728 | 24 hrs ago | IN | 0 S | 0.00008262 | ||||
Allow Trigger Ac... | 885724 | 24 hrs ago | IN | 0 S | 0.00008262 | ||||
Allow Trigger Ac... | 885721 | 24 hrs ago | IN | 0 S | 0.00008262 | ||||
Allow Trigger Ac... | 885717 | 24 hrs ago | IN | 0 S | 0.00008262 | ||||
Allow Trigger Ac... | 885712 | 24 hrs ago | IN | 0 S | 0.00010143 | ||||
Set Open Positio... | 885707 | 24 hrs ago | IN | 0 S | 0.00002792 | ||||
Set Market Order... | 885702 | 24 hrs ago | IN | 0 S | 0.00002788 | ||||
Set Max Triggers... | 885698 | 24 hrs ago | IN | 0 S | 0.00003323 | ||||
Set Spread Fract... | 885695 | 24 hrs ago | IN | 0 S | 0.00005241 | ||||
Set Spread Fract... | 885692 | 24 hrs ago | IN | 0 S | 0.00005241 | ||||
Set Spread Fract... | 885688 | 24 hrs ago | IN | 0 S | 0.00005241 | ||||
Set Spread Fract... | 885684 | 24 hrs ago | IN | 0 S | 0.00005241 | ||||
Set Spread Fract... | 885680 | 24 hrs ago | IN | 0 S | 0.00005241 | ||||
Set Spread Fract... | 885676 | 24 hrs ago | IN | 0 S | 0.00005241 | ||||
Set Spread Fract... | 885671 | 24 hrs ago | IN | 0 S | 0.00005241 |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
TriggersV1
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; import "../interfaces/IRegistryV1.sol"; import "../interfaces/ITradingFloorV1.sol"; import "../interfaces/IPriceValidatorV1.sol"; import "../interfaces/IOrderBookV1.sol"; import "../../AdministrationContracts/ClaimableAdmin.sol"; import "./TriggersPermissionBase.sol"; import "./ConfidenceChecker.sol"; import "./PriceAdjustmentBase.sol"; import "../Locks/SystemLocker.sol"; /** * @title TriggersV1 * @dev The main contract for handling triggers and executing trade requests and limits triggering */ contract TriggersV1 is ClaimableAdmin, TriggersPermissionBase, ConfidenceChecker, PriceAdjustmentBase, SystemLocker { // ***** Contracts (Immutable) ***** ITradingFloorV1 public immutable tradingFloor; IOrderBookV1 public immutable orderBook; IPriceValidatorV1 public priceValidator; // ***** Trigger Params ***** uint public minTriggerPeriodForMarketOrders = 3; // seconds uint public maxTriggerPeriodForMarketOrders = 60; // seconds uint public minTriggerPeriodForLimitOrders = 60; // seconds uint public marketOrdersTimeout = 60; // seconds e.g 30 // @notice the range in which the market order can be accepted (range is [orderTimestamp, orderTimestamp + range] ) uint public marketOrderTightTimeRange = 60 * 3; // 5 seconds // @notice the range in which a trigger reported price can accept(range is [blockTimestamp - triggerPriceFreshnessTimeRange, blockTimestamp] ) uint public triggerPriceFreshnessTimeRange = 60 * 30; // 30 minutes uint public marketOrderCancelFeeFraction = (1 * FRACTION_SCALE) / 1000; // FRACTION_SCALE (0.001 = 0.01%) uint public openPositionCancellationFeeFraction = (2 * FRACTION_SCALE) / 1000; // FRACTION_SCALE (0.002 = 0.02%) uint public maxTriggersPerBlock = 3; mapping(uint => uint) public triggersPerBlock; // ***** Done/Pause state ***** bool public isPaused; // Prevent opening new trades bool public isDone; // Prevent any interaction with the contract // ***** Events ***** event PausedToggled(bool paused); event DoneToggled(bool done); event NumberUpdated(string indexed name, uint value); event AddressUpdated(string indexed name, address value); // Events event OpenPositionExecuted( address indexed triggerer, bytes32 indexed positionId, TradingEnumsV1.PositionPhase indexed phase, uint triggerPrice, uint basePrice, uint priceTimestamp ); event ClosePositionExecuted( address indexed triggerer, bytes32 indexed positionId, TradingEnumsV1.PositionPhase indexed phase, uint triggerPrice, uint basePrice, uint priceTimestamp ); event SlExecuted( address indexed triggerer, bytes32 indexed positionId, uint16 indexed pairId, uint triggerPrice, uint basePrice, uint priceTimestamp ); event TpExecuted( address indexed triggerer, bytes32 indexed positionId, uint16 indexed pairId, uint triggerPrice, uint basePrice, uint priceTimestamp ); event UpdatePositionSingleFieldExecuted( address indexed triggerer, bytes32 indexed positionId, OrderBookStructsV1.UpdatePositionFieldOrderType indexed orderType, TradingEnumsV1.PositionField positionField, uint256 fieldValue, uint64 triggerPrice ); event UpdatePositionSingleFieldRejected( address indexed triggerer, bytes32 indexed positionId, OrderBookStructsV1.UpdatePositionFieldOrderType indexed orderType, TradingEnumsV1.PositionField positionField, uint256 fieldValue, uint64 triggerPrice, string rejectionReason, uint256 rejectionValue ); event LiquidationExecuted( address indexed triggerer, bytes32 indexed positionId, uint16 indexed pairId, uint triggerPrice, uint basePrice, uint priceTimestamp ); event MarketOpenTimeoutTriggered( address indexed triggerer, bytes32 indexed positionId, uint16 indexed pairId ); event MarketCloseTimeoutTriggered( address indexed triggerer, bytes32 indexed positionId, uint16 indexed pairId ); event PositionUpdateTimeoutTriggered( address indexed triggerer, bytes32 indexed positionId, OrderBookStructsV1.UpdatePositionFieldOrderType indexed orderType, uint64 fieldValueA, uint64 fieldValueB ); // ***** Modifiers ***** modifier notDone() { require(!isDone, "DONE"); _; } modifier notDoneOrPaused() { require(!isDone, "DONE"); require(!isPaused, "PAUSED"); _; } // ***** Views ***** function getValidatedPrice( uint pairId, bytes[] calldata pricePayload ) public payable returns (IPriceValidatorV1.ValidatedPrice memory) { return validatePriceForPairWithSafeguardsInternal( pairId, msg.value, pricePayload ); } // ***** Constructor ***** constructor( ITradingFloorV1 _tradingFloor ) ConfidenceChecker((FRACTION_SCALE * 10) / 100) // 10% max confidence PriceAdjustmentBase((FRACTION_SCALE * 1) / 100) // 1% max spread SystemLocker(_tradingFloor.registry()) { require(address(_tradingFloor) != address(0), "WRONG_PARAMS"); tradingFloor = _tradingFloor; orderBook = IOrderBookV1(IRegistryV1(_tradingFloor.registry()).orderBook()); } // ***** Pause/Done (Admin) Toggles ***** function togglePause() external onlyAdmin { isPaused = !isPaused; emit PausedToggled(isPaused); } function toggleDone() external onlyAdmin { isDone = !isDone; emit DoneToggled(isDone); } // ***** Admin functions ***** function setPriceValidator(address _priceValidator) external onlyAdmin { // Sanity require( IPriceValidatorV1(_priceValidator).isPriceValidator(), "!PriceValidator" ); // Setting priceValidator = IPriceValidatorV1(_priceValidator); emit AddressUpdated("PriceValidator", _priceValidator); } function allowTriggerAccount(address account) external onlyAdmin { allowTriggerAccountInternal(account); } function disallowTriggerAccount(address account) external onlyAdmin { disallowTriggerAccountInternal(account); } function setMaxConfidenceForPair( uint pairId, uint32 maxConfidenceFraction ) external onlyAdmin { setMaxConfidenceForPairInternal(pairId, maxConfidenceFraction); } function setSpreadFractionForPair( uint pairId, uint32 spreadFraction ) external onlyAdmin { setSpreadFractionForPairInternal(pairId, spreadFraction); } function setMinTriggerPeriodForMarketOrders( uint _minTriggerPeriodForMarketOrders ) external onlyAdmin { require( _minTriggerPeriodForMarketOrders < maxTriggerPeriodForMarketOrders, "WRONG_VALUE" ); minTriggerPeriodForMarketOrders = _minTriggerPeriodForMarketOrders; emit NumberUpdated( "minTriggerPeriodForMarketOrders", _minTriggerPeriodForMarketOrders ); } function setMaxTriggerPeriodForMarketOrders( uint _maxTriggerPeriodForMarketOrders ) external onlyAdmin { require( _maxTriggerPeriodForMarketOrders > minTriggerPeriodForMarketOrders, "WRONG_VALUE" ); maxTriggerPeriodForMarketOrders = _maxTriggerPeriodForMarketOrders; emit NumberUpdated( "maxTriggerPeriodForMarketOrders", _maxTriggerPeriodForMarketOrders ); } function setMinTriggerPeriodForLimitOrders( uint _minTriggerPeriodForLimitOrders ) external onlyAdmin { minTriggerPeriodForLimitOrders = _minTriggerPeriodForLimitOrders; emit NumberUpdated( "minTriggerPeriodForLimitOrders", _minTriggerPeriodForLimitOrders ); } function setMarketOrdersTimeout( uint _marketOrdersTimeout ) external onlyAdmin { marketOrdersTimeout = _marketOrdersTimeout; emit NumberUpdated("marketOrdersTimeout", _marketOrdersTimeout); } function setMarketOrderTightTimeRange( uint _marketOrderTightTimeRange ) external onlyAdmin { marketOrderTightTimeRange = _marketOrderTightTimeRange; emit NumberUpdated("marketOrderTightTimeRange", _marketOrderTightTimeRange); } function setTriggerPriceFreshnessTimeRange( uint _triggerPriceFreshnessTimeRange ) external onlyAdmin { triggerPriceFreshnessTimeRange = _triggerPriceFreshnessTimeRange; emit NumberUpdated( "triggerPriceFreshnessTimeRange", _triggerPriceFreshnessTimeRange ); } function setMarketOrderCancelFeeFraction( uint _marketOrderCancelFeeFraction ) external onlyAdmin { marketOrderCancelFeeFraction = _marketOrderCancelFeeFraction; emit NumberUpdated( "marketOrderCancelFeeFraction", _marketOrderCancelFeeFraction ); } function setOpenPositionCancellationFeeFraction( uint _openPositionCancellationFeeFraction ) external onlyAdmin { openPositionCancellationFeeFraction = _openPositionCancellationFeeFraction; emit NumberUpdated( "openPositionCancellationFeeFraction", _openPositionCancellationFeeFraction ); } function setMaxTriggersPerBlock( uint _maxTriggersPerBlock ) external onlyAdmin { maxTriggersPerBlock = _maxTriggersPerBlock; emit NumberUpdated("maxTriggersPerBlock", _maxTriggersPerBlock); } // ***** Open Position Triggers ***** /** * Triggers a openTrade at market price. * @dev This function does not revert (as long as the price is valid and the pending order exists), * in case of a failed condition for the trade order, The pending market order will be canceled. */ function trigger_openTrade_market( bytes32 _positionId, bytes[] calldata pricePayload ) external payable notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { ( TradingEnumsV1.PositionPhase phase, uint timestamp, uint16 pairId, bool long, uint32 spreadReductionF ) = tradingFloor.getPositionTriggerInfo(_positionId); require(timestamp > 0, "NO_PENDING_MARKET_ORDER"); require( phase == TradingEnumsV1.PositionPhase.OPEN_MARKET, "NOT_OPEN_MARKET" ); // ** Order price validity ** IPriceValidatorV1.ValidatedPrice memory validatedPrice = validatePriceForPairWithSafeguardsInternal( pairId, msg.value, pricePayload ); // ** Market order timestamp validity ** validateMarketOrderTimestampInternal(timestamp, validatedPrice.timestamp); uint64 priceAfterImpact = validatedPrice.price; uint64 triggerPrice = calculatePostSpreadPrice( pairId, priceAfterImpact, spreadReductionF, long ); safelyIncreaseTriggersPerBlock(); tradingFloor.openNewPosition_market( _positionId, triggerPrice, openPositionCancellationFeeFraction ); emit OpenPositionExecuted( msg.sender, _positionId, phase, triggerPrice, validatedPrice.price, validatedPrice.timestamp ); } function trigger_openTrade_limit( bytes32 _positionId, bytes[] calldata pricePayload ) external payable notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { ( TradingEnumsV1.PositionPhase phase, uint timestamp, uint16 pairId, bool long, uint32 spreadReductionF ) = tradingFloor.getPositionTriggerInfo(_positionId); require(timestamp > 0, "NO_PENDING_LIMIT_ORDER"); require(phase == TradingEnumsV1.PositionPhase.OPEN_LIMIT, "NOT_OPEN_LIMIT"); // Order price validity IPriceValidatorV1.ValidatedPrice memory validatedPrice = validatePriceForPairWithSafeguardsInternal( pairId, msg.value, pricePayload ); // Limit order timestamp validity validateLimitOrderTimestampInternal(timestamp, validatedPrice.timestamp); uint64 priceAfterImpact = validatedPrice.price; uint64 triggerPrice = calculatePostSpreadPrice( pairId, priceAfterImpact, spreadReductionF, long ); safelyIncreaseTriggersPerBlock(); tradingFloor.openNewPosition_limit( _positionId, triggerPrice, openPositionCancellationFeeFraction ); emit OpenPositionExecuted( msg.sender, _positionId, phase, triggerPrice, validatedPrice.price, validatedPrice.timestamp ); } // ***** Close Position Triggers ***** function trigger_closeTrade_market( bytes32 _positionId, bytes[] calldata pricePayload ) external payable notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { ( TradingEnumsV1.PositionPhase phase, uint timestamp, uint16 pairId, , ) = tradingFloor.getPositionTriggerInfo(_positionId); require(timestamp > 0, "NO_PENDING_MARKET_ORDER"); require( phase == TradingEnumsV1.PositionPhase.CLOSE_MARKET, "NOT_CLOSE_MARKET" ); // ** Market order price validity ** IPriceValidatorV1.ValidatedPrice memory validatedPrice = validatePriceForPairWithSafeguardsInternal( pairId, msg.value, pricePayload ); // ** Market order timestamp validity ** validateMarketOrderTimestampInternal(timestamp, validatedPrice.timestamp); uint64 priceAfterImpact = validatedPrice.price; uint64 triggerPrice = priceAfterImpact; safelyIncreaseTriggersPerBlock(); tradingFloor.closeExistingPosition_Market( _positionId, validatedPrice.price, triggerPrice ); emit ClosePositionExecuted( msg.sender, _positionId, phase, triggerPrice, validatedPrice.price, validatedPrice.timestamp ); } function trigger_closeTrade_SL( bytes32 _positionId, bytes[] calldata pricePayload ) external payable notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { (, , uint16 pairId, , ) = tradingFloor.getPositionTriggerInfo(_positionId); TradingFloorStructsV1.PositionLimitsInfo memory limitInfo = tradingFloor .positionLimitsInfoById(_positionId); require(pairId > 0, "NO_SUCH_POSITION"); require(limitInfo.sl > 0, "NO_SL"); uint slLastUpdated = limitInfo.slLastUpdated; // ** Price validity ** IPriceValidatorV1.ValidatedPrice memory validatedPrice = validatePriceForPairWithSafeguardsInternal( pairId, msg.value, pricePayload ); validateLimitOrderTimestampInternal( slLastUpdated, validatedPrice.timestamp ); uint64 triggerPrice = validatedPrice.price; safelyIncreaseTriggersPerBlock(); tradingFloor.closeExistingPosition_Limit( _positionId, TradingEnumsV1.LimitTrigger.SL, validatedPrice.price, triggerPrice ); emit SlExecuted( msg.sender, _positionId, pairId, triggerPrice, validatedPrice.price, validatedPrice.timestamp ); } function trigger_closeTrade_TP( bytes32 _positionId, bytes[] calldata pricePayload ) external payable notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { (, , uint16 pairId, , ) = tradingFloor.getPositionTriggerInfo(_positionId); TradingFloorStructsV1.PositionLimitsInfo memory limitInfo = tradingFloor .positionLimitsInfoById(_positionId); require(pairId > 0, "NO_SUCH_POSITION"); require(limitInfo.tp > 0, "NO_TP"); uint tpLastUpdated = limitInfo.tpLastUpdated; // ** Price validity ** IPriceValidatorV1.ValidatedPrice memory validatedPrice = validatePriceForPairWithSafeguardsInternal( pairId, msg.value, pricePayload ); validateLimitOrderTimestampInternal( tpLastUpdated, validatedPrice.timestamp ); uint64 triggerPrice = validatedPrice.price; // if (t.buy) { // require(finalPrice >= limitInfo.tp, "LONG_PRICE_LESS_THAN_TP"); // } else { // require(finalPrice <= limitInfo.tp, "SHORT_PRICE_MORE_THAN_TP"); // } safelyIncreaseTriggersPerBlock(); tradingFloor.closeExistingPosition_Limit( _positionId, TradingEnumsV1.LimitTrigger.TP, validatedPrice.price, triggerPrice ); emit TpExecuted( msg.sender, _positionId, pairId, triggerPrice, validatedPrice.price, validatedPrice.timestamp ); } function trigger_closeTrade_LIQ( bytes32 _positionId, bytes[] calldata pricePayload ) external payable notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { (, , uint16 pairId, , ) = tradingFloor.getPositionTriggerInfo(_positionId); require(pairId > 0, "NO_SUCH_POSITION"); IPriceValidatorV1.ValidatedPrice memory validatedPrice = validatePriceForPairWithSafeguardsInternal( pairId, msg.value, pricePayload ); uint64 triggerPrice = validatedPrice.price; safelyIncreaseTriggersPerBlock(); tradingFloor.closeExistingPosition_Limit( _positionId, TradingEnumsV1.LimitTrigger.LIQ, validatedPrice.price, triggerPrice ); emit LiquidationExecuted( msg.sender, _positionId, pairId, triggerPrice, validatedPrice.price, validatedPrice.timestamp ); } // ***** Update Position Triggers ***** function trigger_update_TP( bytes32 _positionId, bytes[] calldata pricePayload ) external payable notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { OrderBookStructsV1.UpdatePositionFieldOrder memory o = orderBook .readAndDeleteUpdatePositionOrder(_positionId); require( o.orderType == OrderBookStructsV1.UpdatePositionFieldOrderType.UPDATE_TP, "UPDATE_ORDER_NOT_TP" ); (, , uint16 pairId, , ) = tradingFloor.getPositionTriggerInfo(_positionId); IPriceValidatorV1.ValidatedPrice memory validatedPrice = validatePriceForPairWithSafeguardsInternal( pairId, msg.value, pricePayload ); // ** Market order timestamp validity ** validateMarketOrderTimestampInternal(o.timestamp, validatedPrice.timestamp); safelyIncreaseTriggersPerBlock(); uint64 triggerPrice = validatedPrice.price; safePositionSingleFieldUpdateInternal( msg.sender, _positionId, o.orderType, TradingEnumsV1.PositionField.TP, o.fieldValueA, triggerPrice ); } function trigger_update_SL( bytes32 _positionId, bytes[] calldata pricePayload ) external payable notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { OrderBookStructsV1.UpdatePositionFieldOrder memory o = orderBook .readAndDeleteUpdatePositionOrder(_positionId); require( o.orderType == OrderBookStructsV1.UpdatePositionFieldOrderType.UPDATE_SL, "UPDATE_ORDER_NOT_SL" ); (, , uint16 pairId, , ) = tradingFloor.getPositionTriggerInfo(_positionId); IPriceValidatorV1.ValidatedPrice memory validatedPrice = validatePriceForPairWithSafeguardsInternal( pairId, msg.value, pricePayload ); // ** Market order timestamp validity ** validateMarketOrderTimestampInternal(o.timestamp, validatedPrice.timestamp); safelyIncreaseTriggersPerBlock(); uint64 triggerPrice = validatedPrice.price; safePositionSingleFieldUpdateInternal( msg.sender, _positionId, o.orderType, TradingEnumsV1.PositionField.SL, o.fieldValueA, triggerPrice ); } function trigger_update_TP_and_SL( bytes32 _positionId, bytes[] calldata pricePayload ) external payable notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { OrderBookStructsV1.UpdatePositionFieldOrder memory o = orderBook .readAndDeleteUpdatePositionOrder(_positionId); require( o.orderType == OrderBookStructsV1.UpdatePositionFieldOrderType.UPDATE_TP_AND_SL, "UPDATE_ORDER_NOT_TP_AND_SL" ); (, , uint16 pairId, , ) = tradingFloor.getPositionTriggerInfo(_positionId); IPriceValidatorV1.ValidatedPrice memory validatedPrice = validatePriceForPairWithSafeguardsInternal( pairId, msg.value, pricePayload ); // ** Market order timestamp validity ** validateMarketOrderTimestampInternal(o.timestamp, validatedPrice.timestamp); safelyIncreaseTriggersPerBlock(); uint64 triggerPrice = validatedPrice.price; // Update TP require( safePositionSingleFieldUpdateInternal( msg.sender, _positionId, o.orderType, TradingEnumsV1.PositionField.TP, o.fieldValueA, triggerPrice ), "FAILED_TP_UPDATE" ); // Update SL require( safePositionSingleFieldUpdateInternal( msg.sender, _positionId, o.orderType, TradingEnumsV1.PositionField.SL, o.fieldValueB, triggerPrice ), "FAILED_SL_UPDATE" ); } function trigger_timeout_updatePosition( bytes32 _positionId ) external notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { OrderBookStructsV1.UpdatePositionFieldOrder memory o = orderBook .readAndDeleteUpdatePositionOrder(_positionId); require( block.timestamp >= o.timestamp + marketOrdersTimeout, "WAIT_TIMEOUT" ); emit PositionUpdateTimeoutTriggered( msg.sender, _positionId, o.orderType, o.fieldValueA, o.fieldValueB ); } function safePositionSingleFieldUpdateInternal( address triggerer, bytes32 _positionId, OrderBookStructsV1.UpdatePositionFieldOrderType orderType, TradingEnumsV1.PositionField positionField, uint64 fieldValue, uint64 triggerPrice ) internal returns (bool) { try tradingFloor.updateOpenedPosition( _positionId, positionField, fieldValue, triggerPrice ) { emit UpdatePositionSingleFieldExecuted( triggerer, _positionId, orderType, positionField, fieldValue, triggerPrice ); return true; } catch Error(string memory error) { // Note : Will happen from Normal 'require' emit UpdatePositionSingleFieldRejected( triggerer, _positionId, orderType, positionField, fieldValue, triggerPrice, error, 0 ); return false; } catch (bytes memory err) { // CapError (should only happen when updating TP) if (bytes4(err) == LexErrors.CapError.selector) { require( positionField == TradingEnumsV1.PositionField.TP, "CAP_ERROR_NOT_ON_TP" ); LexErrors.CapType capType; uint256 value; assembly { capType := mload(add(err, 0x24)) value := mload(add(err, 0x44)) } emit UpdatePositionSingleFieldRejected( triggerer, _positionId, orderType, positionField, fieldValue, triggerPrice, "CAP_ERROR", uint(capType) ); return false; } else { revert("UNKNOWN_CUSTOM_ERROR"); } } } // ***** Market Requests Timeout Triggers ***** function trigger_timeout_marketOpen( bytes32 _positionId ) external notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { ( TradingEnumsV1.PositionPhase phase, uint timestamp, uint16 pairId, , ) = tradingFloor.getPositionTriggerInfo(_positionId); require(timestamp > 0, "NO_SUCH_POSITION"); require( phase == TradingEnumsV1.PositionPhase.OPEN_MARKET, "NOT_OPEN_MARKET" ); require(block.timestamp >= timestamp + marketOrdersTimeout, "WAIT_TIMEOUT"); tradingFloor.cancelPendingPosition( _positionId, TradingEnumsV1.OpenOrderType.MARKET, marketOrderCancelFeeFraction ); emit MarketOpenTimeoutTriggered(msg.sender, _positionId, pairId); } function trigger_timeout_marketClose( bytes32 _positionId ) external notDoneOrPaused onlyAllowedTriggerAccount nonReentrant { ( TradingEnumsV1.PositionPhase phase, uint timestamp, uint16 pairId, , ) = tradingFloor.getPositionTriggerInfo(_positionId); require(timestamp > 0, "NO_SUCH_POSITION"); require( phase == TradingEnumsV1.PositionPhase.CLOSE_MARKET, "NOT_CLOSE_MARKET" ); require(block.timestamp >= timestamp + marketOrdersTimeout, "WAIT_TIMEOUT"); tradingFloor.cancelMarketCloseForPosition( _positionId, TradingEnumsV1.CloseOrderType.MARKET, marketOrderCancelFeeFraction ); emit MarketCloseTimeoutTriggered(msg.sender, _positionId, pairId); } // ***** Price Validations Utils ***** /** * Validates the payload and reverts if the price confidence is too high */ function validatePriceForPairWithSafeguardsInternal( uint pairId, uint nativePayment, bytes[] calldata pricePayload ) internal returns (IPriceValidatorV1.ValidatedPrice memory) { IPriceValidatorV1.ValidatedPrice memory validatedPrice = validatePriceForPairInternal( pairId, nativePayment, pricePayload ); uint maxConfidenceF = maxConfidenceFractionForPair[pairId]; uint maxAllowedConfidence = calculateFractionInternal( uint(validatedPrice.price), maxConfidenceF ); require( validatedPrice.confidence <= maxAllowedConfidence, "CONFIDENCE_RANGE_TOO_WIDE" ); require( validatedPrice.timestamp <= block.timestamp, "FUTURE_PRICE_REPORTED" ); return validatedPrice; } function validatePriceForPairInternal( uint pairIndex, uint nativePayment, bytes[] calldata pricePayload ) internal returns (IPriceValidatorV1.ValidatedPrice memory) { return priceValidator.validatePrice{value: nativePayment}( pairIndex, pricePayload ); } /** * The time frame for triggering market orders is [orderTimestamp + minTriggerPeriodForMarketOrders, orderTimestamp + maxTriggerPeriodForMarketOrders] * Both the block.timestamp and the price timestamp MUST be withing this frame */ function validateMarketOrderTimestampInternal( uint pendingMarketOrderTimestamp, uint priceTimestamp ) internal view { uint orderActivationEarliestTimestamp = pendingMarketOrderTimestamp + minTriggerPeriodForMarketOrders; uint orderActivationLatestTimestamp = pendingMarketOrderTimestamp + maxTriggerPeriodForMarketOrders; require( block.timestamp >= orderActivationEarliestTimestamp, "MARKET_ORDER_TRIGGER_TOO_SOON" ); require( block.timestamp <= orderActivationLatestTimestamp, "MARKET_ORDER_TRIGGER_TOO_LATE" ); require( priceTimestamp >= orderActivationEarliestTimestamp && priceTimestamp <= orderActivationLatestTimestamp, "MARKET_ORDER_PRICE_OUT_OF_TIME_FRAME" ); } function validateLimitOrderTimestampInternal( uint pendingLimitOrderTimestamp, uint priceTimestamp ) internal view { // ** Limit order timestamp validity ** uint orderActivationEarliestTimestamp = pendingLimitOrderTimestamp + minTriggerPeriodForLimitOrders; require( block.timestamp >= orderActivationEarliestTimestamp, "LIMIT_ORDER_TRIGGER_TOO_SOON" ); // The price must be reported after the limit order activation timestamp require( priceTimestamp >= orderActivationEarliestTimestamp, "LIMIT_ORDER_PRICE_OUT_OF_TIME_FRAME" ); // The reported price cannot be too long in the past validateTriggerPriceRecentInternal( priceTimestamp, triggerPriceFreshnessTimeRange ); } /** * @notice ensures the given timestamp is not older than the given window (in seconds) */ function validateTriggerPriceRecentInternal( uint priceTimestamp, uint acceptedWindow ) internal view { uint oldestTimestamp = block.timestamp - acceptedWindow; require(priceTimestamp >= oldestTimestamp, "PRICE_TOO_OLD"); // Sanity, price cannot be from the future require(priceTimestamp <= block.timestamp, "PRICE_TOO_NEW"); } // ***** Limitation functions ***** function safelyIncreaseTriggersPerBlock() internal { uint currentBlockTriggers = triggersPerBlock[block.number]; require( currentBlockTriggers < maxTriggersPerBlock, "MAX_TRIGGERS_PER_BLOCK" ); triggersPerBlock[block.number] = currentBlockTriggers + 1; } // ***** Internal Utils ***** function calculateFractionInternal( uint amount, uint fraction ) internal pure returns (uint) { return (amount * fraction) / FRACTION_SCALE; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.20; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position is the index of the value in the `values` array plus 1. // Position 0 is used to mean a value is not in the set. mapping(bytes32 value => uint256) _positions; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._positions[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We cache the value's position to prevent multiple reads from the same storage slot uint256 position = set._positions[value]; if (position != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 valueIndex = position - 1; uint256 lastIndex = set._values.length - 1; if (valueIndex != lastIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the lastValue to the index where the value to delete is set._values[valueIndex] = lastValue; // Update the tracked position of the lastValue (that was just moved) set._positions[lastValue] = position; } // Delete the slot where the moved value was stored set._values.pop(); // Delete the tracked position for the deleted slot delete set._positions[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._positions[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; contract ClaimableAdminStorage { /** * @notice Administrator for this contract */ address public admin; /** * @notice Pending administrator for this contract */ address public pendingAdmin; /*** Modifiers ***/ modifier onlyAdmin() { require(msg.sender == admin, "ONLY_ADMIN"); _; } /*** Constructor ***/ constructor() { // Set admin to caller admin = msg.sender; } } contract AcceptableImplementationClaimableAdminStorage is ClaimableAdminStorage { /** * @notice Active logic */ address public implementation; /** * @notice Pending logic */ address public pendingImplementation; } contract AcceptableRegistryImplementationClaimableAdminStorage is AcceptableImplementationClaimableAdminStorage { /** * @notice System Registry */ address public registry; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; import "./AcceptableImplementationClaimableAdminStorage.sol"; /** * @title Claimable Admin */ contract ClaimableAdmin is ClaimableAdminStorage { /** * @notice Emitted when pendingAdmin is changed */ event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin); /** * @notice Emitted when pendingAdmin is accepted, which means admin is updated */ event NewAdmin(address oldAdmin, address newAdmin); /*** Admin Functions ***/ /** * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer. * @param newPendingAdmin New pending admin. */ function _setPendingAdmin(address newPendingAdmin) public { // Check caller = admin require(msg.sender == admin, "Not Admin"); // Save current value, if any, for inclusion in log address oldPendingAdmin = pendingAdmin; // Store pendingAdmin with value newPendingAdmin pendingAdmin = newPendingAdmin; // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin) emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin); } /** * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin * @dev Admin function for pending admin to accept role and update admin */ function _acceptAdmin() public { // Check caller is pendingAdmin and pendingAdmin ≠ address(0) require( msg.sender == pendingAdmin && pendingAdmin != address(0), "Not the EXISTING pending admin" ); // Save current values for inclusion in log address oldAdmin = admin; address oldPendingAdmin = pendingAdmin; // Store admin with value pendingAdmin admin = pendingAdmin; // Clear the pending value pendingAdmin = address(0); emit NewAdmin(oldAdmin, admin); emit NewPendingAdmin(oldPendingAdmin, pendingAdmin); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; interface IContractRegistryBase { function isImplementationValidForProxy( bytes32 proxyNameHash, address _implementation ) external view returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; /** * @dev only use immutables and constants in this contract */ contract CommonScales { uint256 public constant PRECISION = 1e18; // 18 decimals uint256 public constant LEVERAGE_SCALE = 100; // 2 decimal points uint256 public constant FRACTION_SCALE = 100000; // 5 decimal points uint256 public constant ACCURACY_IMPROVEMENT_SCALE = 1e9; function calculateLeveragedPosition( uint256 collateral, uint256 leverage ) internal pure returns (uint256) { return (collateral * leverage) / LEVERAGE_SCALE; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; interface IFundingRateModel { // return value is the "funding paid by heavier side" in PRECISION per OI (heavier side) per second // e.g : (0.01 * PRECISION) = Paying (heavier) side (as a whole) pays 1% of funding per second for each OI unit function getFundingRate( uint256 pairId, uint256 openInterestLong, uint256 openInterestShort, uint256 pairMaxOpenInterest ) external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; interface IGlobalLock { function lock() external; function freeLock() external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; interface IInterestRateModel { // Returns asset/second of interest per borrowed unit // e.g : (0.01 * PRECISION) = 1% of interest per second function getBorrowRate(uint256 utilization) external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; import "./LexErrors.sol"; import "./LexPoolAdminEnums.sol"; import "./IPoolAccountantV1.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface LexPoolStructs { struct PendingDeposit { uint256 amount; uint256 minAmountOut; } struct PendingRedeem { uint256 amount; uint256 minAmountOut; uint256 maxAmountOut; } } interface LexPoolEvents is LexPoolAdminEnums { event NewEpoch( uint256 epochId, int256 reportedUnrealizedPricePnL, uint256 exchangeRate, uint256 virtualUnderlyingBalance, uint256 totalSupply ); event AddressUpdated(LexPoolAddressesEnum indexed enumCode, address a); event NumberUpdated(LexPoolNumbersEnum indexed enumCode, uint value); event DepositRequest( address indexed user, uint256 amount, uint256 minAmountOut, uint256 processingEpoch ); event RedeemRequest( address indexed user, uint256 amount, uint256 minAmountOut, uint256 processingEpoch ); event ProcessedDeposit( address indexed user, bool deposited, uint256 depositedAmount ); event ProcessedRedeem( address indexed user, bool redeemed, uint256 withdrawnAmount // Underlying amount ); event CanceledDeposit( address indexed user, uint256 epoch, uint256 cancelledAmount ); event CanceledRedeem( address indexed user, uint256 epoch, uint256 cancelledAmount ); event ImmediateDepositAllowedToggled(bool indexed value); event ImmediateDeposit( address indexed depositor, uint256 depositAmount, uint256 mintAmount ); event ReservesWithdrawn( address _to, uint256 interestShare, uint256 totalFundingShare ); } interface ILexPoolFunctionality is IERC20, LexPoolStructs, LexPoolEvents, LexErrors { function setPoolAccountant( IPoolAccountantFunctionality _poolAccountant ) external; function setPnlRole(address pnl) external; function setMaxExtraWithdrawalAmountF(uint256 maxExtra) external; function setEpochsDelayDeposit(uint256 delay) external; function setEpochsDelayRedeem(uint256 delay) external; function setEpochDuration(uint256 duration) external; function setMinDepositAmount(uint256 amount) external; function toggleImmediateDepositAllowed() external; function reduceReserves( address _to ) external returns (uint256 interestShare, uint256 totalFundingShare); function requestDeposit( uint256 amount, uint256 minAmountOut, bytes32 domain, bytes32 referralCode ) external; function requestDepositViaIntent( address user, uint256 amount, uint256 minAmountOut, bytes32 domain, bytes32 referralCode ) external; function requestRedeem(uint256 amount, uint256 minAmountOut) external; function requestRedeemViaIntent( address user, uint256 amount, uint256 minAmountOut ) external; function processDeposit( address[] memory users ) external returns ( uint256 amountDeposited, uint256 amountCancelled, uint256 counterDeposited, uint256 counterCancelled ); function cancelDeposits( address[] memory users, uint256[] memory epochs ) external; function processRedeems( address[] memory users ) external returns ( uint256 amountRedeemed, uint256 amountCancelled, uint256 counterDeposited, uint256 counterCancelled ); function cancelRedeems( address[] memory users, uint256[] memory epochs ) external; function nextEpoch( int256 totalUnrealizedPricePnL ) external returns (uint256 newExchangeRate); function currentVirtualUtilization() external view returns (uint256); function currentVirtualUtilization( uint256 totalBorrows, uint256 totalReserves, int256 unrealizedFunding ) external view returns (uint256); function virtualBalanceForUtilization() external view returns (uint256); function virtualBalanceForUtilization( uint256 extraAmount, int256 unrealizedFunding ) external view returns (uint256); function underlyingBalanceForExchangeRate() external view returns (uint256); function sendAssetToTrader(address to, uint256 amount) external; function isUtilizationForLPsValid() external view returns (bool); } interface ILexPoolV1 is ILexPoolFunctionality { function name() external view returns (string memory); function symbol() external view returns (string memory); function SELF_UNIT_SCALE() external view returns (uint); function underlyingDecimals() external view returns (uint256); function poolAccountant() external view returns (address); function underlying() external view returns (IERC20); function tradingFloor() external view returns (address); function currentEpoch() external view returns (uint256); function currentExchangeRate() external view returns (uint256); function nextEpochStartMin() external view returns (uint256); function epochDuration() external view returns (uint256); function minDepositAmount() external view returns (uint256); function epochsDelayDeposit() external view returns (uint256); function epochsDelayRedeem() external view returns (uint256); function immediateDepositAllowed() external view returns (bool); function pendingDeposits( uint epoch, address account ) external view returns (PendingDeposit memory); function pendingRedeems( uint epoch, address account ) external view returns (PendingRedeem memory); function pendingDepositAmount() external view returns (uint256); function pendingWithdrawalAmount() external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; // import "./ITokenV1.sol"; import "./OrderBookStructsV1.sol"; import "./TradingFloorStructsV1.sol"; interface IOrderBookFunctionalityV1 is OrderBookStructsV1 { // Update Position Orders function storeUpdatePositionSingleFieldOrder( bytes32 _positionId, UpdatePositionFieldOrderType orderType, uint64 fieldValue ) external returns (UpdatePositionFieldOrder memory); function storeUpdatePositionDoubleFieldOrder( bytes32 _positionId, UpdatePositionFieldOrderType orderType, uint64 fieldValueA, uint64 fieldValueB ) external returns (UpdatePositionFieldOrder memory); function readAndDeleteUpdatePositionOrder( bytes32 _positionId ) external returns (UpdatePositionFieldOrder memory order); } interface IOrderBookV1 is IOrderBookFunctionalityV1 { function PRECISION() external pure returns (uint); // *** Public Storage addresses *** function tradingFloor() external view returns (address); // *** Public Storage params *** function pendingUpdateTradeFieldOrdersById( bytes32 positionId ) external view returns (UpdatePositionFieldOrder memory); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; import "./LexErrors.sol"; import "./ILexPoolV1.sol"; import "./IInterestRateModel.sol"; import "./IFundingRateModel.sol"; import "./TradingEnumsV1.sol"; interface PoolAccountantStructs { // @note To be used for passing information in function calls struct PositionRegistrationParams { uint256 collateral; uint32 leverage; bool long; uint64 openPrice; uint64 tp; } struct PairFunding { // Slot 0 int256 accPerOiLong; // 32 bytes -- Underlying Decimals // Slot 1 int256 accPerOiShort; // 32 bytes -- Underlying Decimals // Slot 2 uint256 lastUpdateTimestamp; // 32 bytes } struct TradeInitialAccFees { // Slot 0 uint256 borrowIndex; // 32 bytes // Slot 1 int256 funding; // 32 bytes -- underlying units -- Underlying Decimals } struct PairOpenInterest { // Slot 0 uint256 long; // 32 bytes -- underlying units -- Dynamic open interest for long positions // Slot 1 uint256 short; // 32 bytes -- underlying units -- Dynamic open interest for short positions } // This struct is not kept in storage struct PairFromTo { string from; string to; } struct Pair { // Slot 0 uint16 id; // 02 bytes uint16 groupId; // 02 bytes uint16 feeId; // 02 bytes uint32 minLeverage; // 04 bytes uint32 maxLeverage; // 04 bytes uint32 maxBorrowF; // 04 bytes -- FRACTION_SCALE (5) // Slot 1 uint256 maxPositionSize; // 32 bytes -- underlying units // Slot 2 uint256 maxGain; // 32 bytes -- underlying units // Slot 3 uint256 maxOpenInterest; // 32 bytes -- Underlying units // Slot 4 uint256 maxSkew; // 32 bytes -- underlying units // Slot 5 uint256 minOpenFee; // 32 bytes -- underlying units. MAX_UINT means use the default group level value // Slot 6 uint256 minPerformanceFee; // 32 bytes -- underlying units } struct Group { // Slot 0 uint16 id; // 02 bytes uint32 minLeverage; // 04 bytes uint32 maxLeverage; // 04 bytes uint32 maxBorrowF; // 04 bytes -- FRACTION_SCALE (5) // Slot 1 uint256 maxPositionSize; // 32 bytes (Underlying units) // Slot 2 uint256 minOpenFee; // 32 bytes (Underlying uints). MAX_UINT means use the default global level value } struct Fee { // Slot 0 uint16 id; // 02 bytes uint32 openFeeF; // 04 bytes -- FRACTION_SCALE (5) (Fraction of leveraged pos) uint32 closeFeeF; // 04 bytes -- FRACTION_SCALE (5) (Fraction of leveraged pos) uint32 performanceFeeF; // 04 bytes -- FRACTION_SCALE (5) (Fraction of performance) } } interface PoolAccountantEvents is PoolAccountantStructs { event PairAdded( uint256 indexed id, string indexed from, string indexed to, Pair pair ); event PairUpdated(uint256 indexed id, Pair pair); event GroupAdded(uint256 indexed id, string indexed groupName, Group group); event GroupUpdated(uint256 indexed id, Group group); event FeeAdded(uint256 indexed id, string indexed name, Fee fee); event FeeUpdated(uint256 indexed id, Fee fee); event TradeInitialAccFeesStored( bytes32 indexed positionId, uint256 borrowIndex, // uint256 rollover, int256 funding ); event AccrueFunding( uint256 indexed pairId, int256 valueLong, int256 valueShort ); event ProtocolFundingShareAccrued( uint16 indexed pairId, uint256 protocolFundingShare ); // event AccRolloverFeesStored(uint256 pairIndex, uint256 value); event FeesCharged( bytes32 indexed positionId, address indexed trader, uint16 indexed pairId, PositionRegistrationParams positionRegistrationParams, // bool long, // uint256 collateral, // Underlying Decimals // uint256 leverage, int256 profitPrecision, // PRECISION uint256 interest, int256 funding, // Underlying Decimals uint256 closingFee, uint256 tradeValue ); event PerformanceFeeCharging( bytes32 indexed positionId, uint256 performanceFee ); event MaxOpenInterestUpdated(uint256 pairIndex, uint256 maxOpenInterest); event AccrueInterest( uint256 cash, uint256 totalInterestNew, uint256 borrowIndexNew, uint256 interestShareNew ); event Borrow( uint256 indexed pairId, uint256 borrowAmount, uint256 newTotalBorrows ); event Repay( uint256 indexed pairId, uint256 repayAmount, uint256 newTotalBorrows ); } interface IPoolAccountantFunctionality is PoolAccountantStructs, PoolAccountantEvents, LexErrors, TradingEnumsV1 { function setTradeIncentivizer(address _tradeIncentivizer) external; function setMaxGainF(uint256 _maxGainF) external; function setFrm(IFundingRateModel _frm) external; function setMinOpenFee(uint256 min) external; function setLexPartF(uint256 partF) external; function setFundingRateMax(uint256 maxValue) external; function setLiquidationThresholdF(uint256 threshold) external; function setLiquidationFeeF(uint256 fee) external; function setIrm(IInterestRateModel _irm) external; function setIrmHard(IInterestRateModel _irm) external; function setInterestShareFactor(uint256 factor) external; function setFundingShareFactor(uint256 factor) external; function setBorrowRateMax(uint256 rate) external; function setMaxTotalBorrows(uint256 maxBorrows) external; function setMaxVirtualUtilization(uint256 _maxVirtualUtilization) external; function resetTradersPairGains(uint256 pairId) external; function addGroup(Group calldata _group) external; function updateGroup(Group calldata _group) external; function addFee(Fee calldata _fee) external; function updateFee(Fee calldata _fee) external; function addPair(Pair calldata _pair) external; function addPairs(Pair[] calldata _pairs) external; function updatePair(Pair calldata _pair) external; function readAndZeroReserves() external returns (uint256 accumulatedInterestShare, uint256 accFundingShare); function registerOpenTrade( bytes32 positionId, address trader, uint16 pairId, uint256 collateral, uint32 leverage, bool long, uint256 tp, uint256 openPrice ) external returns (uint256 fee, uint256 lexPartFee); function registerCloseTrade( bytes32 positionId, address trader, uint16 pairId, PositionRegistrationParams calldata positionRegistrationParams, uint256 closePrice, PositionCloseType positionCloseType ) external returns ( uint256 closingFee, uint256 tradeValue, int256 profitPrecision, uint finalClosePrice ); function registerUpdateTp( bytes32 positionId, address trader, uint16 pairId, uint256 collateral, uint32 leverage, bool long, uint256 openPrice, uint256 oldTriggerPrice, uint256 triggerPrice ) external; // function registerUpdateSl( // address trader, // uint256 pairIndex, // uint256 index, // uint256 collateral, // uint256 leverage, // bool long, // uint256 openPrice, // uint256 triggerPrice // ) external returns (uint256 fee); function accrueInterest() external returns ( uint256 totalInterestNew, uint256 interestShareNew, uint256 borrowIndexNew ); // Limited only for the LexPool function accrueInterest( uint256 availableCash ) external returns ( uint256 totalInterestNew, uint256 interestShareNew, uint256 borrowIndexNew ); function getTradeClosingValues( bytes32 positionId, uint16 pairId, PositionRegistrationParams calldata positionRegistrationParams, uint256 closePrice, bool isLiquidation ) external returns ( uint256 tradeValue, // Underlying Decimals uint256 safeClosingFee, int256 profitPrecision, uint256 interest, int256 funding ); function getTradeLiquidationPrice( bytes32 positionId, uint16 pairId, uint256 openPrice, // PRICE_SCALE (8) uint256 tp, bool long, uint256 collateral, // Underlying Decimals uint32 leverage ) external returns ( uint256 // PRICE_SCALE (8) ); function calcTradeDynamicFees( bytes32 positionId, uint16 pairId, bool long, uint256 collateral, uint32 leverage, uint256 openPrice, uint256 tp ) external returns (uint256 interest, int256 funding); function unrealizedFunding() external view returns (int256); function totalBorrows() external view returns (uint256); function interestShare() external view returns (uint256); function fundingShare() external view returns (uint256); function totalReservesView() external view returns (uint256); function borrowsAndInterestShare() external view returns (uint256 totalBorrows, uint256 totalInterestShare); function pairTotalOpenInterest( uint256 pairIndex ) external view returns (int256); function pricePnL( uint256 pairId, uint256 price ) external view returns (int256); function getAllSupportedPairIds() external view returns (uint16[] memory); function getAllSupportedGroupsIds() external view returns (uint16[] memory); function getAllSupportedFeeIds() external view returns (uint16[] memory); } interface IPoolAccountantV1 is IPoolAccountantFunctionality { function totalBorrows() external view returns (uint256); function maxTotalBorrows() external view returns (uint256); function pairBorrows(uint256 pairId) external view returns (uint256); function groupBorrows(uint256 groupId) external view returns (uint256); function pairMaxBorrow(uint16 pairId) external view returns (uint256); function groupMaxBorrow(uint16 groupId) external view returns (uint256); function lexPool() external view returns (ILexPoolV1); function maxGainF() external view returns (uint256); function interestShareFactor() external view returns (uint256); function fundingShareFactor() external view returns (uint256); function frm() external view returns (IFundingRateModel); function irm() external view returns (IInterestRateModel); function pairs(uint16 pairId) external view returns (Pair memory); function groups(uint16 groupId) external view returns (Group memory); function fees(uint16 feeId) external view returns (Fee memory); function openInterestInPair( uint pairId ) external view returns (PairOpenInterest memory); function minOpenFee() external view returns (uint256); function liquidationThresholdF() external view returns (uint256); function liquidationFeeF() external view returns (uint256); function lexPartF() external view returns (uint256); function tradersPairGains(uint256 pairId) external view returns (int256); function calcBorrowAmount( uint256 collateral, uint256 leverage, bool long, uint256 openPrice, uint256 tp ) external pure returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; interface IPriceValidatorV1 { // uint constant PRICE_SCALE = 1e8; struct ValidatedPrice { uint256 timestamp; uint64 price; // Scaled to PRICE_SCALE uint64 confidence; // Scaled to PRICE_SCALE } function isPriceValidator() external view returns (bool); function getUpdateFee( bytes[] calldata updateData ) external view returns (uint256 feeAmount); function validatePrice( uint256 pairIndex, bytes[] calldata updateData ) external payable returns (ValidatedPrice memory validatedPrice); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; import "../../AdministrationContracts/IContractRegistryBase.sol"; import "./IGlobalLock.sol"; interface IRegistryV1Functionality is IContractRegistryBase, IGlobalLock { // **** Locking mechanism **** function isTradersPortalAndLocker( address _address ) external view returns (bool); function isTriggersAndLocker(address _address) external view returns (bool); function isTradersPortalOrTriggersAndLocker( address _address ) external view returns (bool); } interface IRegistryV1 is IRegistryV1Functionality { // **** Public Storage params **** function feesManagers(address asset) external view returns (address); function orderBook() external view returns (address); function tradersPortal() external view returns (address); function triggers() external view returns (address); function tradeIntentsVerifier() external view returns (address); function liquidityIntentsVerifier() external view returns (address); function chipsIntentsVerifier() external view returns (address); function lexProxiesFactory() external view returns (address); function chipsFactory() external view returns (address); /** * @return An array of all supported trading floors */ function getAllSupportedTradingFloors() external view returns (address[] memory); /** * @return An array of all supported settlement assets */ function getSettlementAssetsForTradingFloor( address _tradingFloor ) external view returns (address[] memory); /** * @return The spender role address that is set for this chip */ function getValidSpenderTargetForChipByRole( address chip, string calldata role ) external view returns (address); /** * @return the address of the valid 'burnHandler' for the chip */ function validBurnHandlerForChip( address chip ) external view returns (address); /** * @return The address matching for the given role */ function getDynamicRoleAddress( string calldata _role ) external view returns (address); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; import "./TradingFloorStructsV1.sol"; import "./IPoolAccountantV1.sol"; import "./ILexPoolV1.sol"; interface ITradingFloorV1Functionality is TradingFloorStructsV1 { function supportNewSettlementAsset( address _asset, address _lexPool, address _poolAccountant ) external; function getPositionTriggerInfo( bytes32 _positionId ) external view returns ( PositionPhase positionPhase, uint64 timestamp, uint16 pairId, bool long, uint32 spreadReductionF ); function getPositionPortalInfo( bytes32 _positionId ) external view returns ( PositionPhase positionPhase, uint64 inPhaseSince, address positionTrader ); function storePendingPosition( OpenOrderType _orderType, PositionRequestIdentifiers memory _requestIdentifiers, PositionRequestParams memory _requestParams, uint32 _spreadReductionF ) external returns (bytes32 positionId); function setOpenedPositionToMarketClose( bytes32 _positionId, uint64 _minPrice, uint64 _maxPrice ) external; function cancelPendingPosition( bytes32 _positionId, OpenOrderType _orderType, uint feeFraction ) external; function cancelMarketCloseForPosition( bytes32 _positionId, CloseOrderType _orderType, uint feeFraction ) external; function updatePendingPosition_openLimit( bytes32 _positionId, uint64 _minPrice, uint64 _maxPrice, uint64 _tp, uint64 _sl ) external; function openNewPosition_market( bytes32 _positionId, uint64 assetEffectivePrice, uint256 feeForCancellation ) external; function openNewPosition_limit( bytes32 _positionId, uint64 assetEffectivePrice, uint256 feeForCancellation ) external; function closeExistingPosition_Market( bytes32 _positionId, uint64 assetPrice, uint64 effectivePrice ) external; function closeExistingPosition_Limit( bytes32 _positionId, LimitTrigger limitTrigger, uint64 assetPrice, uint64 effectivePrice ) external; // Manage open trade function updateOpenedPosition( bytes32 _positionId, PositionField updateField, uint64 fieldValue, uint64 effectivePrice ) external; // Fees function collectFee(address _asset, FeeType _feeType, address _to) external; } interface ITradingFloorV1 is ITradingFloorV1Functionality { function PRECISION() external pure returns (uint); // *** Views *** function pairTradersArray( address _asset, uint _pairIndex ) external view returns (address[] memory); function generatePositionHashId( address settlementAsset, address trader, uint16 pairId, uint32 index ) external pure returns (bytes32 hashId); // *** Public Storage addresses *** function lexPoolForAsset(address asset) external view returns (ILexPoolV1); function poolAccountantForAsset( address asset ) external view returns (IPoolAccountantV1); function registry() external view returns (address); // *** Public Storage params *** function positionsById(bytes32 id) external view returns (Position memory); function positionIdentifiersById( bytes32 id ) external view returns (PositionIdentifiers memory); function positionLimitsInfoById( bytes32 id ) external view returns (PositionLimitsInfo memory); function triggerPricesById( bytes32 id ) external view returns (PositionTriggerPrices memory); function pairTradersInfo( address settlementAsset, address trader, uint pairId ) external view returns (PairTraderInfo memory); function spreadReductionsP(uint) external view returns (uint); function maxSlF() external view returns (uint); function maxTradesPerPair() external view returns (uint); function maxSanityProfitF() external view returns (uint); function feesMap( address settlementAsset, FeeType feeType ) external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; interface LexErrors { enum CapType { NONE, // 0 MIN_OPEN_FEE, // 1 MAX_POS_SIZE_PAIR, // 2 MAX_POS_SIZE_GROUP, // 3 MAX_LEVERAGE, // 4 MIN_LEVERAGE, // 5 MAX_VIRTUAL_UTILIZATION, // 6 MAX_OPEN_INTEREST, // 7 MAX_ABS_SKEW, // 8 MAX_BORROW_PAIR, // 9 MAX_BORROW_GROUP, // 10 MIN_DEPOSIT_AMOUNT, // 11 MAX_ACCUMULATED_GAINS, // 12 BORROW_RATE_MAX, // 13 FUNDING_RATE_MAX, // 14 MAX_POTENTIAL_GAIN, // 15 MAX_TOTAL_BORROW, // 16 MIN_PERFORMANCE_FEE // 17 //... } error CapError(CapType, uint256 value); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; interface LexPoolAdminEnums { enum LexPoolAddressesEnum { none, poolAccountant, pnlRole } enum LexPoolNumbersEnum { none, maxExtraWithdrawalAmountF, epochsDelayDeposit, epochsDelayRedeem, epochDuration, minDepositAmount } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; // import "./ITokenV1.sol"; import "./TradingFloorStructsV1.sol"; interface OrderBookStructsV1 { enum UpdatePositionFieldOrderType { NONE, UPDATE_TP, UPDATE_SL, UPDATE_TP_AND_SL } struct UpdatePositionFieldOrder { // Slot 0 bytes32 positionId; // 32 bytes // Slot 1 UpdatePositionFieldOrderType orderType; // 01 bytes uint64 timestamp; // 08 bytes uint64 fieldValueA; // 08 bytes uint64 fieldValueB; // 08 bytes } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; interface TradingEnumsV1 { enum PositionPhase { NONE, OPEN_MARKET, OPEN_LIMIT, OPENED, CLOSE_MARKET, CLOSED } enum OpenOrderType { NONE, MARKET, LIMIT } enum CloseOrderType { NONE, MARKET } enum FeeType { NONE, OPEN_FEE, CLOSE_FEE, TRIGGER_FEE } enum LimitTrigger { NONE, TP, SL, LIQ } enum PositionField { NONE, TP, SL } enum PositionCloseType { NONE, TP, SL, LIQ, MARKET } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; import "./TradingEnumsV1.sol"; interface TradingFloorStructsV1 is TradingEnumsV1 { enum AdminNumericParam { NONE, MAX_TRADES_PER_PAIR, MAX_SL_F, MAX_SANITY_PROFIT_F } /** * @dev Memory struct for identifiers */ struct PositionRequestIdentifiers { address trader; uint16 pairId; address settlementAsset; uint32 positionIndex; } struct PositionRequestParams { bool long; uint256 collateral; // Settlement Asset Decimals uint32 leverage; uint64 minPrice; // PRICE_SCALE uint64 maxPrice; // PRICE_SCALE uint64 tp; // PRICE_SCALE uint64 sl; // PRICE_SCALE uint64 tpByFraction; // FRACTION_SCALE uint64 slByFraction; // FRACTION_SCALE } /** * @dev Storage struct for identifiers */ struct PositionIdentifiers { // Slot 0 address settlementAsset; // 20 bytes uint16 pairId; // 02 bytes uint32 index; // 04 bytes // Slot 1 address trader; // 20 bytes } struct Position { // Slot 0 uint collateral; // 32 bytes -- Settlement Asset Decimals // Slot 1 PositionPhase phase; // 01 bytes uint64 inPhaseSince; // 08 bytes uint32 leverage; // 04 bytes bool long; // 01 bytes uint64 openPrice; // 08 bytes -- PRICE_SCALE (8) uint32 spreadReductionF; // 04 bytes -- FRACTION_SCALE (5) } /** * Holds the non liquidation limits for the position */ struct PositionLimitsInfo { uint64 tpLastUpdated; // 08 bytes -- timestamp uint64 slLastUpdated; // 08 bytes -- timestamp uint64 tp; // 08 bytes -- PRICE_SCALE (8) uint64 sl; // 08 bytes -- PRICE_SCALE (8) } /** * Holds the prices for opening (and market closing) of a position */ struct PositionTriggerPrices { uint64 minPrice; // 08 bytes -- PRICE_SCALE uint64 maxPrice; // 08 bytes -- PRICE_SCALE uint64 tpByFraction; // 04 bytes -- FRACTION_SCALE uint64 slByFraction; // 04 bytes -- FRACTION_SCALE } /** * @dev administration struct, used to keep tracks on the 'PairTraders' list and * to limit the amount of positions a trader can have */ struct PairTraderInfo { uint32 positionsCounter; // 04 bytes uint32 positionInArray; // 04 bytes (the index + 1) // Note : Can add more fields here } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; import "../interfaces/IGlobalLock.sol"; /** * @notice Common contract to handle the global system locks * @dev This contract MUST NOT have any storage variables to not affect the storage layout */ contract SystemLocker { address private immutable globalLock; constructor(address _globalLock) { globalLock = _globalLock; } // ***** Reentrancy Guard ***** /** * @dev Prevents a contract from calling itself, directly or indirectly. */ modifier nonReentrant() { _beforeNonReentrant(); _; _afterNonReentrant(); } /** * @dev Tries to get the system lock */ function _beforeNonReentrant() private { IGlobalLock(globalLock).lock(); } /** * @dev Releases the system lock */ function _afterNonReentrant() private { IGlobalLock(globalLock).freeLock(); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; /** * @title ConfidenceChecker * @dev Base utility contract for storing confidence levels fractions for prices */ contract ConfidenceChecker { // ***** Immutables ***** uint public immutable MAX_ALLOWED_CONFIDENCE_FRACTION; // ***** Storage ***** mapping(uint => uint32) public maxConfidenceFractionForPair; // FRACTION_SCALE (5) // ***** Events ***** event MaxConfidenceForPairSet( uint indexed pairId, uint maxConfidenceFraction ); // ***** Constructor ***** constructor(uint _maxAllowedConfidenceFraction) { MAX_ALLOWED_CONFIDENCE_FRACTION = _maxAllowedConfidenceFraction; } // ***** Internal Functions ***** function setMaxConfidenceForPairInternal( uint _pairId, uint32 _maxConfidenceFractionForPair ) internal { require( _maxConfidenceFractionForPair <= MAX_ALLOWED_CONFIDENCE_FRACTION, "CONFIDENCE_FRACTION_TOO_HIGH" ); maxConfidenceFractionForPair[_pairId] = _maxConfidenceFractionForPair; emit MaxConfidenceForPairSet(_pairId, _maxConfidenceFractionForPair); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; import "../Common/CommonScales.sol"; /** * @title PriceAdjustmentBase * @dev Allows for adjustment of prices by using a simple spread mechanism */ contract PriceAdjustmentBase is CommonScales { // ***** Immutables ***** uint public immutable MAX_ALLOWED_SPREAD_FRACTION; // FRACTION_SCALE (5) // ***** Storage ***** mapping(uint => uint32) public spreadFractionForPair; // FRACTION_SCALE (5) // ***** Events ***** event SpreadFractionForPairSet(uint indexed pairId, uint slippage); // ***** Constructor ***** constructor(uint _maxAllowedSpreadReduction) { MAX_ALLOWED_SPREAD_FRACTION = _maxAllowedSpreadReduction; } // ***** Internal Functions ***** function setSpreadFractionForPairInternal( uint _pairId, uint32 _spreadF ) internal { require(_spreadF <= MAX_ALLOWED_SPREAD_FRACTION, "SPREAD_TOO_HIGH"); spreadFractionForPair[_pairId] = _spreadF; emit SpreadFractionForPairSet(_pairId, _spreadF); } function calculatePostSpreadPrice( uint pairId, uint64 basePrice, uint32 spreadReductionF, bool increase ) internal view returns (uint64) { require(spreadReductionF <= FRACTION_SCALE, "SPREAD_REDUCTION_TOO_HIGH"); uint64 spreadPart = uint64( (spreadFractionForPair[pairId] * uint256(basePrice)) / FRACTION_SCALE ); uint64 safeSpreadPart = spreadPart - uint64(((spreadPart * spreadReductionF) / FRACTION_SCALE)); return increase ? basePrice + safeSpreadPart : basePrice - safeSpreadPart; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.24; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; /** * @title TriggersPermissionBase * @dev Allows for a basic whitelisting mechanism */ contract TriggersPermissionBase { using EnumerableSet for EnumerableSet.AddressSet; // ***** Storage ***** EnumerableSet.AddressSet private triggerPermissionSet; // ***** Modifiers ***** modifier onlyAllowedTriggerAccount() { require(isAllowedToTrigger(msg.sender), "NOT_ALLOWED_TO_TRIGGER"); _; } // ***** Events ***** event TriggerAccountAllowed(address indexed account); event TriggerAccountDisallowed(address indexed account); // ***** View ***** function isAllowedToTrigger(address account) public view returns (bool) { return triggerPermissionSet.contains(account); } function getAllTriggerPermissionedAccounts() public view returns (address[] memory) { return triggerPermissionSet.values(); } // ***** Internal Functions ***** function allowTriggerAccountInternal(address account) internal { require(!isAllowedToTrigger(account), "ACCOUNT_ALREADY_ALLOWED"); triggerPermissionSet.add(account); emit TriggerAccountAllowed(account); } function disallowTriggerAccountInternal(address account) internal { require(isAllowedToTrigger(account), "ACCOUNT_NOT_ALLOWED"); triggerPermissionSet.remove(account); emit TriggerAccountDisallowed(account); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ITradingFloorV1","name":"_tradingFloor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"address","name":"value","type":"address"}],"name":"AddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"triggerer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"positionId","type":"bytes32"},{"indexed":true,"internalType":"enum TradingEnumsV1.PositionPhase","name":"phase","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"basePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceTimestamp","type":"uint256"}],"name":"ClosePositionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"done","type":"bool"}],"name":"DoneToggled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"triggerer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"positionId","type":"bytes32"},{"indexed":true,"internalType":"uint16","name":"pairId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"basePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceTimestamp","type":"uint256"}],"name":"LiquidationExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"triggerer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"positionId","type":"bytes32"},{"indexed":true,"internalType":"uint16","name":"pairId","type":"uint16"}],"name":"MarketCloseTimeoutTriggered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"triggerer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"positionId","type":"bytes32"},{"indexed":true,"internalType":"uint16","name":"pairId","type":"uint16"}],"name":"MarketOpenTimeoutTriggered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pairId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxConfidenceFraction","type":"uint256"}],"name":"MaxConfidenceForPairSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPendingAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"NewPendingAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"NumberUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"triggerer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"positionId","type":"bytes32"},{"indexed":true,"internalType":"enum TradingEnumsV1.PositionPhase","name":"phase","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"basePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceTimestamp","type":"uint256"}],"name":"OpenPositionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PausedToggled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"triggerer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"positionId","type":"bytes32"},{"indexed":true,"internalType":"enum OrderBookStructsV1.UpdatePositionFieldOrderType","name":"orderType","type":"uint8"},{"indexed":false,"internalType":"uint64","name":"fieldValueA","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"fieldValueB","type":"uint64"}],"name":"PositionUpdateTimeoutTriggered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"triggerer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"positionId","type":"bytes32"},{"indexed":true,"internalType":"uint16","name":"pairId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"basePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceTimestamp","type":"uint256"}],"name":"SlExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pairId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"slippage","type":"uint256"}],"name":"SpreadFractionForPairSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"triggerer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"positionId","type":"bytes32"},{"indexed":true,"internalType":"uint16","name":"pairId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"basePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceTimestamp","type":"uint256"}],"name":"TpExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"TriggerAccountAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"TriggerAccountDisallowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"triggerer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"positionId","type":"bytes32"},{"indexed":true,"internalType":"enum OrderBookStructsV1.UpdatePositionFieldOrderType","name":"orderType","type":"uint8"},{"indexed":false,"internalType":"enum TradingEnumsV1.PositionField","name":"positionField","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"fieldValue","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"triggerPrice","type":"uint64"}],"name":"UpdatePositionSingleFieldExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"triggerer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"positionId","type":"bytes32"},{"indexed":true,"internalType":"enum OrderBookStructsV1.UpdatePositionFieldOrderType","name":"orderType","type":"uint8"},{"indexed":false,"internalType":"enum TradingEnumsV1.PositionField","name":"positionField","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"fieldValue","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"triggerPrice","type":"uint64"},{"indexed":false,"internalType":"string","name":"rejectionReason","type":"string"},{"indexed":false,"internalType":"uint256","name":"rejectionValue","type":"uint256"}],"name":"UpdatePositionSingleFieldRejected","type":"event"},{"inputs":[],"name":"ACCURACY_IMPROVEMENT_SCALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FRACTION_SCALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LEVERAGE_SCALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_ALLOWED_CONFIDENCE_FRACTION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_ALLOWED_SPREAD_FRACTION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"_setPendingAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"allowTriggerAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"disallowTriggerAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllTriggerPermissionedAccounts","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pairId","type":"uint256"},{"internalType":"bytes[]","name":"pricePayload","type":"bytes[]"}],"name":"getValidatedPrice","outputs":[{"components":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint64","name":"price","type":"uint64"},{"internalType":"uint64","name":"confidence","type":"uint64"}],"internalType":"struct IPriceValidatorV1.ValidatedPrice","name":"","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isAllowedToTrigger","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isDone","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketOrderCancelFeeFraction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketOrderTightTimeRange","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketOrdersTimeout","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"maxConfidenceFractionForPair","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTriggerPeriodForMarketOrders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTriggersPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTriggerPeriodForLimitOrders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTriggerPeriodForMarketOrders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openPositionCancellationFeeFraction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"orderBook","outputs":[{"internalType":"contract IOrderBookV1","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceValidator","outputs":[{"internalType":"contract IPriceValidatorV1","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_marketOrderCancelFeeFraction","type":"uint256"}],"name":"setMarketOrderCancelFeeFraction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_marketOrderTightTimeRange","type":"uint256"}],"name":"setMarketOrderTightTimeRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_marketOrdersTimeout","type":"uint256"}],"name":"setMarketOrdersTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pairId","type":"uint256"},{"internalType":"uint32","name":"maxConfidenceFraction","type":"uint32"}],"name":"setMaxConfidenceForPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxTriggerPeriodForMarketOrders","type":"uint256"}],"name":"setMaxTriggerPeriodForMarketOrders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxTriggersPerBlock","type":"uint256"}],"name":"setMaxTriggersPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minTriggerPeriodForLimitOrders","type":"uint256"}],"name":"setMinTriggerPeriodForLimitOrders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minTriggerPeriodForMarketOrders","type":"uint256"}],"name":"setMinTriggerPeriodForMarketOrders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_openPositionCancellationFeeFraction","type":"uint256"}],"name":"setOpenPositionCancellationFeeFraction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_priceValidator","type":"address"}],"name":"setPriceValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pairId","type":"uint256"},{"internalType":"uint32","name":"spreadFraction","type":"uint32"}],"name":"setSpreadFractionForPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_triggerPriceFreshnessTimeRange","type":"uint256"}],"name":"setTriggerPriceFreshnessTimeRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spreadFractionForPair","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleDone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tradingFloor","outputs":[{"internalType":"contract ITradingFloorV1","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"triggerPriceFreshnessTimeRange","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"},{"internalType":"bytes[]","name":"pricePayload","type":"bytes[]"}],"name":"trigger_closeTrade_LIQ","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"},{"internalType":"bytes[]","name":"pricePayload","type":"bytes[]"}],"name":"trigger_closeTrade_SL","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"},{"internalType":"bytes[]","name":"pricePayload","type":"bytes[]"}],"name":"trigger_closeTrade_TP","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"},{"internalType":"bytes[]","name":"pricePayload","type":"bytes[]"}],"name":"trigger_closeTrade_market","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"},{"internalType":"bytes[]","name":"pricePayload","type":"bytes[]"}],"name":"trigger_openTrade_limit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"},{"internalType":"bytes[]","name":"pricePayload","type":"bytes[]"}],"name":"trigger_openTrade_market","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"}],"name":"trigger_timeout_marketClose","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"}],"name":"trigger_timeout_marketOpen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"}],"name":"trigger_timeout_updatePosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"},{"internalType":"bytes[]","name":"pricePayload","type":"bytes[]"}],"name":"trigger_update_SL","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"},{"internalType":"bytes[]","name":"pricePayload","type":"bytes[]"}],"name":"trigger_update_TP","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_positionId","type":"bytes32"},{"internalType":"bytes[]","name":"pricePayload","type":"bytes[]"}],"name":"trigger_update_TP_and_SL","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"triggersPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101206040526003600755603c600855603c600955603c600a5560b4600b55610708600c556103e8620186a0600162000039919062000291565b620000459190620002bd565b600d556103e86200005b620186a0600262000291565b620000679190620002bd565b600e556003600f553480156200007c57600080fd5b5060405162004ee838038062004ee88339810160408190526200009f91620002f9565b806001600160a01b0316637b1039996040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001049190620002f9565b606462000116620186a0600162000291565b620001229190620002bd565b606462000134620186a0600a62000291565b620001409190620002bd565b600080546001600160a01b0319163317905560805260a0526001600160a01b0390811660c0528116620001a85760405162461bcd60e51b815260206004820152600c60248201526b57524f4e475f504152414d5360a01b604482015260640160405180910390fd5b6001600160a01b03811660e081905260408051637b10399960e01b81529051637b103999916004808201926020929091908290030181865afa158015620001f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002199190620002f9565b6001600160a01b031663776af5ba6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000257573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200027d9190620002f9565b6001600160a01b0316610100525062000320565b8082028115828204841417620002b757634e487b7160e01b600052601160045260246000fd5b92915050565b600082620002db57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0381168114620002f657600080fd5b50565b6000602082840312156200030c57600080fd5b81516200031981620002e0565b9392505050565b60805160a05160c05160e05161010051614ab8620004306000396000818161076001528181610fc201528181611bb7015281816127100152612dd801526000818161039801528181610b3401528181610cd301528181611198015281816112f00152818161141b015281816115c901528181611817015281816118b1015281816119e101528181611ca201528181611e1001528181611eaa01528181611fd701528181612158015281816123080152818161242d01528181612508015281816127fb01528181612b4701528181612c9e01528181612ecd015261397d015260008181613339015261366101526000818161051501526136bc01526000818161098d0152613c460152614ab86000f3fe6080604052600436106103815760003560e01c8063776af5ba116101d1578063ad1f2b5611610102578063c4ae3168116100a0578063e9c714f21161006f578063e9c714f214610a37578063f851a44014610a4c578063fae5a83f14610a6c578063fd057e9414610a8c57600080fd5b8063c4ae3168146109cf578063d99dc0c1146109e4578063e231377014610a04578063e8051b0114610a2457600080fd5b8063b71f3cfe116100dc578063b71f3cfe14610943578063b81bfa051461095b578063b88750a91461097b578063bfc084d9146109af57600080fd5b8063ad1f2b56146108f4578063b187bd2614610909578063b71d1a0c1461092357600080fd5b80639abf17821161016f578063a5b6020811610149578063a5b602081461088f578063a5e02c8d146108a5578063a9f7c521146108c5578063aaf5eb68146108d857600080fd5b80639abf17821461081c5780639f918f451461083c578063a1d627a11461086f57600080fd5b806380193b26116101ab57806380193b26146107ae57806381405205146107c557806386c7f19a146107db5780638f062227146107fd57600080fd5b8063776af5ba1461074e5780637f31c2db146107825780637f588b911461079857600080fd5b8063392503e0116102b65780634cdb06a5116102545780636c1bb5ca116102235780636c1bb5ca146106e8578063718ddc14146107085780637670d9481461071b578063771ad70d1461073b57600080fd5b80634cdb06a51461065a5780634d3691511461067a5780635d2cdfea1461068d5780636447dc8b146106d557600080fd5b8063410c0b7c11610290578063410c0b7c146105fb57806345b6171314610611578063490580e3146106275780634bdf19731461064757600080fd5b8063392503e0146105bd5780633b321666146105d35780633be3d626146105e657600080fd5b806326b4120a1161032357806333a01d32116102fd57806333a01d321461050357806336930d0b1461053757806336b669f714610557578063382672571461059d57600080fd5b806326b4120a146104935780632f86d7c2146104b357806333511e5e146104d357600080fd5b8063221407af1161035f578063221407af1461042857806322ede93c1461043d57806325577e9f14610453578063267822471461047357600080fd5b80630d3b0b761461038657806310b4cc13146103d757806320cb5976146103fb575b600080fd5b34801561039257600080fd5b506103ba7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156103e357600080fd5b506103ed600d5481565b6040519081526020016103ce565b34801561040757600080fd5b506103ed610416366004614157565b60106020526000908152604090205481565b61043b6104363660046141bb565b610aac565b005b34801561044957600080fd5b506103ed600e5481565b34801561045f57600080fd5b5061043b61046e366004614218565b610db3565b34801561047f57600080fd5b506001546103ba906001600160a01b031681565b34801561049f57600080fd5b5061043b6104ae366004614157565b610deb565b3480156104bf57600080fd5b5061043b6104ce366004614157565b610e82565b3480156104df57600080fd5b506104f36104ee366004614248565b610f1e565b60405190151581526020016103ce565b34801561050f57600080fd5b506103ed7f000000000000000000000000000000000000000000000000000000000000000081565b34801561054357600080fd5b5061043b610552366004614157565b610f31565b61056a6105653660046141bb565b6110e8565b60408051825181526020808401516001600160401b039081169183019190915292820151909216908201526060016103ce565b3480156105a957600080fd5b5061043b6105b8366004614157565b611119565b3480156105c957600080fd5b506103ed600c5481565b61043b6105e13660046141bb565b611399565b3480156105f257600080fd5b5061043b6116a7565b34801561060757600080fd5b506103ed600a5481565b34801561061d57600080fd5b506103ed60075481565b34801561063357600080fd5b5061043b610642366004614157565b611733565b61043b6106553660046141bb565b611786565b34801561066657600080fd5b5061043b610675366004614157565b611abd565b61043b6106883660046141bb565b611b26565b34801561069957600080fd5b506106c06106a8366004614157565b60056020526000908152604090205463ffffffff1681565b60405163ffffffff90911681526020016103ce565b61043b6106e33660046141bb565b611d7f565b3480156106f457600080fd5b5061043b610703366004614218565b6120a2565b61043b6107163660046141bb565b6120d6565b34801561072757600080fd5b5061043b610736366004614157565b61233f565b61043b6107493660046141bb565b61239c565b34801561075a57600080fd5b506103ba7f000000000000000000000000000000000000000000000000000000000000000081565b34801561078e57600080fd5b506103ed60085481565b3480156107a457600080fd5b506103ed60095481565b3480156107ba57600080fd5b506103ed620186a081565b3480156107d157600080fd5b506103ed600f5481565b3480156107e757600080fd5b506107f06125de565b6040516103ce9190614271565b34801561080957600080fd5b506011546104f390610100900460ff1681565b34801561082857600080fd5b5061043b610837366004614157565b6125ef565b34801561084857600080fd5b506106c0610857366004614157565b60046020526000908152604090205463ffffffff1681565b34801561087b57600080fd5b506006546103ba906001600160a01b031681565b34801561089b57600080fd5b506103ed600b5481565b3480156108b157600080fd5b5061043b6108c0366004614248565b61264c565b61043b6108d33660046141bb565b61267f565b3480156108e457600080fd5b506103ed670de0b6b3a764000081565b34801561090057600080fd5b506103ed606481565b34801561091557600080fd5b506011546104f39060ff1681565b34801561092f57600080fd5b5061043b61093e366004614248565b6128cb565b34801561094f57600080fd5b506103ed633b9aca0081565b34801561096757600080fd5b5061043b610976366004614157565b612973565b34801561098757600080fd5b506103ed7f000000000000000000000000000000000000000000000000000000000000000081565b3480156109bb57600080fd5b5061043b6109ca366004614157565b6129c6565b3480156109db57600080fd5b5061043b612a23565b3480156109f057600080fd5b5061043b6109ff366004614248565b612a95565b348015610a1057600080fd5b5061043b610a1f366004614157565b612ac8565b61043b610a323660046141bb565b612d47565b348015610a4357600080fd5b5061043b61303e565b348015610a5857600080fd5b506000546103ba906001600160a01b031681565b348015610a7857600080fd5b5061043b610a87366004614248565b61315c565b348015610a9857600080fd5b5061043b610aa7366004614157565b61329b565b601154610100900460ff1615610add5760405162461bcd60e51b8152600401610ad4906142b2565b60405180910390fd5b60115460ff1615610b005760405162461bcd60e51b8152600401610ad4906142d0565b610b0933610f1e565b610b255760405162461bcd60e51b8152600401610ad4906142f0565b610b2d613337565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395be5050876040518263ffffffff1660e01b8152600401610b8091815260200190565b60a060405180830381865afa158015610b9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc1919061434c565b505092506001600160401b03169250925060008211610c1c5760405162461bcd60e51b81526020600482015260176024820152762727afa822a72224a723afa6a0a925a2aa2fa7a92222a960491b6044820152606401610ad4565b6004836005811115610c3057610c306143c4565b14610c705760405162461bcd60e51b815260206004820152601060248201526f1393d517d0d313d4d157d3505492d15560821b6044820152606401610ad4565b6000610c828261ffff163488886133ac565b9050610c928382600001516134bb565b602081015180610ca06135e7565b602083015160405163651d1d4160e11b8152600481018b90526001600160401b03918216602482015290821660448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ca3a3a8290606401600060405180830381600087803b158015610d1f57600080fd5b505af1158015610d33573d6000803e3d6000fd5b50505050856005811115610d4957610d496143c4565b6020848101518551604080516001600160401b038781168252909316938301939093528183015290518b9133917f5b5ec0827d50049e9f15c1d5c28dc87d620987ef82a18f0b98afac1c76076d3d9181900360600190a4505050505050610dae61365f565b505050565b6000546001600160a01b03163314610ddd5760405162461bcd60e51b8152600401610ad4906143da565b610de782826136ba565b5050565b6000546001600160a01b03163314610e155760405162461bcd60e51b8152600401610ad4906143da565b600b8190556040517f6d61726b65744f72646572546967687454696d6552616e67650000000000000081526019015b604051908190038120828252907f8cf3e35f6221b16e1670a3413180c9484bf5aa71787905909fa82a6a2662e9ab906020015b60405180910390a250565b6000546001600160a01b03163314610eac5760405162461bcd60e51b8152600401610ad4906143da565b6008548110610eeb5760405162461bcd60e51b815260206004820152600b60248201526a57524f4e475f56414c554560a81b6044820152606401610ad4565b60078190556040517f6d696e54726967676572506572696f64466f724d61726b65744f7264657273008152601f01610e44565b6000610f2b600283613781565b92915050565b601154610100900460ff1615610f595760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff1615610f7c5760405162461bcd60e51b8152600401610ad4906142d0565b610f8533610f1e565b610fa15760405162461bcd60e51b8152600401610ad4906142f0565b610fa9613337565b60405163c608b6c160e01b8152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c608b6c19060240160a0604051808303816000875af1158015611013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110379190614438565b9050600a5481604001516001600160401b031661105491906144e8565b4210156110735760405162461bcd60e51b8152600401610ad4906144fb565b80602001516003811115611089576110896143c4565b60608201516080830151604080516001600160401b039384168152929091166020830152849133917f7b5b2e57aed6ee99244bd22f2b43e33e9fcbf0d77a9f425d59ee2d74e1c3795d910160405180910390a4506110e561365f565b50565b6040805160608101825260008082526020820181905291810191909152611111843485856133ac565b949350505050565b601154610100900460ff16156111415760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156111645760405162461bcd60e51b8152600401610ad4906142d0565b61116d33610f1e565b6111895760405162461bcd60e51b8152600401610ad4906142f0565b611191613337565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395be5050856040518263ffffffff1660e01b81526004016111e491815260200190565b60a060405180830381865afa158015611201573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611225919061434c565b505092506001600160401b031692509250600082116112565760405162461bcd60e51b8152600401610ad490614521565b600483600581111561126a5761126a6143c4565b146112aa5760405162461bcd60e51b815260206004820152601060248201526f1393d517d0d313d4d157d3505492d15560821b6044820152606401610ad4565b600a546112b790836144e8565b4210156112d65760405162461bcd60e51b8152600401610ad4906144fb565b600d54604051634ebe5c3360e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691634ebe5c33916113299188916001919060040161454b565b600060405180830381600087803b15801561134357600080fd5b505af1158015611357573d6000803e3d6000fd5b505060405161ffff8416925086915033907f89a3ecf5024675f1d0abc6dc42608fc41216f103c12c2c84f8ca3938bd055f0390600090a45050506110e561365f565b601154610100900460ff16156113c15760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156113e45760405162461bcd60e51b8152600401610ad4906142d0565b6113ed33610f1e565b6114095760405162461bcd60e51b8152600401610ad4906142f0565b611411613337565b60008060008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395be5050896040518263ffffffff1660e01b815260040161146791815260200190565b60a060405180830381865afa158015611484573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a8919061434c565b9450945094506001600160401b031694509450600084116115045760405162461bcd60e51b81526020600482015260166024820152752727afa822a72224a723afa624a6a4aa2fa7a92222a960511b6044820152606401610ad4565b6002856005811115611518576115186143c4565b146115565760405162461bcd60e51b815260206004820152600e60248201526d1393d517d3d4115397d31253525560921b6044820152606401610ad4565b60006115688461ffff16348a8a6133ac565b90506115788582600001516137a6565b6020810151600061158f61ffff8716838688613870565b90506115996135e7565b600e54604051631ea9af6b60e01b8152600481018d90526001600160401b038316602482015260448101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631ea9af6b906064015b600060405180830381600087803b15801561161657600080fd5b505af115801561162a573d6000803e3d6000fd5b50505050876005811115611640576116406143c4565b6020848101518551604080516001600160401b038781168252909316938301939093528183015290518d9133917f60fab6e183a7c350210c0b457db01423b47aa3e72f5b735b8dbb3ecd3e8077439181900360600190a45050505050505050610dae61365f565b6000546001600160a01b031633146116d15760405162461bcd60e51b8152600401610ad4906143da565b6011805460ff610100808304821615810261ff001990931692909217928390556040517f8e47bd62470c6cba4d30c023548622607c9c84402a5655f2569b7934c36a9e4f936117299390049091161515815260200190565b60405180910390a1565b6000546001600160a01b0316331461175d5760405162461bcd60e51b8152600401610ad4906143da565b600f819055604051726d61785472696767657273506572426c6f636b60681b8152601301610e44565b601154610100900460ff16156117ae5760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156117d15760405162461bcd60e51b8152600401610ad4906142d0565b6117da33610f1e565b6117f65760405162461bcd60e51b8152600401610ad4906142f0565b6117fe613337565b60405163095be50560e41b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906395be50509060240160a060405180830381865afa158015611866573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188a919061434c565b50506040516366307a4f60e01b815260048101889052909350600092506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691506366307a4f90602401608060405180830381865afa1580156118f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191d9190614573565b905060008261ffff16116119435760405162461bcd60e51b8152600401610ad490614521565b600081606001516001600160401b0316116119885760405162461bcd60e51b81526020600482015260056024820152641393d7d4d360da1b6044820152606401610ad4565b60208101516001600160401b031660006119a861ffff85163488886133ac565b90506119b88282600001516137a6565b60208101516119c56135e7565b6020820151604051632029fcf560e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916380a7f3d491611a1c918c916002919087906004016145fd565b600060405180830381600087803b158015611a3657600080fd5b505af1158015611a4a573d6000803e3d6000fd5b5050506020808401518451604080516001600160401b038088168252909316938301939093529181019190915261ffff87169150899033907fb03dbc9368faf0f8588dc8429c40a26ef9a637488f1ea5521a2ba2bfb5ff2016906060015b60405180910390a45050505050610dae61365f565b6000546001600160a01b03163314611ae75760405162461bcd60e51b8152600401610ad4906143da565b600e8190556040517f6f70656e506f736974696f6e43616e63656c6c6174696f6e466565467261637481526234b7b760e91b6020820152602301610e44565b601154610100900460ff1615611b4e5760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff1615611b715760405162461bcd60e51b8152600401610ad4906142d0565b611b7a33610f1e565b611b965760405162461bcd60e51b8152600401610ad4906142f0565b611b9e613337565b60405163c608b6c160e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c608b6c19060240160a0604051808303816000875af1158015611c08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2c9190614438565b9050600281602001516003811115611c4657611c466143c4565b14611c895760405162461bcd60e51b815260206004820152601360248201527215541110551157d3d491115497d393d517d4d3606a1b6044820152606401610ad4565b60405163095be50560e41b8152600481018590526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906395be50509060240160a060405180830381865afa158015611cf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d15919061434c565b5050925050506000611d2d8261ffff163487876133ac565b9050611d4a83604001516001600160401b031682600001516134bb565b611d526135e7565b600081602001519050611d72338886602001516002886060015186613963565b5050505050610dae61365f565b601154610100900460ff1615611da75760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff1615611dca5760405162461bcd60e51b8152600401610ad4906142d0565b611dd333610f1e565b611def5760405162461bcd60e51b8152600401610ad4906142f0565b611df7613337565b60405163095be50560e41b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906395be50509060240160a060405180830381865afa158015611e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e83919061434c565b50506040516366307a4f60e01b815260048101889052909350600092506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691506366307a4f90602401608060405180830381865afa158015611ef2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f169190614573565b905060008261ffff1611611f3c5760405162461bcd60e51b8152600401610ad490614521565b600081604001516001600160401b031611611f815760405162461bcd60e51b815260206004820152600560248201526404e4f5f54560dc1b6044820152606401610ad4565b80516001600160401b03166000611f9e61ffff85163488886133ac565b9050611fae8282600001516137a6565b6020810151611fbb6135e7565b6020820151604051632029fcf560e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916380a7f3d491612012918c916001919087906004016145fd565b600060405180830381600087803b15801561202c57600080fd5b505af1158015612040573d6000803e3d6000fd5b5050506020808401518451604080516001600160401b038088168252909316938301939093529181019190915261ffff87169150899033907fbe700227f721a08f3b755aa3348a63564c2c07890aba73de46372f7bffcaa2e290606001611aa8565b6000546001600160a01b031633146120cc5760405162461bcd60e51b8152600401610ad4906143da565b610de78282613c44565b601154610100900460ff16156120fe5760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156121215760405162461bcd60e51b8152600401610ad4906142d0565b61212a33610f1e565b6121465760405162461bcd60e51b8152600401610ad4906142f0565b61214e613337565b60008060008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395be5050896040518263ffffffff1660e01b81526004016121a491815260200190565b60a060405180830381865afa1580156121c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e5919061434c565b9450945094506001600160401b031694509450600084116122425760405162461bcd60e51b81526020600482015260176024820152762727afa822a72224a723afa6a0a925a2aa2fa7a92222a960491b6044820152606401610ad4565b6001856005811115612256576122566143c4565b146122955760405162461bcd60e51b815260206004820152600f60248201526e1393d517d3d4115397d3505492d155608a1b6044820152606401610ad4565b60006122a78461ffff16348a8a6133ac565b90506122b78582600001516134bb565b602081015160006122ce61ffff8716838688613870565b90506122d86135e7565b600e546040516303ad224560e61b8152600481018d90526001600160401b038316602482015260448101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063eb489140906064016115fc565b6000546001600160a01b031633146123695760405162461bcd60e51b8152600401610ad4906143da565b600c8190556040517f74726967676572507269636546726573686e65737354696d6552616e676500008152601e01610e44565b601154610100900460ff16156123c45760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156123e75760405162461bcd60e51b8152600401610ad4906142d0565b6123f033610f1e565b61240c5760405162461bcd60e51b8152600401610ad4906142f0565b612414613337565b60405163095be50560e41b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906395be50509060240160a060405180830381865afa15801561247c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a0919061434c565b50509250505060008161ffff16116124ca5760405162461bcd60e51b8152600401610ad490614521565b60006124dc8261ffff163486866133ac565b60208101519091506124ec6135e7565b6020820151604051632029fcf560e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916380a7f3d491612543918a916003919087906004016145fd565b600060405180830381600087803b15801561255d57600080fd5b505af1158015612571573d6000803e3d6000fd5b505050506020828101518351604080516001600160401b0386811682529093169383019390935281830152905161ffff851691889133917f086bdd0cdd4ae322dd6112d05bdf96c020e6b90cc84ee2d39941bd716e18fb92919081900360600190a4505050610dae61365f565b60606125ea6002613d11565b905090565b6000546001600160a01b031633146126195760405162461bcd60e51b8152600401610ad4906143da565b600d8190556040517f6d61726b65744f7264657243616e63656c4665654672616374696f6e000000008152601c01610e44565b6000546001600160a01b031633146126765760405162461bcd60e51b8152600401610ad4906143da565b6110e581613d1e565b601154610100900460ff16156126a75760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156126ca5760405162461bcd60e51b8152600401610ad4906142d0565b6126d333610f1e565b6126ef5760405162461bcd60e51b8152600401610ad4906142f0565b6126f7613337565b60405163c608b6c160e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c608b6c19060240160a0604051808303816000875af1158015612761573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127859190614438565b905060018160200151600381111561279f5761279f6143c4565b146127e25760405162461bcd60e51b815260206004820152601360248201527205550444154455f4f524445525f4e4f545f545606c1b6044820152606401610ad4565b60405163095be50560e41b8152600481018590526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906395be50509060240160a060405180830381865afa15801561284a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286e919061434c565b50509250505060006128868261ffff163487876133ac565b90506128a383604001516001600160401b031682600001516134bb565b6128ab6135e7565b600081602001519050611d72338886602001516001886060015186613963565b6000546001600160a01b031633146129115760405162461bcd60e51b81526020600482015260096024820152682737ba1020b236b4b760b91b6044820152606401610ad4565b600180546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a991015b60405180910390a15050565b6000546001600160a01b0316331461299d5760405162461bcd60e51b8152600401610ad4906143da565b600a819055604051721b585c9ad95d13dc99195c9cd51a5b595bdd5d606a1b8152601301610e44565b6000546001600160a01b031633146129f05760405162461bcd60e51b8152600401610ad4906143da565b60098190556040517f6d696e54726967676572506572696f64466f724c696d69744f726465727300008152601e01610e44565b6000546001600160a01b03163314612a4d5760405162461bcd60e51b8152600401610ad4906143da565b6011805460ff8082161560ff1990921682179092556040519116151581527fda88b5dfaac55549d4ddddd43a09d4b911233df354952ebc9ac2041aa185343690602001611729565b6000546001600160a01b03163314612abf5760405162461bcd60e51b8152600401610ad4906143da565b6110e581613dac565b601154610100900460ff1615612af05760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff1615612b135760405162461bcd60e51b8152600401610ad4906142d0565b612b1c33610f1e565b612b385760405162461bcd60e51b8152600401610ad4906142f0565b612b40613337565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166395be5050856040518263ffffffff1660e01b8152600401612b9391815260200190565b60a060405180830381865afa158015612bb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd4919061434c565b505092506001600160401b03169250925060008211612c055760405162461bcd60e51b8152600401610ad490614521565b6001836005811115612c1957612c196143c4565b14612c585760405162461bcd60e51b815260206004820152600f60248201526e1393d517d3d4115397d3505492d155608a1b6044820152606401610ad4565b600a54612c6590836144e8565b421015612c845760405162461bcd60e51b8152600401610ad4906144fb565b600d54604051636e01af8d60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691636e01af8d91612cd791889160019190600401614649565b600060405180830381600087803b158015612cf157600080fd5b505af1158015612d05573d6000803e3d6000fd5b505060405161ffff8416925086915033907f5079795ec65f793d5a0ed74d8f8e1562b7795934b40612bf55cf0e5d55a3447990600090a45050506110e561365f565b601154610100900460ff1615612d6f5760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff1615612d925760405162461bcd60e51b8152600401610ad4906142d0565b612d9b33610f1e565b612db75760405162461bcd60e51b8152600401610ad4906142f0565b612dbf613337565b60405163c608b6c160e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c608b6c19060240160a0604051808303816000875af1158015612e29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4d9190614438565b9050600381602001516003811115612e6757612e676143c4565b14612eb45760405162461bcd60e51b815260206004820152601a60248201527f5550444154455f4f524445525f4e4f545f54505f414e445f534c0000000000006044820152606401610ad4565b60405163095be50560e41b8152600481018590526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906395be50509060240160a060405180830381865afa158015612f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f40919061434c565b5050925050506000612f588261ffff163487876133ac565b9050612f7583604001516001600160401b031682600001516134bb565b612f7d6135e7565b600081602001519050612f9d338886602001516001886060015186613963565b612fdc5760405162461bcd60e51b815260206004820152601060248201526f4641494c45445f54505f55504441544560801b6044820152606401610ad4565b612ff3338886602001516002886080015186613963565b6130325760405162461bcd60e51b815260206004820152601060248201526f4641494c45445f534c5f55504441544560801b6044820152606401610ad4565b50505050610dae61365f565b6001546001600160a01b03163314801561306257506001546001600160a01b031615155b6130ae5760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420746865204558495354494e472070656e64696e672061646d696e00006044820152606401610ad4565b60008054600180546001600160a01b038082166001600160a01b031980861682179096559490911690915560408051919092168082526020820184905292917ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc910160405180910390a1600154604080516001600160a01b03808516825290921660208301527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101612967565b6000546001600160a01b031633146131865760405162461bcd60e51b8152600401610ad4906143da565b806001600160a01b0316634535dc4c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e89190614659565b6132265760405162461bcd60e51b815260206004820152600f60248201526e10a83934b1b2ab30b634b230ba37b960891b6044820152606401610ad4565b600680546001600160a01b0319166001600160a01b0383161790556040516d283934b1b2ab30b634b230ba37b960911b8152600e016040519081900381206001600160a01b0383168252907f943e9d45a11aaae5d87503e3bc248665d9807856e5cf2bdb4a988bee4442278190602001610e77565b6000546001600160a01b031633146132c55760405162461bcd60e51b8152600401610ad4906143da565b60075481116133045760405162461bcd60e51b815260206004820152600b60248201526a57524f4e475f56414c554560a81b6044820152606401610ad4565b60088190556040517f6d617854726967676572506572696f64466f724d61726b65744f7264657273008152601f01610e44565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f83d08ba6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561339257600080fd5b505af11580156133a6573d6000803e3d6000fd5b50505050565b60408051606081018252600080825260208201819052918101829052906133d586868686613e45565b60008781526004602090815260408220549083015192935063ffffffff1691613407906001600160401b031683613ee0565b90508083604001516001600160401b031611156134665760405162461bcd60e51b815260206004820152601960248201527f434f4e464944454e43455f52414e47455f544f4f5f57494445000000000000006044820152606401610ad4565b82514210156134af5760405162461bcd60e51b815260206004820152601560248201527411955515549157d4149250d157d4915413d4951151605a1b6044820152606401610ad4565b50909695505050505050565b6000600754836134cb91906144e8565b90506000600854846134dd91906144e8565b90508142101561352f5760405162461bcd60e51b815260206004820152601d60248201527f4d41524b45545f4f524445525f545249474745525f544f4f5f534f4f4e0000006044820152606401610ad4565b8042111561357f5760405162461bcd60e51b815260206004820152601d60248201527f4d41524b45545f4f524445525f545249474745525f544f4f5f4c4154450000006044820152606401610ad4565b81831015801561358f5750808311155b6133a65760405162461bcd60e51b8152602060048201526024808201527f4d41524b45545f4f524445525f50524943455f4f55545f4f465f54494d455f4660448201526352414d4560e01b6064820152608401610ad4565b43600090815260106020526040902054600f5481106136415760405162461bcd60e51b81526020600482015260166024820152754d41585f54524947474552535f5045525f424c4f434b60501b6044820152606401610ad4565b61364c8160016144e8565b4360009081526010602052604090205550565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166340da020f6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561339257600080fd5b7f00000000000000000000000000000000000000000000000000000000000000008163ffffffff1611156137225760405162461bcd60e51b815260206004820152600f60248201526e0a6a0a48a8288bea89e9ebe90928e9608b1b6044820152606401610ad4565b600082815260056020908152604091829020805463ffffffff191663ffffffff8516908117909155915191825283917ffe5fd0852fab5f8ba593533cf24a4b4b235704c0e06956d0a58cc2ca0a4b6b4491015b60405180910390a25050565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b6000600954836137b691906144e8565b9050804210156138085760405162461bcd60e51b815260206004820152601c60248201527f4c494d49545f4f524445525f545249474745525f544f4f5f534f4f4e000000006044820152606401610ad4565b808210156138645760405162461bcd60e51b815260206004820152602360248201527f4c494d49545f4f524445525f50524943455f4f55545f4f465f54494d455f4652604482015262414d4560e81b6064820152608401610ad4565b610dae82600c54613efa565b6000620186a08363ffffffff1611156138cb5760405162461bcd60e51b815260206004820152601960248201527f5350524541445f524544554354494f4e5f544f4f5f48494748000000000000006044820152606401610ad4565b600085815260056020526040812054620186a0906138f9906001600160401b0388169063ffffffff16614674565b613903919061468b565b90506000620186a061391b63ffffffff8716846146ad565b6001600160401b031661392e919061468b565b61393890836146d8565b90508361394e5761394981876146d8565b613958565b61395881876146f8565b979650505050505050565b60405163c07f992160e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c07f9921906139b8908990889088908890600401614718565b600060405180830381600087803b1580156139d257600080fd5b505af19250505080156139e3575060015b613bde576139ef614728565b806308c379a003613a755750613a03614744565b80613a0e5750613a77565b856003811115613a2057613a206143c4565b87896001600160a01b03167f889460050d9a293fbe31b6ce00a37ae62020cb8c8a19cf31e9496cb13246f6e2888888876000604051613a639594939291906147cd565b60405180910390a46000915050613c3a565b505b3d808015613aa1576040519150601f19603f3d011682016040523d82523d6000602084013e613aa6565b606091505b50632eb752bf60e21b613ab88261484f565b6001600160e01b03191603613b9f576001856002811115613adb57613adb6143c4565b14613b1e5760405162461bcd60e51b815260206004820152601360248201527204341505f4552524f525f4e4f545f4f4e5f545606c1b6044820152606401610ad4565b60248101516044820151876003811115613b3a57613b3a6143c4565b898b6001600160a01b03167f889460050d9a293fbe31b6ce00a37ae62020cb8c8a19cf31e9496cb13246f6e28a8a8a886011811115613b7b57613b7b6143c4565b604051613b8b9493929190614886565b60405180910390a460009350505050613c3a565b60405162461bcd60e51b81526020600482015260146024820152732aa725a727aba72fa1aaa9aa27a6afa2a92927a960611b6044820152606401610ad4565b846003811115613bf057613bf06143c4565b86886001600160a01b03167ff0ac91a20375484f5a80315763782e4fe4b42bd038b08ba4939ff1a506974edf878787604051613c2e939291906148d5565b60405180910390a45060015b9695505050505050565b7f00000000000000000000000000000000000000000000000000000000000000008163ffffffff161115613cba5760405162461bcd60e51b815260206004820152601c60248201527f434f4e464944454e43455f4652414354494f4e5f544f4f5f48494748000000006044820152606401610ad4565b600082815260046020908152604091829020805463ffffffff191663ffffffff8516908117909155915191825283917f88e6fad616d859d6fba20e93ab2acbf0756b6bc2d90c6002000f709f510cadb09101613775565b6060600061379f83613f88565b613d2781610f1e565b613d695760405162461bcd60e51b81526020600482015260136024820152721050d0d3d5539517d393d517d0531313d5d151606a1b6044820152606401610ad4565b613d74600282613fe4565b506040516001600160a01b038216907fc985d67a353004ba149a223b2b9e5c13cca6610b11cb45b4aa029c880d8f7cb590600090a250565b613db581610f1e565b15613e025760405162461bcd60e51b815260206004820152601760248201527f4143434f554e545f414c52454144595f414c4c4f5745440000000000000000006044820152606401610ad4565b613e0d600282613ff9565b506040516001600160a01b038216907fc5944eab072face4b169928723314c5978080e99ed8f8527faedb18c06664c3590600090a250565b6040805160608101825260008082526020820181905281830152600654915163f4a6a09360e01b815290916001600160a01b03169063f4a6a093908690613e9490899088908890600401614929565b60606040518083038185885af1158015613eb2573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613ed791906149d1565b95945050505050565b6000620186a0613ef08385614674565b61379f919061468b565b6000613f068242614a43565b905080831015613f485760405162461bcd60e51b815260206004820152600d60248201526c14149250d157d513d3d7d3d311609a1b6044820152606401610ad4565b42831115610dae5760405162461bcd60e51b815260206004820152600d60248201526c50524943455f544f4f5f4e455760981b6044820152606401610ad4565b606081600001805480602002602001604051908101604052809291908181526020018280548015613fd857602002820191906000526020600020905b815481526020019060010190808311613fc4575b50505050509050919050565b600061379f836001600160a01b03841661400e565b600061379f836001600160a01b038416614108565b600081815260018301602052604081205480156140f7576000614032600183614a43565b855490915060009061404690600190614a43565b90508082146140ab57600086600001828154811061406657614066614a56565b906000526020600020015490508087600001848154811061408957614089614a56565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806140bc576140bc614a6c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610f2b565b6000915050610f2b565b5092915050565b600081815260018301602052604081205461414f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610f2b565b506000610f2b565b60006020828403121561416957600080fd5b5035919050565b60008083601f84011261418257600080fd5b5081356001600160401b0381111561419957600080fd5b6020830191508360208260051b85010111156141b457600080fd5b9250929050565b6000806000604084860312156141d057600080fd5b8335925060208401356001600160401b038111156141ed57600080fd5b6141f986828701614170565b9497909650939450505050565b63ffffffff811681146110e557600080fd5b6000806040838503121561422b57600080fd5b82359150602083013561423d81614206565b809150509250929050565b60006020828403121561425a57600080fd5b81356001600160a01b038116811461379f57600080fd5b6020808252825182820181905260009190848201906040850190845b818110156134af5783516001600160a01b03168352928401929184019160010161428d565b602080825260049082015263444f4e4560e01b604082015260600190565b60208082526006908201526514105554d15160d21b604082015260600190565b6020808252601690820152752727aa2fa0a62627aba2a22faa27afaa2924a3a3a2a960511b604082015260600190565b80516001600160401b038116811461433757600080fd5b919050565b8051801515811461433757600080fd5b600080600080600060a0868803121561436457600080fd5b85516006811061437357600080fd5b945061438160208701614320565b9350604086015161ffff8116811461439857600080fd5b92506143a66060870161433c565b915060808601516143b681614206565b809150509295509295909350565b634e487b7160e01b600052602160045260246000fd5b6020808252600a908201526927a7262cafa0a226a4a760b11b604082015260600190565b601f8201601f191681016001600160401b038111828210171561443157634e487b7160e01b600052604160045260246000fd5b6040525050565b600060a0828403121561444a57600080fd5b60405160a081018181106001600160401b038211171561447a57634e487b7160e01b600052604160045260246000fd5b6040528251815260208301516004811061449357600080fd5b60208201526144a460408401614320565b60408201526144b560608401614320565b60608201526144c660808401614320565b60808201529392505050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610f2b57610f2b6144d2565b6020808252600c908201526b15d0525517d512535153d55560a21b604082015260600190565b60208082526010908201526f2727afa9aaa1a42fa827a9a4aa24a7a760811b604082015260600190565b8381526060810160028410614562576145626143c4565b602082019390935260400152919050565b60006080828403121561458557600080fd5b604051608081018181106001600160401b03821117156145b557634e487b7160e01b600052604160045260246000fd5b6040526145c183614320565b81526145cf60208401614320565b60208201526145e060408401614320565b60408201526145f160608401614320565b60608201529392505050565b8481526080810160048510614614576146146143c4565b60208201949094526001600160401b0392831660408201529116606090910152919050565b600381106110e5576110e56143c4565b8381526060810161456284614639565b60006020828403121561466b57600080fd5b61379f8261433c565b8082028115828204841417610f2b57610f2b6144d2565b6000826146a857634e487b7160e01b600052601260045260246000fd5b500490565b6001600160401b038181168382160280821691908281146146d0576146d06144d2565b505092915050565b6001600160401b03828116828216039080821115614101576141016144d2565b6001600160401b03818116838216019080821115614101576141016144d2565b8481526080810161461485614639565b600060033d11156147415760046000803e5060005160e01c5b90565b600060443d10156147525790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561478157505050505090565b82850191508151818111156147995750505050505090565b843d87010160208285010111156147b35750505050505090565b6147c2602082860101876143fe565b509095945050505050565b6147d686614639565b858152600060206001600160401b03808816602085015280871660408501525060a0606084015284518060a085015260005b818110156148245786810183015185820160c001528201614808565b50600060c0828601015260c0601f19601f830116850101925050508260808301529695505050505050565b805160208201516001600160e01b0319808216929190600483101561487e5780818460040360031b1b83161693505b505050919050565b61488f85614639565b9384526001600160401b0392831660208501529116604083015260a0606083018190526009908301526821a0a82fa2a92927a960b91b60c0830152608082015260e00190565b606081016148e285614639565b9381526001600160401b039283166020820152911660409091015290565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000604082018583526020604060208501528185835260608501905060608660051b86010192508660005b878110156149c357868503605f190183528135368a9003601e1901811261497a57600080fd5b890184810190356001600160401b0381111561499557600080fd5b8036038213156149a457600080fd5b6149af878284614900565b965050509183019190830190600101614954565b509298975050505050505050565b6000606082840312156149e357600080fd5b604051606081018181106001600160401b0382111715614a1357634e487b7160e01b600052604160045260246000fd5b60405282518152614a2660208401614320565b6020820152614a3760408401614320565b60408201529392505050565b81810381811115610f2b57610f2b6144d2565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea26469706673582212205ea30faf884e26d1e90ed9111c8ccbd84fa172559deb1ea27cff51bc6487b13c64736f6c6343000818003300000000000000000000000037792eecfa985d0b00a51864c970e7df406aa868
Deployed Bytecode
0x6080604052600436106103815760003560e01c8063776af5ba116101d1578063ad1f2b5611610102578063c4ae3168116100a0578063e9c714f21161006f578063e9c714f214610a37578063f851a44014610a4c578063fae5a83f14610a6c578063fd057e9414610a8c57600080fd5b8063c4ae3168146109cf578063d99dc0c1146109e4578063e231377014610a04578063e8051b0114610a2457600080fd5b8063b71f3cfe116100dc578063b71f3cfe14610943578063b81bfa051461095b578063b88750a91461097b578063bfc084d9146109af57600080fd5b8063ad1f2b56146108f4578063b187bd2614610909578063b71d1a0c1461092357600080fd5b80639abf17821161016f578063a5b6020811610149578063a5b602081461088f578063a5e02c8d146108a5578063a9f7c521146108c5578063aaf5eb68146108d857600080fd5b80639abf17821461081c5780639f918f451461083c578063a1d627a11461086f57600080fd5b806380193b26116101ab57806380193b26146107ae57806381405205146107c557806386c7f19a146107db5780638f062227146107fd57600080fd5b8063776af5ba1461074e5780637f31c2db146107825780637f588b911461079857600080fd5b8063392503e0116102b65780634cdb06a5116102545780636c1bb5ca116102235780636c1bb5ca146106e8578063718ddc14146107085780637670d9481461071b578063771ad70d1461073b57600080fd5b80634cdb06a51461065a5780634d3691511461067a5780635d2cdfea1461068d5780636447dc8b146106d557600080fd5b8063410c0b7c11610290578063410c0b7c146105fb57806345b6171314610611578063490580e3146106275780634bdf19731461064757600080fd5b8063392503e0146105bd5780633b321666146105d35780633be3d626146105e657600080fd5b806326b4120a1161032357806333a01d32116102fd57806333a01d321461050357806336930d0b1461053757806336b669f714610557578063382672571461059d57600080fd5b806326b4120a146104935780632f86d7c2146104b357806333511e5e146104d357600080fd5b8063221407af1161035f578063221407af1461042857806322ede93c1461043d57806325577e9f14610453578063267822471461047357600080fd5b80630d3b0b761461038657806310b4cc13146103d757806320cb5976146103fb575b600080fd5b34801561039257600080fd5b506103ba7f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa86881565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156103e357600080fd5b506103ed600d5481565b6040519081526020016103ce565b34801561040757600080fd5b506103ed610416366004614157565b60106020526000908152604090205481565b61043b6104363660046141bb565b610aac565b005b34801561044957600080fd5b506103ed600e5481565b34801561045f57600080fd5b5061043b61046e366004614218565b610db3565b34801561047f57600080fd5b506001546103ba906001600160a01b031681565b34801561049f57600080fd5b5061043b6104ae366004614157565b610deb565b3480156104bf57600080fd5b5061043b6104ce366004614157565b610e82565b3480156104df57600080fd5b506104f36104ee366004614248565b610f1e565b60405190151581526020016103ce565b34801561050f57600080fd5b506103ed7f00000000000000000000000000000000000000000000000000000000000003e881565b34801561054357600080fd5b5061043b610552366004614157565b610f31565b61056a6105653660046141bb565b6110e8565b60408051825181526020808401516001600160401b039081169183019190915292820151909216908201526060016103ce565b3480156105a957600080fd5b5061043b6105b8366004614157565b611119565b3480156105c957600080fd5b506103ed600c5481565b61043b6105e13660046141bb565b611399565b3480156105f257600080fd5b5061043b6116a7565b34801561060757600080fd5b506103ed600a5481565b34801561061d57600080fd5b506103ed60075481565b34801561063357600080fd5b5061043b610642366004614157565b611733565b61043b6106553660046141bb565b611786565b34801561066657600080fd5b5061043b610675366004614157565b611abd565b61043b6106883660046141bb565b611b26565b34801561069957600080fd5b506106c06106a8366004614157565b60056020526000908152604090205463ffffffff1681565b60405163ffffffff90911681526020016103ce565b61043b6106e33660046141bb565b611d7f565b3480156106f457600080fd5b5061043b610703366004614218565b6120a2565b61043b6107163660046141bb565b6120d6565b34801561072757600080fd5b5061043b610736366004614157565b61233f565b61043b6107493660046141bb565b61239c565b34801561075a57600080fd5b506103ba7f00000000000000000000000008422b1ca26c4b6e28bd8635cabb03bc1dbe5d6281565b34801561078e57600080fd5b506103ed60085481565b3480156107a457600080fd5b506103ed60095481565b3480156107ba57600080fd5b506103ed620186a081565b3480156107d157600080fd5b506103ed600f5481565b3480156107e757600080fd5b506107f06125de565b6040516103ce9190614271565b34801561080957600080fd5b506011546104f390610100900460ff1681565b34801561082857600080fd5b5061043b610837366004614157565b6125ef565b34801561084857600080fd5b506106c0610857366004614157565b60046020526000908152604090205463ffffffff1681565b34801561087b57600080fd5b506006546103ba906001600160a01b031681565b34801561089b57600080fd5b506103ed600b5481565b3480156108b157600080fd5b5061043b6108c0366004614248565b61264c565b61043b6108d33660046141bb565b61267f565b3480156108e457600080fd5b506103ed670de0b6b3a764000081565b34801561090057600080fd5b506103ed606481565b34801561091557600080fd5b506011546104f39060ff1681565b34801561092f57600080fd5b5061043b61093e366004614248565b6128cb565b34801561094f57600080fd5b506103ed633b9aca0081565b34801561096757600080fd5b5061043b610976366004614157565b612973565b34801561098757600080fd5b506103ed7f000000000000000000000000000000000000000000000000000000000000271081565b3480156109bb57600080fd5b5061043b6109ca366004614157565b6129c6565b3480156109db57600080fd5b5061043b612a23565b3480156109f057600080fd5b5061043b6109ff366004614248565b612a95565b348015610a1057600080fd5b5061043b610a1f366004614157565b612ac8565b61043b610a323660046141bb565b612d47565b348015610a4357600080fd5b5061043b61303e565b348015610a5857600080fd5b506000546103ba906001600160a01b031681565b348015610a7857600080fd5b5061043b610a87366004614248565b61315c565b348015610a9857600080fd5b5061043b610aa7366004614157565b61329b565b601154610100900460ff1615610add5760405162461bcd60e51b8152600401610ad4906142b2565b60405180910390fd5b60115460ff1615610b005760405162461bcd60e51b8152600401610ad4906142d0565b610b0933610f1e565b610b255760405162461bcd60e51b8152600401610ad4906142f0565b610b2d613337565b60008060007f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b03166395be5050876040518263ffffffff1660e01b8152600401610b8091815260200190565b60a060405180830381865afa158015610b9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc1919061434c565b505092506001600160401b03169250925060008211610c1c5760405162461bcd60e51b81526020600482015260176024820152762727afa822a72224a723afa6a0a925a2aa2fa7a92222a960491b6044820152606401610ad4565b6004836005811115610c3057610c306143c4565b14610c705760405162461bcd60e51b815260206004820152601060248201526f1393d517d0d313d4d157d3505492d15560821b6044820152606401610ad4565b6000610c828261ffff163488886133ac565b9050610c928382600001516134bb565b602081015180610ca06135e7565b602083015160405163651d1d4160e11b8152600481018b90526001600160401b03918216602482015290821660448201527f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b03169063ca3a3a8290606401600060405180830381600087803b158015610d1f57600080fd5b505af1158015610d33573d6000803e3d6000fd5b50505050856005811115610d4957610d496143c4565b6020848101518551604080516001600160401b038781168252909316938301939093528183015290518b9133917f5b5ec0827d50049e9f15c1d5c28dc87d620987ef82a18f0b98afac1c76076d3d9181900360600190a4505050505050610dae61365f565b505050565b6000546001600160a01b03163314610ddd5760405162461bcd60e51b8152600401610ad4906143da565b610de782826136ba565b5050565b6000546001600160a01b03163314610e155760405162461bcd60e51b8152600401610ad4906143da565b600b8190556040517f6d61726b65744f72646572546967687454696d6552616e67650000000000000081526019015b604051908190038120828252907f8cf3e35f6221b16e1670a3413180c9484bf5aa71787905909fa82a6a2662e9ab906020015b60405180910390a250565b6000546001600160a01b03163314610eac5760405162461bcd60e51b8152600401610ad4906143da565b6008548110610eeb5760405162461bcd60e51b815260206004820152600b60248201526a57524f4e475f56414c554560a81b6044820152606401610ad4565b60078190556040517f6d696e54726967676572506572696f64466f724d61726b65744f7264657273008152601f01610e44565b6000610f2b600283613781565b92915050565b601154610100900460ff1615610f595760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff1615610f7c5760405162461bcd60e51b8152600401610ad4906142d0565b610f8533610f1e565b610fa15760405162461bcd60e51b8152600401610ad4906142f0565b610fa9613337565b60405163c608b6c160e01b8152600481018290526000907f00000000000000000000000008422b1ca26c4b6e28bd8635cabb03bc1dbe5d626001600160a01b03169063c608b6c19060240160a0604051808303816000875af1158015611013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110379190614438565b9050600a5481604001516001600160401b031661105491906144e8565b4210156110735760405162461bcd60e51b8152600401610ad4906144fb565b80602001516003811115611089576110896143c4565b60608201516080830151604080516001600160401b039384168152929091166020830152849133917f7b5b2e57aed6ee99244bd22f2b43e33e9fcbf0d77a9f425d59ee2d74e1c3795d910160405180910390a4506110e561365f565b50565b6040805160608101825260008082526020820181905291810191909152611111843485856133ac565b949350505050565b601154610100900460ff16156111415760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156111645760405162461bcd60e51b8152600401610ad4906142d0565b61116d33610f1e565b6111895760405162461bcd60e51b8152600401610ad4906142f0565b611191613337565b60008060007f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b03166395be5050856040518263ffffffff1660e01b81526004016111e491815260200190565b60a060405180830381865afa158015611201573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611225919061434c565b505092506001600160401b031692509250600082116112565760405162461bcd60e51b8152600401610ad490614521565b600483600581111561126a5761126a6143c4565b146112aa5760405162461bcd60e51b815260206004820152601060248201526f1393d517d0d313d4d157d3505492d15560821b6044820152606401610ad4565b600a546112b790836144e8565b4210156112d65760405162461bcd60e51b8152600401610ad4906144fb565b600d54604051634ebe5c3360e01b81526001600160a01b037f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8681691634ebe5c33916113299188916001919060040161454b565b600060405180830381600087803b15801561134357600080fd5b505af1158015611357573d6000803e3d6000fd5b505060405161ffff8416925086915033907f89a3ecf5024675f1d0abc6dc42608fc41216f103c12c2c84f8ca3938bd055f0390600090a45050506110e561365f565b601154610100900460ff16156113c15760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156113e45760405162461bcd60e51b8152600401610ad4906142d0565b6113ed33610f1e565b6114095760405162461bcd60e51b8152600401610ad4906142f0565b611411613337565b60008060008060007f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b03166395be5050896040518263ffffffff1660e01b815260040161146791815260200190565b60a060405180830381865afa158015611484573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a8919061434c565b9450945094506001600160401b031694509450600084116115045760405162461bcd60e51b81526020600482015260166024820152752727afa822a72224a723afa624a6a4aa2fa7a92222a960511b6044820152606401610ad4565b6002856005811115611518576115186143c4565b146115565760405162461bcd60e51b815260206004820152600e60248201526d1393d517d3d4115397d31253525560921b6044820152606401610ad4565b60006115688461ffff16348a8a6133ac565b90506115788582600001516137a6565b6020810151600061158f61ffff8716838688613870565b90506115996135e7565b600e54604051631ea9af6b60e01b8152600481018d90526001600160401b038316602482015260448101919091527f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b031690631ea9af6b906064015b600060405180830381600087803b15801561161657600080fd5b505af115801561162a573d6000803e3d6000fd5b50505050876005811115611640576116406143c4565b6020848101518551604080516001600160401b038781168252909316938301939093528183015290518d9133917f60fab6e183a7c350210c0b457db01423b47aa3e72f5b735b8dbb3ecd3e8077439181900360600190a45050505050505050610dae61365f565b6000546001600160a01b031633146116d15760405162461bcd60e51b8152600401610ad4906143da565b6011805460ff610100808304821615810261ff001990931692909217928390556040517f8e47bd62470c6cba4d30c023548622607c9c84402a5655f2569b7934c36a9e4f936117299390049091161515815260200190565b60405180910390a1565b6000546001600160a01b0316331461175d5760405162461bcd60e51b8152600401610ad4906143da565b600f819055604051726d61785472696767657273506572426c6f636b60681b8152601301610e44565b601154610100900460ff16156117ae5760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156117d15760405162461bcd60e51b8152600401610ad4906142d0565b6117da33610f1e565b6117f65760405162461bcd60e51b8152600401610ad4906142f0565b6117fe613337565b60405163095be50560e41b8152600481018490526000907f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b0316906395be50509060240160a060405180830381865afa158015611866573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188a919061434c565b50506040516366307a4f60e01b815260048101889052909350600092506001600160a01b037f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8681691506366307a4f90602401608060405180830381865afa1580156118f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191d9190614573565b905060008261ffff16116119435760405162461bcd60e51b8152600401610ad490614521565b600081606001516001600160401b0316116119885760405162461bcd60e51b81526020600482015260056024820152641393d7d4d360da1b6044820152606401610ad4565b60208101516001600160401b031660006119a861ffff85163488886133ac565b90506119b88282600001516137a6565b60208101516119c56135e7565b6020820151604051632029fcf560e21b81526001600160a01b037f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa86816916380a7f3d491611a1c918c916002919087906004016145fd565b600060405180830381600087803b158015611a3657600080fd5b505af1158015611a4a573d6000803e3d6000fd5b5050506020808401518451604080516001600160401b038088168252909316938301939093529181019190915261ffff87169150899033907fb03dbc9368faf0f8588dc8429c40a26ef9a637488f1ea5521a2ba2bfb5ff2016906060015b60405180910390a45050505050610dae61365f565b6000546001600160a01b03163314611ae75760405162461bcd60e51b8152600401610ad4906143da565b600e8190556040517f6f70656e506f736974696f6e43616e63656c6c6174696f6e466565467261637481526234b7b760e91b6020820152602301610e44565b601154610100900460ff1615611b4e5760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff1615611b715760405162461bcd60e51b8152600401610ad4906142d0565b611b7a33610f1e565b611b965760405162461bcd60e51b8152600401610ad4906142f0565b611b9e613337565b60405163c608b6c160e01b8152600481018490526000907f00000000000000000000000008422b1ca26c4b6e28bd8635cabb03bc1dbe5d626001600160a01b03169063c608b6c19060240160a0604051808303816000875af1158015611c08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2c9190614438565b9050600281602001516003811115611c4657611c466143c4565b14611c895760405162461bcd60e51b815260206004820152601360248201527215541110551157d3d491115497d393d517d4d3606a1b6044820152606401610ad4565b60405163095be50560e41b8152600481018590526000907f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b0316906395be50509060240160a060405180830381865afa158015611cf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d15919061434c565b5050925050506000611d2d8261ffff163487876133ac565b9050611d4a83604001516001600160401b031682600001516134bb565b611d526135e7565b600081602001519050611d72338886602001516002886060015186613963565b5050505050610dae61365f565b601154610100900460ff1615611da75760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff1615611dca5760405162461bcd60e51b8152600401610ad4906142d0565b611dd333610f1e565b611def5760405162461bcd60e51b8152600401610ad4906142f0565b611df7613337565b60405163095be50560e41b8152600481018490526000907f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b0316906395be50509060240160a060405180830381865afa158015611e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e83919061434c565b50506040516366307a4f60e01b815260048101889052909350600092506001600160a01b037f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8681691506366307a4f90602401608060405180830381865afa158015611ef2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f169190614573565b905060008261ffff1611611f3c5760405162461bcd60e51b8152600401610ad490614521565b600081604001516001600160401b031611611f815760405162461bcd60e51b815260206004820152600560248201526404e4f5f54560dc1b6044820152606401610ad4565b80516001600160401b03166000611f9e61ffff85163488886133ac565b9050611fae8282600001516137a6565b6020810151611fbb6135e7565b6020820151604051632029fcf560e21b81526001600160a01b037f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa86816916380a7f3d491612012918c916001919087906004016145fd565b600060405180830381600087803b15801561202c57600080fd5b505af1158015612040573d6000803e3d6000fd5b5050506020808401518451604080516001600160401b038088168252909316938301939093529181019190915261ffff87169150899033907fbe700227f721a08f3b755aa3348a63564c2c07890aba73de46372f7bffcaa2e290606001611aa8565b6000546001600160a01b031633146120cc5760405162461bcd60e51b8152600401610ad4906143da565b610de78282613c44565b601154610100900460ff16156120fe5760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156121215760405162461bcd60e51b8152600401610ad4906142d0565b61212a33610f1e565b6121465760405162461bcd60e51b8152600401610ad4906142f0565b61214e613337565b60008060008060007f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b03166395be5050896040518263ffffffff1660e01b81526004016121a491815260200190565b60a060405180830381865afa1580156121c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e5919061434c565b9450945094506001600160401b031694509450600084116122425760405162461bcd60e51b81526020600482015260176024820152762727afa822a72224a723afa6a0a925a2aa2fa7a92222a960491b6044820152606401610ad4565b6001856005811115612256576122566143c4565b146122955760405162461bcd60e51b815260206004820152600f60248201526e1393d517d3d4115397d3505492d155608a1b6044820152606401610ad4565b60006122a78461ffff16348a8a6133ac565b90506122b78582600001516134bb565b602081015160006122ce61ffff8716838688613870565b90506122d86135e7565b600e546040516303ad224560e61b8152600481018d90526001600160401b038316602482015260448101919091527f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b03169063eb489140906064016115fc565b6000546001600160a01b031633146123695760405162461bcd60e51b8152600401610ad4906143da565b600c8190556040517f74726967676572507269636546726573686e65737354696d6552616e676500008152601e01610e44565b601154610100900460ff16156123c45760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156123e75760405162461bcd60e51b8152600401610ad4906142d0565b6123f033610f1e565b61240c5760405162461bcd60e51b8152600401610ad4906142f0565b612414613337565b60405163095be50560e41b8152600481018490526000907f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b0316906395be50509060240160a060405180830381865afa15801561247c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a0919061434c565b50509250505060008161ffff16116124ca5760405162461bcd60e51b8152600401610ad490614521565b60006124dc8261ffff163486866133ac565b60208101519091506124ec6135e7565b6020820151604051632029fcf560e21b81526001600160a01b037f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa86816916380a7f3d491612543918a916003919087906004016145fd565b600060405180830381600087803b15801561255d57600080fd5b505af1158015612571573d6000803e3d6000fd5b505050506020828101518351604080516001600160401b0386811682529093169383019390935281830152905161ffff851691889133917f086bdd0cdd4ae322dd6112d05bdf96c020e6b90cc84ee2d39941bd716e18fb92919081900360600190a4505050610dae61365f565b60606125ea6002613d11565b905090565b6000546001600160a01b031633146126195760405162461bcd60e51b8152600401610ad4906143da565b600d8190556040517f6d61726b65744f7264657243616e63656c4665654672616374696f6e000000008152601c01610e44565b6000546001600160a01b031633146126765760405162461bcd60e51b8152600401610ad4906143da565b6110e581613d1e565b601154610100900460ff16156126a75760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff16156126ca5760405162461bcd60e51b8152600401610ad4906142d0565b6126d333610f1e565b6126ef5760405162461bcd60e51b8152600401610ad4906142f0565b6126f7613337565b60405163c608b6c160e01b8152600481018490526000907f00000000000000000000000008422b1ca26c4b6e28bd8635cabb03bc1dbe5d626001600160a01b03169063c608b6c19060240160a0604051808303816000875af1158015612761573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127859190614438565b905060018160200151600381111561279f5761279f6143c4565b146127e25760405162461bcd60e51b815260206004820152601360248201527205550444154455f4f524445525f4e4f545f545606c1b6044820152606401610ad4565b60405163095be50560e41b8152600481018590526000907f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b0316906395be50509060240160a060405180830381865afa15801561284a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286e919061434c565b50509250505060006128868261ffff163487876133ac565b90506128a383604001516001600160401b031682600001516134bb565b6128ab6135e7565b600081602001519050611d72338886602001516001886060015186613963565b6000546001600160a01b031633146129115760405162461bcd60e51b81526020600482015260096024820152682737ba1020b236b4b760b91b6044820152606401610ad4565b600180546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a991015b60405180910390a15050565b6000546001600160a01b0316331461299d5760405162461bcd60e51b8152600401610ad4906143da565b600a819055604051721b585c9ad95d13dc99195c9cd51a5b595bdd5d606a1b8152601301610e44565b6000546001600160a01b031633146129f05760405162461bcd60e51b8152600401610ad4906143da565b60098190556040517f6d696e54726967676572506572696f64466f724c696d69744f726465727300008152601e01610e44565b6000546001600160a01b03163314612a4d5760405162461bcd60e51b8152600401610ad4906143da565b6011805460ff8082161560ff1990921682179092556040519116151581527fda88b5dfaac55549d4ddddd43a09d4b911233df354952ebc9ac2041aa185343690602001611729565b6000546001600160a01b03163314612abf5760405162461bcd60e51b8152600401610ad4906143da565b6110e581613dac565b601154610100900460ff1615612af05760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff1615612b135760405162461bcd60e51b8152600401610ad4906142d0565b612b1c33610f1e565b612b385760405162461bcd60e51b8152600401610ad4906142f0565b612b40613337565b60008060007f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b03166395be5050856040518263ffffffff1660e01b8152600401612b9391815260200190565b60a060405180830381865afa158015612bb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd4919061434c565b505092506001600160401b03169250925060008211612c055760405162461bcd60e51b8152600401610ad490614521565b6001836005811115612c1957612c196143c4565b14612c585760405162461bcd60e51b815260206004820152600f60248201526e1393d517d3d4115397d3505492d155608a1b6044820152606401610ad4565b600a54612c6590836144e8565b421015612c845760405162461bcd60e51b8152600401610ad4906144fb565b600d54604051636e01af8d60e01b81526001600160a01b037f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8681691636e01af8d91612cd791889160019190600401614649565b600060405180830381600087803b158015612cf157600080fd5b505af1158015612d05573d6000803e3d6000fd5b505060405161ffff8416925086915033907f5079795ec65f793d5a0ed74d8f8e1562b7795934b40612bf55cf0e5d55a3447990600090a45050506110e561365f565b601154610100900460ff1615612d6f5760405162461bcd60e51b8152600401610ad4906142b2565b60115460ff1615612d925760405162461bcd60e51b8152600401610ad4906142d0565b612d9b33610f1e565b612db75760405162461bcd60e51b8152600401610ad4906142f0565b612dbf613337565b60405163c608b6c160e01b8152600481018490526000907f00000000000000000000000008422b1ca26c4b6e28bd8635cabb03bc1dbe5d626001600160a01b03169063c608b6c19060240160a0604051808303816000875af1158015612e29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4d9190614438565b9050600381602001516003811115612e6757612e676143c4565b14612eb45760405162461bcd60e51b815260206004820152601a60248201527f5550444154455f4f524445525f4e4f545f54505f414e445f534c0000000000006044820152606401610ad4565b60405163095be50560e41b8152600481018590526000907f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa8686001600160a01b0316906395be50509060240160a060405180830381865afa158015612f1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f40919061434c565b5050925050506000612f588261ffff163487876133ac565b9050612f7583604001516001600160401b031682600001516134bb565b612f7d6135e7565b600081602001519050612f9d338886602001516001886060015186613963565b612fdc5760405162461bcd60e51b815260206004820152601060248201526f4641494c45445f54505f55504441544560801b6044820152606401610ad4565b612ff3338886602001516002886080015186613963565b6130325760405162461bcd60e51b815260206004820152601060248201526f4641494c45445f534c5f55504441544560801b6044820152606401610ad4565b50505050610dae61365f565b6001546001600160a01b03163314801561306257506001546001600160a01b031615155b6130ae5760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420746865204558495354494e472070656e64696e672061646d696e00006044820152606401610ad4565b60008054600180546001600160a01b038082166001600160a01b031980861682179096559490911690915560408051919092168082526020820184905292917ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc910160405180910390a1600154604080516001600160a01b03808516825290921660208301527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101612967565b6000546001600160a01b031633146131865760405162461bcd60e51b8152600401610ad4906143da565b806001600160a01b0316634535dc4c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e89190614659565b6132265760405162461bcd60e51b815260206004820152600f60248201526e10a83934b1b2ab30b634b230ba37b960891b6044820152606401610ad4565b600680546001600160a01b0319166001600160a01b0383161790556040516d283934b1b2ab30b634b230ba37b960911b8152600e016040519081900381206001600160a01b0383168252907f943e9d45a11aaae5d87503e3bc248665d9807856e5cf2bdb4a988bee4442278190602001610e77565b6000546001600160a01b031633146132c55760405162461bcd60e51b8152600401610ad4906143da565b60075481116133045760405162461bcd60e51b815260206004820152600b60248201526a57524f4e475f56414c554560a81b6044820152606401610ad4565b60088190556040517f6d617854726967676572506572696f64466f724d61726b65744f7264657273008152601f01610e44565b7f0000000000000000000000004cf3d61165a6be8ff741320ad27cab57fae5c2076001600160a01b031663f83d08ba6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561339257600080fd5b505af11580156133a6573d6000803e3d6000fd5b50505050565b60408051606081018252600080825260208201819052918101829052906133d586868686613e45565b60008781526004602090815260408220549083015192935063ffffffff1691613407906001600160401b031683613ee0565b90508083604001516001600160401b031611156134665760405162461bcd60e51b815260206004820152601960248201527f434f4e464944454e43455f52414e47455f544f4f5f57494445000000000000006044820152606401610ad4565b82514210156134af5760405162461bcd60e51b815260206004820152601560248201527411955515549157d4149250d157d4915413d4951151605a1b6044820152606401610ad4565b50909695505050505050565b6000600754836134cb91906144e8565b90506000600854846134dd91906144e8565b90508142101561352f5760405162461bcd60e51b815260206004820152601d60248201527f4d41524b45545f4f524445525f545249474745525f544f4f5f534f4f4e0000006044820152606401610ad4565b8042111561357f5760405162461bcd60e51b815260206004820152601d60248201527f4d41524b45545f4f524445525f545249474745525f544f4f5f4c4154450000006044820152606401610ad4565b81831015801561358f5750808311155b6133a65760405162461bcd60e51b8152602060048201526024808201527f4d41524b45545f4f524445525f50524943455f4f55545f4f465f54494d455f4660448201526352414d4560e01b6064820152608401610ad4565b43600090815260106020526040902054600f5481106136415760405162461bcd60e51b81526020600482015260166024820152754d41585f54524947474552535f5045525f424c4f434b60501b6044820152606401610ad4565b61364c8160016144e8565b4360009081526010602052604090205550565b7f0000000000000000000000004cf3d61165a6be8ff741320ad27cab57fae5c2076001600160a01b03166340da020f6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561339257600080fd5b7f00000000000000000000000000000000000000000000000000000000000003e88163ffffffff1611156137225760405162461bcd60e51b815260206004820152600f60248201526e0a6a0a48a8288bea89e9ebe90928e9608b1b6044820152606401610ad4565b600082815260056020908152604091829020805463ffffffff191663ffffffff8516908117909155915191825283917ffe5fd0852fab5f8ba593533cf24a4b4b235704c0e06956d0a58cc2ca0a4b6b4491015b60405180910390a25050565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b6000600954836137b691906144e8565b9050804210156138085760405162461bcd60e51b815260206004820152601c60248201527f4c494d49545f4f524445525f545249474745525f544f4f5f534f4f4e000000006044820152606401610ad4565b808210156138645760405162461bcd60e51b815260206004820152602360248201527f4c494d49545f4f524445525f50524943455f4f55545f4f465f54494d455f4652604482015262414d4560e81b6064820152608401610ad4565b610dae82600c54613efa565b6000620186a08363ffffffff1611156138cb5760405162461bcd60e51b815260206004820152601960248201527f5350524541445f524544554354494f4e5f544f4f5f48494748000000000000006044820152606401610ad4565b600085815260056020526040812054620186a0906138f9906001600160401b0388169063ffffffff16614674565b613903919061468b565b90506000620186a061391b63ffffffff8716846146ad565b6001600160401b031661392e919061468b565b61393890836146d8565b90508361394e5761394981876146d8565b613958565b61395881876146f8565b979650505050505050565b60405163c07f992160e01b81526000906001600160a01b037f00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa868169063c07f9921906139b8908990889088908890600401614718565b600060405180830381600087803b1580156139d257600080fd5b505af19250505080156139e3575060015b613bde576139ef614728565b806308c379a003613a755750613a03614744565b80613a0e5750613a77565b856003811115613a2057613a206143c4565b87896001600160a01b03167f889460050d9a293fbe31b6ce00a37ae62020cb8c8a19cf31e9496cb13246f6e2888888876000604051613a639594939291906147cd565b60405180910390a46000915050613c3a565b505b3d808015613aa1576040519150601f19603f3d011682016040523d82523d6000602084013e613aa6565b606091505b50632eb752bf60e21b613ab88261484f565b6001600160e01b03191603613b9f576001856002811115613adb57613adb6143c4565b14613b1e5760405162461bcd60e51b815260206004820152601360248201527204341505f4552524f525f4e4f545f4f4e5f545606c1b6044820152606401610ad4565b60248101516044820151876003811115613b3a57613b3a6143c4565b898b6001600160a01b03167f889460050d9a293fbe31b6ce00a37ae62020cb8c8a19cf31e9496cb13246f6e28a8a8a886011811115613b7b57613b7b6143c4565b604051613b8b9493929190614886565b60405180910390a460009350505050613c3a565b60405162461bcd60e51b81526020600482015260146024820152732aa725a727aba72fa1aaa9aa27a6afa2a92927a960611b6044820152606401610ad4565b846003811115613bf057613bf06143c4565b86886001600160a01b03167ff0ac91a20375484f5a80315763782e4fe4b42bd038b08ba4939ff1a506974edf878787604051613c2e939291906148d5565b60405180910390a45060015b9695505050505050565b7f00000000000000000000000000000000000000000000000000000000000027108163ffffffff161115613cba5760405162461bcd60e51b815260206004820152601c60248201527f434f4e464944454e43455f4652414354494f4e5f544f4f5f48494748000000006044820152606401610ad4565b600082815260046020908152604091829020805463ffffffff191663ffffffff8516908117909155915191825283917f88e6fad616d859d6fba20e93ab2acbf0756b6bc2d90c6002000f709f510cadb09101613775565b6060600061379f83613f88565b613d2781610f1e565b613d695760405162461bcd60e51b81526020600482015260136024820152721050d0d3d5539517d393d517d0531313d5d151606a1b6044820152606401610ad4565b613d74600282613fe4565b506040516001600160a01b038216907fc985d67a353004ba149a223b2b9e5c13cca6610b11cb45b4aa029c880d8f7cb590600090a250565b613db581610f1e565b15613e025760405162461bcd60e51b815260206004820152601760248201527f4143434f554e545f414c52454144595f414c4c4f5745440000000000000000006044820152606401610ad4565b613e0d600282613ff9565b506040516001600160a01b038216907fc5944eab072face4b169928723314c5978080e99ed8f8527faedb18c06664c3590600090a250565b6040805160608101825260008082526020820181905281830152600654915163f4a6a09360e01b815290916001600160a01b03169063f4a6a093908690613e9490899088908890600401614929565b60606040518083038185885af1158015613eb2573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613ed791906149d1565b95945050505050565b6000620186a0613ef08385614674565b61379f919061468b565b6000613f068242614a43565b905080831015613f485760405162461bcd60e51b815260206004820152600d60248201526c14149250d157d513d3d7d3d311609a1b6044820152606401610ad4565b42831115610dae5760405162461bcd60e51b815260206004820152600d60248201526c50524943455f544f4f5f4e455760981b6044820152606401610ad4565b606081600001805480602002602001604051908101604052809291908181526020018280548015613fd857602002820191906000526020600020905b815481526020019060010190808311613fc4575b50505050509050919050565b600061379f836001600160a01b03841661400e565b600061379f836001600160a01b038416614108565b600081815260018301602052604081205480156140f7576000614032600183614a43565b855490915060009061404690600190614a43565b90508082146140ab57600086600001828154811061406657614066614a56565b906000526020600020015490508087600001848154811061408957614089614a56565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806140bc576140bc614a6c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610f2b565b6000915050610f2b565b5092915050565b600081815260018301602052604081205461414f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610f2b565b506000610f2b565b60006020828403121561416957600080fd5b5035919050565b60008083601f84011261418257600080fd5b5081356001600160401b0381111561419957600080fd5b6020830191508360208260051b85010111156141b457600080fd5b9250929050565b6000806000604084860312156141d057600080fd5b8335925060208401356001600160401b038111156141ed57600080fd5b6141f986828701614170565b9497909650939450505050565b63ffffffff811681146110e557600080fd5b6000806040838503121561422b57600080fd5b82359150602083013561423d81614206565b809150509250929050565b60006020828403121561425a57600080fd5b81356001600160a01b038116811461379f57600080fd5b6020808252825182820181905260009190848201906040850190845b818110156134af5783516001600160a01b03168352928401929184019160010161428d565b602080825260049082015263444f4e4560e01b604082015260600190565b60208082526006908201526514105554d15160d21b604082015260600190565b6020808252601690820152752727aa2fa0a62627aba2a22faa27afaa2924a3a3a2a960511b604082015260600190565b80516001600160401b038116811461433757600080fd5b919050565b8051801515811461433757600080fd5b600080600080600060a0868803121561436457600080fd5b85516006811061437357600080fd5b945061438160208701614320565b9350604086015161ffff8116811461439857600080fd5b92506143a66060870161433c565b915060808601516143b681614206565b809150509295509295909350565b634e487b7160e01b600052602160045260246000fd5b6020808252600a908201526927a7262cafa0a226a4a760b11b604082015260600190565b601f8201601f191681016001600160401b038111828210171561443157634e487b7160e01b600052604160045260246000fd5b6040525050565b600060a0828403121561444a57600080fd5b60405160a081018181106001600160401b038211171561447a57634e487b7160e01b600052604160045260246000fd5b6040528251815260208301516004811061449357600080fd5b60208201526144a460408401614320565b60408201526144b560608401614320565b60608201526144c660808401614320565b60808201529392505050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610f2b57610f2b6144d2565b6020808252600c908201526b15d0525517d512535153d55560a21b604082015260600190565b60208082526010908201526f2727afa9aaa1a42fa827a9a4aa24a7a760811b604082015260600190565b8381526060810160028410614562576145626143c4565b602082019390935260400152919050565b60006080828403121561458557600080fd5b604051608081018181106001600160401b03821117156145b557634e487b7160e01b600052604160045260246000fd5b6040526145c183614320565b81526145cf60208401614320565b60208201526145e060408401614320565b60408201526145f160608401614320565b60608201529392505050565b8481526080810160048510614614576146146143c4565b60208201949094526001600160401b0392831660408201529116606090910152919050565b600381106110e5576110e56143c4565b8381526060810161456284614639565b60006020828403121561466b57600080fd5b61379f8261433c565b8082028115828204841417610f2b57610f2b6144d2565b6000826146a857634e487b7160e01b600052601260045260246000fd5b500490565b6001600160401b038181168382160280821691908281146146d0576146d06144d2565b505092915050565b6001600160401b03828116828216039080821115614101576141016144d2565b6001600160401b03818116838216019080821115614101576141016144d2565b8481526080810161461485614639565b600060033d11156147415760046000803e5060005160e01c5b90565b600060443d10156147525790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561478157505050505090565b82850191508151818111156147995750505050505090565b843d87010160208285010111156147b35750505050505090565b6147c2602082860101876143fe565b509095945050505050565b6147d686614639565b858152600060206001600160401b03808816602085015280871660408501525060a0606084015284518060a085015260005b818110156148245786810183015185820160c001528201614808565b50600060c0828601015260c0601f19601f830116850101925050508260808301529695505050505050565b805160208201516001600160e01b0319808216929190600483101561487e5780818460040360031b1b83161693505b505050919050565b61488f85614639565b9384526001600160401b0392831660208501529116604083015260a0606083018190526009908301526821a0a82fa2a92927a960b91b60c0830152608082015260e00190565b606081016148e285614639565b9381526001600160401b039283166020820152911660409091015290565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000604082018583526020604060208501528185835260608501905060608660051b86010192508660005b878110156149c357868503605f190183528135368a9003601e1901811261497a57600080fd5b890184810190356001600160401b0381111561499557600080fd5b8036038213156149a457600080fd5b6149af878284614900565b965050509183019190830190600101614954565b509298975050505050505050565b6000606082840312156149e357600080fd5b604051606081018181106001600160401b0382111715614a1357634e487b7160e01b600052604160045260246000fd5b60405282518152614a2660208401614320565b6020820152614a3760408401614320565b60408201529392505050565b81810381811115610f2b57610f2b6144d2565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fdfea26469706673582212205ea30faf884e26d1e90ed9111c8ccbd84fa172559deb1ea27cff51bc6487b13c64736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa868
-----Decoded View---------------
Arg [0] : _tradingFloor (address): 0x37792EecFA985D0b00a51864c970e7df406AA868
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000037792eecfa985d0b00a51864c970e7df406aa868
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.