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
- 2024-06-07T07:00:44.093227Z
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 {
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_TOKEN_NOT_WHITELISTED = "13"; // VaultConfigurator: token not whitelisted
string public constant VC_INVALID_MIN_PROFIT_TIME_COEF_BPS = "16"; // VaultConfigurator: invalid minProfitTimeCoefBps
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 liquidationFeeUsd;
bool hasDynamicFees;
// staking
uint256 stakingBps;
}
struct TokenConfig {
// should always be true if token exists
bool isWhitelisted;
// basic parameters
uint256 decimals;
uint256 weight; // customisation of index composition
uint256 minProfitBps;
uint256 minProfitTime;
bool hasMinProfitTimeFloor;
uint256 minProfitTimeCoefBps; // coefficient for minProfitTime
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 maxGlobalLongSize;
uint256 maxGlobalShortSize;
uint256 maxPositionLongSize;
uint256 maxPositionShortSize;
// fees
uint256 longMarginFeeBps;
uint256 shortMarginFeeBps;
// funding rate
uint256 fundingInterval;
uint256 fundingRateFactor;
}
struct TokenConfigs {
uint256 totalTokenWeights;
address[] allWhitelistedTokens;
mapping(address => TokenConfig) tokenConfigs;
}
struct AccountTokenConfig {
bool isLongBlacklisted;
bool isShortBlacklisted;
uint256 maxPositionLongSizeOverride;
uint256 maxPositionShortSizeOverride;
}
}
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"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
0x610a3c610026600b82828239805160001a60731461001957fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100565760003560e01c80632e43d1011461005b578063475522391461007d57806354fd4d501461009057806398a1a85c146100ae575b600080fd5b81801561006757600080fd5b5061007b61007636600461079f565b6100ce565b005b61007b61008b3660046107ca565b6102ed565b610098610565565b6040516100a591906108b3565b60405180910390f35b8180156100ba57600080fd5b5061007b6100c9366004610818565b61056a565b6001600160a01b0381166000908152600283016020908152604091829020548251808401909352600383526203230360ec1b9183019190915260ff166101305760405162461bcd60e51b81526004016101279190610860565b60405180910390fd5b506001600160a01b0381166000908152600280840160205260409091200154825461015a916106a9565b82556001600160a01b0381166000908152600280840160205260408220805460ff199081168255600180830185905592820184905560038201849055600482018490556005820180549091169055600681018390556007810183905560088101805461ffff1916905560098101839055600a8101839055600b8101839055600c8101839055600d8101839055600e8101839055600f81018390556010810183905560110182905583015460001901905b818110156102b857826001600160a01b031684600101828154811061022b57fe5b6000918252602090912001546001600160a01b031614156102b05783600101828154811061025557fe5b6000918252602090912001546001850180546001600160a01b03909216918390811061027d57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506102b8565b60010161020a565b50826001018054806102c657fe5b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b80156103f757816001600160a01b0316836001600160a01b031614604051806040016040528060028152602001611a1960f11b815250906103415760405162461bcd60e51b81526004016101279190610860565b506001600160a01b03831660009081526002808601602090815260409283902054835180850190945291835261343360f01b9083015260ff166103975760405162461bcd60e51b81526004016101279190610860565b506001600160a01b038316600090815260028086016020908152604092839020600801548351808501909452918352610d0d60f21b9083015260ff16156103f15760405162461bcd60e51b81526004016101279190610860565b5061055f565b6001600160a01b03831660009081526002808601602090815260409283902054835180850190945291835261343360f01b9083015260ff1661044c5760405162461bcd60e51b81526004016101279190610860565b506001600160a01b038316600090815260028086016020908152604092839020600801548351808501909452918352611a1b60f11b9083015260ff166104a55760405162461bcd60e51b81526004016101279190610860565b506001600160a01b03821660009081526002808601602090815260409283902060080154835180850190945291835261343760f01b9083015260ff16156104ff5760405162461bcd60e51b81526004016101279190610860565b506001600160a01b03821660009081526002858101602090815260409283902060080154835180850190945291835261068760f31b90830152610100900460ff1661055d5760405162461bcd60e51b81526004016101279190610860565b505b50505050565b600190565b6105776020820182610783565b6040518060400160405280600381526020016203230360ec1b815250906105b15760405162461bcd60e51b81526004016101279190610860565b50604080518082018252600381526232303160e81b6020820152908201356105ec5760405162461bcd60e51b81526004016101279190610860565b506001600160a01b038216600090815260028401602052604090205460ff1661063f576001838101805491820181556000908152602090200180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b038216600090815260028085016020526040822001548454610667916106a9565b6001600160a01b03841660009081526002860160205260409020909150829061069082826108e4565b506106a19050816040840135610706565b909355505050565b600082821115610700576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082820183811015610760576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b80356001600160a01b038116811461077e57600080fd5b919050565b600060208284031215610794578081fd5b8135610760816109f5565b600080604083850312156107b1578081fd5b823591506107c160208401610767565b90509250929050565b600080600080608085870312156107df578182fd5b843593506107ef60208601610767565b92506107fd60408601610767565b9150606085013561080d816109f5565b939692955090935050565b60008060008385036102a081121561082e578384fd5b8435935061083e60208601610767565b9250610260603f1982011215610852578182fd5b506040840190509250925092565b6000602080835283518082850152825b8181101561088c57858101830151858201604001528201610870565b8181111561089d5783604083870101525b50601f01601f1916929092016040019392505050565b90815260200190565b600081356108c9816109f5565b92915050565b60ff1981541660ff8315151681178255505050565b6108f66108f0836108bc565b826108cf565b6020820135600182015560408201356002820155606082013560038201556080820135600482015561093661092d60a084016108bc565b600583016108cf565b60c0820135600682015560e082013560078201556008810161095e6108f061010085016108bc565b61097461096e61012085016108bc565b826109dc565b506101408201356009820155610160820135600a820155610180820135600b8201556101a0820135600c8201556101c0820135600d8201556101e0820135600e820155610200820135600f820155610220820135601082015561024082013560118201555050565b805461ff00191691151560081b61ff0016919091179055565b8015158114610a0357600080fd5b5056fea26469706673582212205eee9e28644549aee21f32766adf8bf38b755d47d36fab09518cbd8a36815def64736f6c63430007060033
Deployed ByteCode
0x735019828f87706c895c889577cdd272f4a3ac182330146080604052600436106100565760003560e01c80632e43d1011461005b578063475522391461007d57806354fd4d501461009057806398a1a85c146100ae575b600080fd5b81801561006757600080fd5b5061007b61007636600461079f565b6100ce565b005b61007b61008b3660046107ca565b6102ed565b610098610565565b6040516100a591906108b3565b60405180910390f35b8180156100ba57600080fd5b5061007b6100c9366004610818565b61056a565b6001600160a01b0381166000908152600283016020908152604091829020548251808401909352600383526203230360ec1b9183019190915260ff166101305760405162461bcd60e51b81526004016101279190610860565b60405180910390fd5b506001600160a01b0381166000908152600280840160205260409091200154825461015a916106a9565b82556001600160a01b0381166000908152600280840160205260408220805460ff199081168255600180830185905592820184905560038201849055600482018490556005820180549091169055600681018390556007810183905560088101805461ffff1916905560098101839055600a8101839055600b8101839055600c8101839055600d8101839055600e8101839055600f81018390556010810183905560110182905583015460001901905b818110156102b857826001600160a01b031684600101828154811061022b57fe5b6000918252602090912001546001600160a01b031614156102b05783600101828154811061025557fe5b6000918252602090912001546001850180546001600160a01b03909216918390811061027d57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506102b8565b60010161020a565b50826001018054806102c657fe5b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b80156103f757816001600160a01b0316836001600160a01b031614604051806040016040528060028152602001611a1960f11b815250906103415760405162461bcd60e51b81526004016101279190610860565b506001600160a01b03831660009081526002808601602090815260409283902054835180850190945291835261343360f01b9083015260ff166103975760405162461bcd60e51b81526004016101279190610860565b506001600160a01b038316600090815260028086016020908152604092839020600801548351808501909452918352610d0d60f21b9083015260ff16156103f15760405162461bcd60e51b81526004016101279190610860565b5061055f565b6001600160a01b03831660009081526002808601602090815260409283902054835180850190945291835261343360f01b9083015260ff1661044c5760405162461bcd60e51b81526004016101279190610860565b506001600160a01b038316600090815260028086016020908152604092839020600801548351808501909452918352611a1b60f11b9083015260ff166104a55760405162461bcd60e51b81526004016101279190610860565b506001600160a01b03821660009081526002808601602090815260409283902060080154835180850190945291835261343760f01b9083015260ff16156104ff5760405162461bcd60e51b81526004016101279190610860565b506001600160a01b03821660009081526002858101602090815260409283902060080154835180850190945291835261068760f31b90830152610100900460ff1661055d5760405162461bcd60e51b81526004016101279190610860565b505b50505050565b600190565b6105776020820182610783565b6040518060400160405280600381526020016203230360ec1b815250906105b15760405162461bcd60e51b81526004016101279190610860565b50604080518082018252600381526232303160e81b6020820152908201356105ec5760405162461bcd60e51b81526004016101279190610860565b506001600160a01b038216600090815260028401602052604090205460ff1661063f576001838101805491820181556000908152602090200180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b038216600090815260028085016020526040822001548454610667916106a9565b6001600160a01b03841660009081526002860160205260409020909150829061069082826108e4565b506106a19050816040840135610706565b909355505050565b600082821115610700576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082820183811015610760576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b80356001600160a01b038116811461077e57600080fd5b919050565b600060208284031215610794578081fd5b8135610760816109f5565b600080604083850312156107b1578081fd5b823591506107c160208401610767565b90509250929050565b600080600080608085870312156107df578182fd5b843593506107ef60208601610767565b92506107fd60408601610767565b9150606085013561080d816109f5565b939692955090935050565b60008060008385036102a081121561082e578384fd5b8435935061083e60208601610767565b9250610260603f1982011215610852578182fd5b506040840190509250925092565b6000602080835283518082850152825b8181101561088c57858101830151858201604001528201610870565b8181111561089d5783604083870101525b50601f01601f1916929092016040019392505050565b90815260200190565b600081356108c9816109f5565b92915050565b60ff1981541660ff8315151681178255505050565b6108f66108f0836108bc565b826108cf565b6020820135600182015560408201356002820155606082013560038201556080820135600482015561093661092d60a084016108bc565b600583016108cf565b60c0820135600682015560e082013560078201556008810161095e6108f061010085016108bc565b61097461096e61012085016108bc565b826109dc565b506101408201356009820155610160820135600a820155610180820135600b8201556101a0820135600c8201556101c0820135600d8201556101e0820135600e820155610200820135600f820155610220820135601082015561024082013560118201555050565b805461ff00191691151560081b61ff0016919091179055565b8015158114610a0357600080fd5b5056fea26469706673582212205eee9e28644549aee21f32766adf8bf38b755d47d36fab09518cbd8a36815def64736f6c63430007060033