Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- TokenConfigsLogic
- Optimization enabled
- true
- Compiler version
- v0.7.6+commit.7338295f
- Optimization runs
- 200
- EVM Version
- istanbul
- Verified at
- 2023-09-15T17:56:27.320667Z
contracts/protocol/libraries/logic/TokenConfigsLogic.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import "../../../dependencies/openzeppelin/contracts/SafeMath.sol";
import "../helpers/Errors.sol";
import "../types/DataTypes.sol";
library TokenConfigsLogic {
using SafeMath for uint256;
using TokenConfigsLogic for DataTypes.TokenConfigs;
function version() public pure returns (uint256) {
return 1;
}
function setTokenConfig(
DataTypes.TokenConfigs storage tokenConfigs,
address _token,
DataTypes.TokenConfig calldata tokenConfig
) public {
require(tokenConfig.isWhitelisted, Errors.TCL_TOKEN_NOT_WHITELISTED);
require(tokenConfig.weight > 0, Errors.TCL_INVALID_TOKEN_WEIGHT);
// increment token count for the first time
if (!tokenConfigs.tokenConfigs[_token].isWhitelisted) {
tokenConfigs.allWhitelistedTokens.push(_token);
}
uint256 _totalTokenWeights = tokenConfigs.totalTokenWeights.sub(
tokenConfigs.tokenConfigs[_token].weight
);
tokenConfigs.tokenConfigs[_token] = tokenConfig;
tokenConfigs.totalTokenWeights = _totalTokenWeights.add(
tokenConfig.weight
);
}
function clearTokenConfig(
DataTypes.TokenConfigs storage tokenConfigs,
address _token
) public {
require(
tokenConfigs.tokenConfigs[_token].isWhitelisted,
Errors.TCL_TOKEN_NOT_WHITELISTED
);
tokenConfigs.totalTokenWeights = tokenConfigs.totalTokenWeights.sub(
tokenConfigs.tokenConfigs[_token].weight
);
delete tokenConfigs.tokenConfigs[_token];
uint256 lengthMinus1 = tokenConfigs.allWhitelistedTokens.length - 1;
for (uint256 i = 0; i < lengthMinus1; i++) {
// no need to compare last element
// if no match, it's the target to be removed
// otherwise, its value will be saved in target's slot
if (tokenConfigs.allWhitelistedTokens[i] == _token) {
tokenConfigs.allWhitelistedTokens[i] = tokenConfigs
.allWhitelistedTokens[lengthMinus1];
break;
}
}
tokenConfigs.allWhitelistedTokens.pop();
}
function validateTokens(
DataTypes.TokenConfigs storage tokenConfigs,
address _collateralToken,
address _indexToken,
bool _isLong
) public view {
if (_isLong) {
require(
_collateralToken == _indexToken,
Errors.TCL_MISMATCHED_TOKENS
);
require(
tokenConfigs.tokenConfigs[_collateralToken].isWhitelisted,
Errors.TCL_COLLATERAL_TOKEN_NOT_WHITELISTED
);
require(
!tokenConfigs.tokenConfigs[_collateralToken].isStable,
Errors.TCL_COLLATERAL_TOKEN_MUST_NOT_BE_STABLE
);
return;
}
require(
tokenConfigs.tokenConfigs[_collateralToken].isWhitelisted,
Errors.TCL_COLLATERAL_TOKEN_NOT_WHITELISTED
);
require(
tokenConfigs.tokenConfigs[_collateralToken].isStable,
Errors.TCL_COLLATERAL_TOKEN_MUST_BE_STABLE
);
require(
!tokenConfigs.tokenConfigs[_indexToken].isStable,
Errors.TCL_INDEX_TOKEN_MUST_NOT_BE_STABLE
);
require(
tokenConfigs.tokenConfigs[_indexToken].isShortable,
Errors.TCL_INDEX_TOKEN_NOT_SHORTABLE
);
}
}
contracts/dependencies/openzeppelin/contracts/SafeMath.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b)
internal
pure
returns (bool, uint256)
{
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b)
internal
pure
returns (bool, uint256)
{
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b)
internal
pure
returns (bool, uint256)
{
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b)
internal
pure
returns (bool, uint256)
{
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b)
internal
pure
returns (bool, uint256)
{
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
contracts/protocol/libraries/helpers/Errors.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.6;
library Errors {
uint256 public constant V_TOKEN_NOT_WHITELISTED = 14; // Vault: token not whitelisted
uint256 public constant V_INVALID_TOKEN_AMOUNT = 15; // Vault: invalid tokenAmount
uint256 public constant V_INVALID_USDPH_AMOUNT = 18; // Vault: invalid usdphAmount
uint256 public constant V_INVALID_REDEMPTION_AMOUNT = 21; // Vault: invalid redemptionAmount
uint256 public constant V_INVALID_AMOUNT_OUT = 22; // Vault: invalid amountOut
uint256 public constant V_SWAPS_NOT_ENABLED = 23; // Vault: swaps not enabled
uint256 public constant V_SAME_TOKEN = 26; // Vault: same token in and out
uint256 public constant V_INVALID_AMOUNT_IN = 27; // Vault: invalid amountIn
uint256 public constant V_INSUFFICIENT_COLLATERAL_FOR_FEES = 29; // Vault: insufficient collateral for fees
uint256 public constant V_INVALID_POSITION_SIZE = 30; // Vault: invalid position.size
uint256 public constant V_EMPTY_POSITION = 31; // Vault: empty position
uint256 public constant V_POSITION_SIZE_EXCEEDED = 32; // Vault: position size exceeded
uint256 public constant V_POSITION_COLLATERAL_EXCEEDED = 33; // Vault: position collateral exceeded
uint256 public constant V_INVALID_LIQUIDATOR = 34; // Vault: invalid liquidator
uint256 public constant V_POSITION_CANNOT_BE_LIQUIDATED = 36; // Vault: position cannot be liquidated
uint256 public constant V_COLLATERAL_SHOULD_BE_WITHDRAWN = 39; // Vault: collateral should be withdrawn
uint256 public constant V_SIZE_MUST_BE_MORE_THAN_COLLATERAL = 40; // Vault: size must be more than collateral
uint256 public constant V_POOL_AMOUNT_EXCEEDS_BALANCE = 49; // Vault: pool amount exceeds balance
uint256 public constant V_RESERVE_EXCEEDS_POOL = 50; // Vault: reserve exceeds pool
uint256 public constant V_MAX_USDPH_EXCEEDED = 51; // Vault: max USDPH exceeded
uint256 public constant V_NOT_PHLP_MANAGER = 54; // Vault: caller is not PHLP Manager
uint256 public constant V_POOL_LESS_THAN_BUFFER = 100; // Vault: poolAmount < bufferAmount
uint256 public constant V_MAX_SHORTS_EXCEEDED = 101; // Vault: max shorts exceeded
uint256 public constant V_NOT_CONFIGURATOR = 102; // Vault: caller is not the vault configurator
uint256 public constant V_NOT_ROUTER = 103; // Vault: caller is not the router
string public constant VC_INVALID_STAKING_BPS = "1"; // VaultConfigurator: invalid stakingBps
string public constant VC_INVALID_MAX_LEVERAGE = "2"; // VaultConfigurator: invalid maxLeverage
string public constant VC_INVALID_TAX_BPS = "3"; // VaultConfigurator: invalid taxBps
string public constant VC_INVALID_STABLE_TAX_BPS = "4"; // VaultConfigurator: invalid stableTaxBps
string public constant VC_INVALID_MINT_BURN_FEE_BPS = "5"; // VaultConfigurator: invalid mintBurnFeeBps
string public constant VC_INVALID_SWAP_FEE_BPS = "6"; // VaultConfigurator: invalid swapFeeBps
string public constant VC_INVALID_STABLE_SWAP_FEE_BPS = "7"; // VaultConfigurator: invalid stableSwapFeeBps
string public constant VC_INVALID_MARGIN_FEE_BPS = "8"; // VaultConfigurator: invalid marginFeeBps
string public constant VC_INVALID_LIQUIDATION_FEE_USD = "9"; // VaultConfigurator: invalid _liquidationFeeUsd
string public constant VC_INVALID_FUNDING_INTERVAL = "10"; // VaultConfigurator: invalid fundingInterval
string public constant VC_INVALID_FUNDING_RATE_FACTOR = "11"; // VaultConfigurator: invalid fundingRateFactor
string public constant VC_INVALID_STABLE_FUNDING_RATE_FACTOR = "12"; // VaultConfigurator: invalid stableFundingRateFactor
string public constant VC_TOKEN_NOT_WHITELISTED = "13"; // VaultConfigurator: token not whitelisted
string public constant VU_LEVERAGE_NOT_ENABLED = "28"; // VaultUtil: leverage not enabled
string public constant VU_INVALID_AVERAGE_PRICE = "38"; // VaultUtil: invalid averagePrice
string public constant VU_INVALID_MSG_SENDER = "41"; // VaultUtil: invalid msg.sender
string public constant TCL_MISMATCHED_TOKENS = "42"; // TokenConfigsLogic: mismatched tokens
string public constant TCL_COLLATERAL_TOKEN_NOT_WHITELISTED = "43"; // TokenConfigsLogic: collateralToken not whitelisted
string public constant TCL_COLLATERAL_TOKEN_MUST_NOT_BE_STABLE = "44"; // TokenConfigsLogic: collateralToken must not be a stableToken
string public constant TCL_COLLATERAL_TOKEN_MUST_BE_STABLE = "46"; // TokenConfigsLogic: collateralToken must be a stableToken
string public constant TCL_INDEX_TOKEN_MUST_NOT_BE_STABLE = "47"; // TokenConfigsLogic: indexToken must not be a stableToken
string public constant TCL_INDEX_TOKEN_NOT_SHORTABLE = "48"; // TokenConfigsLogic: indexToken not shortable
string public constant TCL_TOKEN_NOT_WHITELISTED = "200"; // TokenConfigsLogic: token not whitelisted
string public constant TCL_INVALID_TOKEN_WEIGHT = "201"; // TokenConfigsLogic: invalid token weight
}
contracts/protocol/libraries/types/DataTypes.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.6;
library DataTypes {
struct VaultConfig {
bool isSwapEnabled;
bool isLeverageEnabled;
uint256 maxLeverage;
// fees
uint256 taxBps;
uint256 stableTaxBps;
uint256 mintBurnFeeBps;
uint256 swapFeeBps;
uint256 stableSwapFeeBps;
uint256 marginFeeBps;
uint256 liquidationFeeUsd;
uint256 minProfitTime;
bool hasDynamicFees;
// staking
uint256 stakingBps;
// funding rate
uint256 fundingInterval;
uint256 fundingRateFactor;
uint256 stableFundingRateFactor;
}
struct TokenConfig {
// should always be true if token exists
bool isWhitelisted;
// basic parameters
uint256 decimals;
uint256 weight; // customisation of index composition
uint256 minProfitBps;
uint256 maxUsdphAmount; // a max amount of USDPH debt for a token
bool isStable;
bool isShortable;
// risk parameters
// bufferAmount allows specification of an amount to exclude from swaps
// this can be used to ensure a certain amount of liquidity is available for leverage positions
uint256 bufferAmount;
uint256 maxGlobalShortSize;
}
struct TokenConfigs {
uint256 totalTokenWeights;
address[] allWhitelistedTokens;
mapping(address => TokenConfig) tokenConfigs;
}
}
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{},"evmVersion":"istanbul"}
Contract ABI
[{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"version","inputs":[]}]
Contract Creation Code
0x610974610026600b82828239805160001a60731461001957fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100565760003560e01c80632e43d1011461005b578063475522391461007d57806354fd4d501461009057806398a1a85c146100ae575b600080fd5b81801561006757600080fd5b5061007b610076366004610753565b6100ce565b005b61007b61008b36600461077e565b6102a1565b610098610519565b6040516100a59190610867565b60405180910390f35b8180156100ba57600080fd5b5061007b6100c93660046107cc565b61051e565b6001600160a01b0381166000908152600283016020908152604091829020548251808401909352600383526203230360ec1b9183019190915260ff166101305760405162461bcd60e51b81526004016101279190610814565b60405180910390fd5b506001600160a01b0381166000908152600280840160205260409091200154825461015a9161065d565b82556001600160a01b0381166000908152600280840160205260408220805460ff191681556001808201849055918101839055600381018390556004810183905560058101805461ffff191690556006810183905560070182905583015460001901905b8181101561026c57826001600160a01b03168460010182815481106101df57fe5b6000918252602090912001546001600160a01b031614156102645783600101828154811061020957fe5b6000918252602090912001546001850180546001600160a01b03909216918390811061023157fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061026c565b6001016101be565b508260010180548061027a57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b80156103ab57816001600160a01b0316836001600160a01b031614604051806040016040528060028152602001611a1960f11b815250906102f55760405162461bcd60e51b81526004016101279190610814565b506001600160a01b03831660009081526002808601602090815260409283902054835180850190945291835261343360f01b9083015260ff1661034b5760405162461bcd60e51b81526004016101279190610814565b506001600160a01b038316600090815260028086016020908152604092839020600501548351808501909452918352610d0d60f21b9083015260ff16156103a55760405162461bcd60e51b81526004016101279190610814565b50610513565b6001600160a01b03831660009081526002808601602090815260409283902054835180850190945291835261343360f01b9083015260ff166104005760405162461bcd60e51b81526004016101279190610814565b506001600160a01b038316600090815260028086016020908152604092839020600501548351808501909452918352611a1b60f11b9083015260ff166104595760405162461bcd60e51b81526004016101279190610814565b506001600160a01b03821660009081526002808601602090815260409283902060050154835180850190945291835261343760f01b9083015260ff16156104b35760405162461bcd60e51b81526004016101279190610814565b506001600160a01b03821660009081526002858101602090815260409283902060050154835180850190945291835261068760f31b90830152610100900460ff166105115760405162461bcd60e51b81526004016101279190610814565b505b50505050565b600190565b61052b6020820182610737565b6040518060400160405280600381526020016203230360ec1b815250906105655760405162461bcd60e51b81526004016101279190610814565b50604080518082018252600381526232303160e81b6020820152908201356105a05760405162461bcd60e51b81526004016101279190610814565b506001600160a01b038216600090815260028401602052604090205460ff166105f3576001838101805491820181556000908152602090200180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b03821660009081526002808501602052604082200154845461061b9161065d565b6001600160a01b0384166000908152600286016020526040902090915082906106448282610898565b5061065590508160408401356106ba565b909355505050565b6000828211156106b4576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082820183811015610714576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b80356001600160a01b038116811461073257600080fd5b919050565b600060208284031215610748578081fd5b81356107148161092d565b60008060408385031215610765578081fd5b823591506107756020840161071b565b90509250929050565b60008060008060808587031215610793578182fd5b843593506107a36020860161071b565b92506107b16040860161071b565b915060608501356107c18161092d565b939692955090935050565b60008060008385036101608112156107e2578384fd5b843593506107f26020860161071b565b9250610120603f1982011215610806578182fd5b506040840190509250925092565b6000602080835283518082850152825b8181101561084057858101830151858201604001528201610824565b818111156108515783604083870101525b50601f01601f1916929092016040019392505050565b90815260200190565b6000813561087d8161092d565b92915050565b60ff1981541660ff8315151681178255505050565b6108aa6108a483610870565b82610883565b60208201356001820155604082013560028201556060820135600382015560808201356004820155600581016108e56108a460a08501610870565b6108fa6108f460c08501610870565b82610914565b5060e0820135600682015561010082013560078201555050565b805461ff00191691151560081b61ff0016919091179055565b801515811461093b57600080fd5b5056fea2646970667358221220353fdc1fb374d52d3f01ddc47bc6e63a05da024d85bcd9b13c28061bbf53016264736f6c63430007060033
Deployed ByteCode
0x7308858b5ca8ffc1a28c5645a8839f48641801660d30146080604052600436106100565760003560e01c80632e43d1011461005b578063475522391461007d57806354fd4d501461009057806398a1a85c146100ae575b600080fd5b81801561006757600080fd5b5061007b610076366004610753565b6100ce565b005b61007b61008b36600461077e565b6102a1565b610098610519565b6040516100a59190610867565b60405180910390f35b8180156100ba57600080fd5b5061007b6100c93660046107cc565b61051e565b6001600160a01b0381166000908152600283016020908152604091829020548251808401909352600383526203230360ec1b9183019190915260ff166101305760405162461bcd60e51b81526004016101279190610814565b60405180910390fd5b506001600160a01b0381166000908152600280840160205260409091200154825461015a9161065d565b82556001600160a01b0381166000908152600280840160205260408220805460ff191681556001808201849055918101839055600381018390556004810183905560058101805461ffff191690556006810183905560070182905583015460001901905b8181101561026c57826001600160a01b03168460010182815481106101df57fe5b6000918252602090912001546001600160a01b031614156102645783600101828154811061020957fe5b6000918252602090912001546001850180546001600160a01b03909216918390811061023157fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555061026c565b6001016101be565b508260010180548061027a57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b80156103ab57816001600160a01b0316836001600160a01b031614604051806040016040528060028152602001611a1960f11b815250906102f55760405162461bcd60e51b81526004016101279190610814565b506001600160a01b03831660009081526002808601602090815260409283902054835180850190945291835261343360f01b9083015260ff1661034b5760405162461bcd60e51b81526004016101279190610814565b506001600160a01b038316600090815260028086016020908152604092839020600501548351808501909452918352610d0d60f21b9083015260ff16156103a55760405162461bcd60e51b81526004016101279190610814565b50610513565b6001600160a01b03831660009081526002808601602090815260409283902054835180850190945291835261343360f01b9083015260ff166104005760405162461bcd60e51b81526004016101279190610814565b506001600160a01b038316600090815260028086016020908152604092839020600501548351808501909452918352611a1b60f11b9083015260ff166104595760405162461bcd60e51b81526004016101279190610814565b506001600160a01b03821660009081526002808601602090815260409283902060050154835180850190945291835261343760f01b9083015260ff16156104b35760405162461bcd60e51b81526004016101279190610814565b506001600160a01b03821660009081526002858101602090815260409283902060050154835180850190945291835261068760f31b90830152610100900460ff166105115760405162461bcd60e51b81526004016101279190610814565b505b50505050565b600190565b61052b6020820182610737565b6040518060400160405280600381526020016203230360ec1b815250906105655760405162461bcd60e51b81526004016101279190610814565b50604080518082018252600381526232303160e81b6020820152908201356105a05760405162461bcd60e51b81526004016101279190610814565b506001600160a01b038216600090815260028401602052604090205460ff166105f3576001838101805491820181556000908152602090200180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b03821660009081526002808501602052604082200154845461061b9161065d565b6001600160a01b0384166000908152600286016020526040902090915082906106448282610898565b5061065590508160408401356106ba565b909355505050565b6000828211156106b4576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082820183811015610714576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b80356001600160a01b038116811461073257600080fd5b919050565b600060208284031215610748578081fd5b81356107148161092d565b60008060408385031215610765578081fd5b823591506107756020840161071b565b90509250929050565b60008060008060808587031215610793578182fd5b843593506107a36020860161071b565b92506107b16040860161071b565b915060608501356107c18161092d565b939692955090935050565b60008060008385036101608112156107e2578384fd5b843593506107f26020860161071b565b9250610120603f1982011215610806578182fd5b506040840190509250925092565b6000602080835283518082850152825b8181101561084057858101830151858201604001528201610824565b818111156108515783604083870101525b50601f01601f1916929092016040019392505050565b90815260200190565b6000813561087d8161092d565b92915050565b60ff1981541660ff8315151681178255505050565b6108aa6108a483610870565b82610883565b60208201356001820155604082013560028201556060820135600382015560808201356004820155600581016108e56108a460a08501610870565b6108fa6108f460c08501610870565b82610914565b5060e0820135600682015561010082013560078201555050565b805461ff00191691151560081b61ff0016919091179055565b801515811461093b57600080fd5b5056fea2646970667358221220353fdc1fb374d52d3f01ddc47bc6e63a05da024d85bcd9b13c28061bbf53016264736f6c63430007060033