Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
OriginStrategy
Compiler Version
v0.8.10+commit.fc410830
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2023-08-10
*/
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;
/// @title Interface an aggregator needs to adhere.
interface IAggregatorV3Interface {
/// @notice decimals used by the aggregator
function decimals() external view returns (uint8);
/// @notice aggregator's description
function description() external view returns (string memory);
/// @notice aggregator's version
function version() external view returns (uint256);
// getRoundData and latestRoundData should both raise "No data present"
// if they do not have data to report, instead of returning unset values
// which could be misinterpreted as actual reported values.
/// @notice get's round data for requested id
function getRoundData(
uint80 id
)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
/// @notice get's latest round data
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
/**
* @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 amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* ////IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [////IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* ////IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* ////IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
library OracleMath {
function process(
address oracle,
uint256 twapTimeInterval,
uint8 tokenDecimals,
uint256 tokenAmount
) internal view returns (uint256 usdValue) {
IAggregatorV3Interface chainlink = IAggregatorV3Interface(oracle);
(uint80 roundId, int256 price,,,) = chainlink.latestRoundData();
uint256 oracleDecimals = chainlink.decimals();
int256 finalPriceInt = twapTimeInterval == 0
? price
: getTwapPrice(chainlink, roundId, price, twapTimeInterval);
uint256 finalPrice;
if (oracleDecimals > tokenDecimals) {
finalPrice = uint256(finalPriceInt) / 10**(oracleDecimals - tokenDecimals);
} else if (oracleDecimals < tokenDecimals) {
finalPrice = uint256(finalPriceInt) * 10**(tokenDecimals - oracleDecimals);
} else {
finalPrice = uint256(finalPriceInt);
}
// Adjust usdValue to have 18 decimal places
usdValue = (tokenAmount * finalPrice * 10**(18 - tokenDecimals)) / (10**tokenDecimals);
return usdValue;
}
function getPrice(
address oracle,
uint8 tokenDecimals
) internal view returns (uint256 finalPrice) {
IAggregatorV3Interface chainlink = IAggregatorV3Interface(oracle);
(, int256 price,,,) = chainlink.latestRoundData();
uint256 oracleDecimals = chainlink.decimals();
if (oracleDecimals > tokenDecimals) {
finalPrice = uint256(price) / 10**(oracleDecimals - tokenDecimals);
} else if (oracleDecimals < tokenDecimals) {
finalPrice = uint256(price) * 10**(tokenDecimals - oracleDecimals);
} else {
finalPrice = uint256(price);
}
}
function getTwapPrice(
IAggregatorV3Interface chainlink,
uint80 latestRoundId,
int256 latestPrice,
uint256 twapTimeInterval
) internal view returns (int256 price) {
int256 priceSum = latestPrice;
uint256 priceCount = 1;
uint256 startTime = block.timestamp - twapTimeInterval;
while (latestRoundId > 0) {
try chainlink.getRoundData(--latestRoundId) returns (
uint80,
int256 answer,
uint256,
uint256 updatedAt,
uint80
) {
if (updatedAt < startTime) {
break;
}
priceSum += answer;
priceCount++;
} catch {
break;
}
}
return priceSum / int256(priceCount);
}
}
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
interface IParaSwapAugustus {
function getTokenTransferProxy() external view returns (address);
}
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
interface IOracleRegistry{
function getSupportedOracle(address) external view returns (address);
}
interface ITokenRegistry {
function getSupportedToken(address) external view returns (bool);
}
abstract contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner == msg.sender, "not owner");
_;
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) external virtual onlyOwner {
require(newOwner != address(0), '0 address');
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
/**
* @notice FractBaseStrategy should be inherited by new strategies.
*/
abstract contract FractBaseStrategy is Ownable, ReentrancyGuard {
using SafeERC20 for IERC20;
/*///////////////////////////////////////////////////////////////
Constants and Immutables
//////////////////////////////////////////////////////////////*/
address constant PARASWAP = 0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57;
address constant NATIVE_ASSET = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
uint256 constant BIPS_DIVISOR = uint256(10000);
uint256 constant ONE_ETHER = uint256(10 ** 18);
/*///////////////////////////////////////////////////////////////
Constructor
//////////////////////////////////////////////////////////////*/
/**
* @dev Initializes the contract setting the deployer as the operator.
*/
constructor() {
_operator = msg.sender;
}
/*///////////////////////////////////////////////////////////////
Receive
//////////////////////////////////////////////////////////////*/
receive() external payable {}
/*///////////////////////////////////////////////////////////////
State Variables
//////////////////////////////////////////////////////////////*/
//slot1
address internal _operator;
//slot2
address internal _oracleRegistry;
//slot3
address internal _tokenRegistry;
/*///////////////////////////////////////////////////////////////
Mappings
//////////////////////////////////////////////////////////////*/
//Map of token and its deployed amounts
mapping(address => PositionParams[]) internal tokenDeployedAmounts;
//Map of token and its withdrawn amounts
mapping(address => PositionParams[]) internal tokenWithdrawalAmounts;
/*///////////////////////////////////////////////////////////////
Structs
//////////////////////////////////////////////////////////////*/
/**
* @notice Position Params.
* @param amount The amount of token deployed into a position.
* @param price The price of the token at time of deployment into a position.
* @param time The time of deployment into the position.
*/
struct PositionParams {
uint256 amount;
uint256 price;
uint256 time;
}
/*///////////////////////////////////////////////////////////////
Events
//////////////////////////////////////////////////////////////*/
event DepositETH(address account, uint256 amount);
event Deposit(address indexed account, uint256 amount);
event Withdraw(address indexed account, uint256 amount);
event WithdrawETH(address account, uint256 amount);
event WithdrawToOwner(IERC20 token, uint256 amount);
event SetOracleRegistry(address oracleRegistry);
event SetTokenRegistry(address tokenRegistry);
/*///////////////////////////////////////////////////////////////
Modifiers
//////////////////////////////////////////////////////////////*/
/**
* @notice Only called by operator
*/
modifier onlyOperator() {
require(msg.sender == _operator, "Only Operator");
_;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwnerOrOperator() {
require(msg.sender == owner || msg.sender == _operator, "not owner or operator");
_;
}
/*///////////////////////////////////////////////////////////////
Setters
//////////////////////////////////////////////////////////////*/
/**
* @notice Sets the operator address
* @param operatorAddr Specifies the address of the poolContract.
*/
function setOperator(address operatorAddr) external nonReentrant onlyOwner {
_operator = operatorAddr;
}
/**
* @notice Sets the oracle registry address
* @param oracleRegistryAddr Specifies the address of the oracle registry.
*/
function setOracleRegistry(address oracleRegistryAddr) external nonReentrant onlyOwner {
_oracleRegistry = oracleRegistryAddr;
emit SetOracleRegistry(_oracleRegistry);
}
/**
* @notice Sets the oracle registry address
* @param tokenRegistryAddr Specifies the address of the oracle registry.
*/
function setTokenRegistry(address tokenRegistryAddr) external nonReentrant onlyOwner {
_tokenRegistry = tokenRegistryAddr;
emit SetTokenRegistry(_tokenRegistry);
}
/*///////////////////////////////////////////////////////////////
Base Operations
//////////////////////////////////////////////////////////////*/
/**
* @notice Log a deposit or withdrawal into the strategy contract.
* @param token token to deposit or withdrawal.
* @param amount amount of tokens to deposit or withdraw.
*/
function _logPosition(address token, uint256 amount) internal view returns (PositionParams memory positionParams) {
uint8 decimals = (token == NATIVE_ASSET) ? 18 : IERC20Metadata(token).decimals();
uint256 price =
OracleMath.getPrice(IOracleRegistry(_oracleRegistry).getSupportedOracle(address(token)), decimals);
positionParams.amount = amount;
positionParams.time = block.timestamp;
positionParams.price = price;
return positionParams;
}
/**
* @notice Deposit into the strategy
* @param token token to deposit.
* @param amount amount of tokens to deposit.
*/
function _deposit(IERC20 token, uint256 amount) internal {
token.safeTransferFrom(msg.sender, address(this), amount);
PositionParams memory deployedAmount = _logPosition(address(token), amount);
tokenDeployedAmounts[address(token)].push(deployedAmount); // Store the deposit information
emit Deposit(msg.sender, amount);
}
/**
* @notice Withdraw from the strategy
* @param token token to withdraw.
* @param amount amount of tokens to withdraw.
*/
function _withdraw(IERC20 token, uint256 amount) internal {
token.safeTransfer(msg.sender, amount);
PositionParams memory withdrawnAmount = _logPosition(address(token), amount);
tokenWithdrawalAmounts[address(token)].push(withdrawnAmount); // Store the withdrawal information
emit Withdraw(msg.sender, amount);
}
/**
* @notice Withdraw from the strategy to the owner.
* @param token token to withdraw.
* @param amount amount of tokens to withdraw.
*/
function _withdrawToOwner(IERC20 token, uint256 amount) internal {
token.safeTransfer(owner, amount);
PositionParams memory withdrawnAmount = _logPosition(address(token), amount);
tokenWithdrawalAmounts[address(token)].push(withdrawnAmount); // Store the withdrawal information
emit WithdrawToOwner(token, amount);
}
/**
* @notice Swap rewards via the paraswap router.
* @param srcToken The token to swap.
* @param destToken The token to receive.
* @param srcAmount The amount of tokens to swap.
* @param minDestAmountOut The minimum amount of tokens out we expect to receive.
* @param callData The callData to pass to the paraswap router. Generated offchain.
*/
function _swap(
IERC20 srcToken,
IERC20 destToken,
uint256 srcAmount,
uint256 minDestAmountOut,
bytes memory callData
) internal {
require(ITokenRegistry(_tokenRegistry).getSupportedToken(address(srcToken)), "invalid token");
require(ITokenRegistry(_tokenRegistry).getSupportedToken(address(destToken)), "invalid token");
address tokenTransferProxy = IParaSwapAugustus(PARASWAP).getTokenTransferProxy();
uint256 destTokenBalanceBefore = destToken.balanceOf(address(this));
srcToken.safeApprove(tokenTransferProxy, srcAmount);
(bool success,) = PARASWAP.call(callData);
require(success, "swap failed");
uint256 destTokenBalanceAfter = destToken.balanceOf(address(this));
require(destTokenBalanceAfter - destTokenBalanceBefore >= minDestAmountOut, "slippage check");
srcToken.safeApprove(tokenTransferProxy, 0);
}
/*///////////////////////////////////////////////////////////////
ETH Operations
//////////////////////////////////////////////////////////////*/
/**
* @notice Depost ETH into the contract
*/
function depositETH() external payable nonReentrant onlyOwnerOrOperator {
PositionParams memory deployedAmount = _logPosition(NATIVE_ASSET, msg.value);
tokenDeployedAmounts[NATIVE_ASSET].push(deployedAmount); // Store the deposit information
emit DepositETH(msg.sender, msg.value);
}
/**
* @notice Withdraw eth locked in contract back to owner
* @param amount amount of eth to send.
*/
function withdrawETH(uint256 amount) external nonReentrant onlyOwnerOrOperator {
PositionParams memory withdrawnAmount = _logPosition(NATIVE_ASSET, amount);
tokenWithdrawalAmounts[NATIVE_ASSET].push(withdrawnAmount); // Store the withdrawal information
payable(msg.sender).transfer(amount);
emit WithdrawETH(msg.sender, amount);
}
/*///////////////////////////////////////////////////////////////
Getters
//////////////////////////////////////////////////////////////*/
/**
* @notice Get array of token deployments.
* @param token token address.
* @dev pass NATIVE_ASSET to return ETH deployments.
*/
function getTokenDeployedAmounts(address token) external view returns (PositionParams[] memory)
{
return tokenDeployedAmounts[token];
}
/**
* @notice Get array of token withdrawals.
* @param token token address.
* @dev pass NATIVE_ASSET to return ETH withdrawals.
*/
function getTokenWithdrawalAmounts(address token) external view returns (PositionParams[] memory)
{
return tokenWithdrawalAmounts[token];
}
}
interface IOriginRewardsSource {
/// @notice Collect rewards.
///
/// Can only be called by the contract that will receive the rewards.
///
/// @return rewards OGV collected
function collectRewards() external returns (uint256);
/// @notice Preview the amount of rewards that would be returned if rewards
/// were collected now.
///
/// @return rewards OGV that would be collected
function previewRewards() external view returns (uint256);
}
interface IOriginRewardsHarvester {
/**
* @dev Collect reward tokens for a specific strategy and swap for supported
* stablecoin via Uniswap. Can be called by anyone. Rewards incentivizing
* the caller are sent to the caller of this function.
* @param _strategyAddr Address of the strategy to collect rewards from
*/
function harvestAndSwap(address _strategyAddr) external;
}
interface IOrigin {
function rebaseOptIn() external;
function rebaseOptOut() external;
function rebaseState(address addr) external view returns (uint8);
}
contract OriginStrategy is FractBaseStrategy {
address public constant OUSD_ADDRESS = address(0x2A8e1E676Ec238d8A992307B495b45B3fEAa5e86);
address public constant OETH_ADDRESS = address(0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3);
address public constant OUSD_HARVESTER = address(0x21Fb5812D70B3396880D30e90D9e5C1202266c89);
address public constant OETH_HARVESTER = address(0x0D017aFA83EAce9F10A8EC5B6E13941664A6785C);
address public constant OGV_REWARDS_SOURCE = address(0x7d82E86CF1496f9485a8ea04012afeb3C7489397);
using SafeERC20 for IERC20;
function deposit(IERC20 token, uint256 amount) external nonReentrant onlyOwner {
_deposit(token, amount);
}
function withdraw(IERC20 token, uint256 amount) external nonReentrant onlyOwnerOrOperator {
_withdraw(token, amount);
}
function withdrawToOwner(IERC20 token, uint256 amount) external nonReentrant onlyOwner {
_withdrawToOwner(token, amount);
}
function rebaseOptInUsd() external nonReentrant onlyOwnerOrOperator {
IOrigin(OUSD_ADDRESS).rebaseOptIn();
}
function rebaseOptInEth() external nonReentrant onlyOwnerOrOperator {
IOrigin(OETH_ADDRESS).rebaseOptIn();
}
function rebaseOptOutUsd() external nonReentrant onlyOwnerOrOperator {
IOrigin(OUSD_ADDRESS).rebaseOptOut();
}
function rebaseOptOutEth() external nonReentrant onlyOwnerOrOperator {
IOrigin(OETH_ADDRESS).rebaseOptOut();
}
function swap(IERC20 srcToken, IERC20 destToken, uint256 srcAmount, uint256 minDestAmountOut, bytes memory callData) external payable nonReentrant onlyOperator {
_swap(srcToken, destToken, srcAmount, minDestAmountOut, callData);
}
function computeRewardsUsdForEveryone(address strategyAddr) external nonReentrant onlyOwnerOrOperator {
IOriginRewardsHarvester(OUSD_HARVESTER).harvestAndSwap(strategyAddr);
}
function computeRewardsEthForEveryone(address strategyAddr) external nonReentrant onlyOwnerOrOperator {
IOriginRewardsHarvester(OETH_HARVESTER).harvestAndSwap(strategyAddr);
}
function collectRewards() external nonReentrant onlyOwnerOrOperator returns (uint256) {
return IOriginRewardsSource(OGV_REWARDS_SOURCE).collectRewards();
}
function previewRewards() external view returns (uint256) {
return IOriginRewardsSource(OGV_REWARDS_SOURCE).previewRewards();
}
function getCurrentRebaseStateUsd() external view returns (uint8) {
return IOrigin(OUSD_ADDRESS).rebaseState(address(this));
}
function getCurrentRebaseStateEth() external view returns (uint8) {
return IOrigin(OETH_ADDRESS).rebaseState(address(this));
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositETH","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oracleRegistry","type":"address"}],"name":"SetOracleRegistry","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenRegistry","type":"address"}],"name":"SetTokenRegistry","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawETH","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawToOwner","type":"event"},{"inputs":[],"name":"OETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OETH_HARVESTER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OGV_REWARDS_SOURCE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OUSD_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OUSD_HARVESTER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collectRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategyAddr","type":"address"}],"name":"computeRewardsEthForEveryone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategyAddr","type":"address"}],"name":"computeRewardsUsdForEveryone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getCurrentRebaseStateEth","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentRebaseStateUsd","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getTokenDeployedAmounts","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"time","type":"uint256"}],"internalType":"struct FractBaseStrategy.PositionParams[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getTokenWithdrawalAmounts","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"time","type":"uint256"}],"internalType":"struct FractBaseStrategy.PositionParams[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"previewRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebaseOptInEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebaseOptInUsd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebaseOptOutEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebaseOptOutUsd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operatorAddr","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oracleRegistryAddr","type":"address"}],"name":"setOracleRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenRegistryAddr","type":"address"}],"name":"setTokenRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"srcToken","type":"address"},{"internalType":"contract IERC20","name":"destToken","type":"address"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"minDestAmountOut","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"name":"swap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawToOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
608060405234801561001057600080fd5b5060008054336001600160a01b031991821681178355600180556002805490921617905561246c90819061004490396000f3fe6080604052600436106101bb5760003560e01c80638165354e116100ec578063e443a4831161008a578063f14210a611610064578063f14210a6146104d6578063f2fde38b146104f6578063f3fef3a314610516578063f6326fb31461053657600080fd5b8063e443a48314610479578063e8b964bc14610499578063ef518a4b146104ae57600080fd5b8063b3ab15fb116100c6578063b3ab15fb14610407578063ceb73b7f14610427578063d54021ae1461044f578063e0d801dd1461046457600080fd5b80638165354e146103a75780638da5cb5b146103c757806397ea951a146103e757600080fd5b806347c62a0d1161015957806354453b1d1161013357806354453b1d1461033257806366c990111461034757806370bb45b31461036f5780637c91d9241461039257600080fd5b806347c62a0d146102dd57806347e7ef24146102fd578063495d77441461031d57600080fd5b806322fdd1951161019557806322fdd195146102615780632506c018146102885780632d6b8e7e1461029d57806335a5af92146102bd57600080fd5b806306eff2fb146101c7578063123b2a401461020c578063175f1c601461023457600080fd5b366101c257005b600080fd5b3480156101d357600080fd5b506101ef732a8e1e676ec238d8a992307b495b45b3feaa5e8681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021857600080fd5b506101ef73856c4efb76c1d1ae02e20ceb03a2a6a08b0b8dc381565b34801561024057600080fd5b5061025461024f366004611f5f565b61053e565b6040516102039190611f83565b34801561026d57600080fd5b506102766105d1565b60405160ff9091168152602001610203565b61029b610296366004611ff2565b61064d565b005b3480156102a957600080fd5b5061029b6102b8366004611f5f565b6106c1565b3480156102c957600080fd5b5061029b6102d8366004611f5f565b610782565b3480156102e957600080fd5b5061029b6102f83660046120dc565b61080f565b34801561030957600080fd5b5061029b6103183660046120dc565b610858565b34801561032957600080fd5b5061029b610894565b34801561033e57600080fd5b5061029b61094d565b34801561035357600080fd5b506101ef7321fb5812d70b3396880d30e90d9e5c1202266c8981565b34801561037b57600080fd5b506103846109e3565b604051908152602001610203565b34801561039e57600080fd5b5061029b610ab2565b3480156103b357600080fd5b5061029b6103c2366004611f5f565b610b48565b3480156103d357600080fd5b506000546101ef906001600160a01b031681565b3480156103f357600080fd5b5061029b610402366004611f5f565b610bc8565b34801561041357600080fd5b5061029b610422366004611f5f565b610c4f565b34801561043357600080fd5b506101ef737d82e86cf1496f9485a8ea04012afeb3c748939781565b34801561045b57600080fd5b5061029b610ca3565b34801561047057600080fd5b50610384610d39565b34801561048557600080fd5b50610254610494366004611f5f565b610db1565b3480156104a557600080fd5b50610276610e36565b3480156104ba57600080fd5b506101ef730d017afa83eace9f10a8ec5b6e13941664a6785c81565b3480156104e257600080fd5b5061029b6104f1366004612108565b610e70565b34801561050257600080fd5b5061029b610511366004611f5f565b611000565b34801561052257600080fd5b5061029b6105313660046120dc565b6110c7565b61029b611118565b6001600160a01b0381166000908152600560209081526040808320805482518185028101850190935280835260609492939192909184015b828210156105c65783829060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505081526020019060010190610576565b505050509050919050565b6040516322b7714360e11b815230600482015260009073856c4efb76c1d1ae02e20ceb03a2a6a08b0b8dc39063456ee286906024015b602060405180830381865afa158015610624573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106489190612121565b905090565b61065561127c565b6002546001600160a01b031633146106a45760405162461bcd60e51b815260206004820152600d60248201526c27b7363c9027b832b930ba37b960991b60448201526064015b60405180910390fd5b6106b185858585856112d6565b6106ba60018055565b5050505050565b6106c961127c565b6000546001600160a01b03163314806106ec57506002546001600160a01b031633145b6107085760405162461bcd60e51b815260040161069b90612144565b60405163548f5ae560e01b81526001600160a01b0382166004820152730d017afa83eace9f10a8ec5b6e13941664a6785c9063548f5ae5906024015b600060405180830381600087803b15801561075e57600080fd5b505af1158015610772573d6000803e3d6000fd5b5050505061077f60018055565b50565b61078a61127c565b6000546001600160a01b031633146107b45760405162461bcd60e51b815260040161069b90612173565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f7f221725f2e949e8562bdbb6a6a90a4cc22b96336ba50962357bf3a27dcb4755906020015b60405180910390a161077f60018055565b61081761127c565b6000546001600160a01b031633146108415760405162461bcd60e51b815260040161069b90612173565b61084b82826116b0565b61085460018055565b5050565b61086061127c565b6000546001600160a01b0316331461088a5760405162461bcd60e51b815260040161069b90612173565b61084b828261175e565b61089c61127c565b6000546001600160a01b03163314806108bf57506002546001600160a01b031633145b6108db5760405162461bcd60e51b815260040161069b90612144565b73856c4efb76c1d1ae02e20ceb03a2a6a08b0b8dc36001600160a01b031663c2376dff6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561092a57600080fd5b505af115801561093e573d6000803e3d6000fd5b5050505061094b60018055565b565b61095561127c565b6000546001600160a01b031633148061097857506002546001600160a01b031633145b6109945760405162461bcd60e51b815260040161069b90612144565b73856c4efb76c1d1ae02e20ceb03a2a6a08b0b8dc36001600160a01b031663f51b0fd46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561092a57600080fd5b60006109ed61127c565b6000546001600160a01b0316331480610a1057506002546001600160a01b031633145b610a2c5760405162461bcd60e51b815260040161069b90612144565b737d82e86cf1496f9485a8ea04012afeb3c74893976001600160a01b03166370bb45b36040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610a80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa49190612196565b9050610aaf60018055565b90565b610aba61127c565b6000546001600160a01b0316331480610add57506002546001600160a01b031633145b610af95760405162461bcd60e51b815260040161069b90612144565b732a8e1e676ec238d8a992307b495b45b3feaa5e866001600160a01b031663f51b0fd46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561092a57600080fd5b610b5061127c565b6000546001600160a01b03163314610b7a5760405162461bcd60e51b815260040161069b90612173565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527fd7eea7f547123e0693ad16e2016adde5c4b263f3449dc5e8632ef3463aa3e1e1906020016107fe565b610bd061127c565b6000546001600160a01b0316331480610bf357506002546001600160a01b031633145b610c0f5760405162461bcd60e51b815260040161069b90612144565b60405163548f5ae560e01b81526001600160a01b03821660048201527321fb5812d70b3396880d30e90d9e5c1202266c899063548f5ae590602401610744565b610c5761127c565b6000546001600160a01b03163314610c815760405162461bcd60e51b815260040161069b90612173565b600280546001600160a01b0319166001600160a01b0383161790556001805550565b610cab61127c565b6000546001600160a01b0316331480610cce57506002546001600160a01b031633145b610cea5760405162461bcd60e51b815260040161069b90612144565b732a8e1e676ec238d8a992307b495b45b3feaa5e866001600160a01b031663c2376dff6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561092a57600080fd5b6000737d82e86cf1496f9485a8ea04012afeb3c74893976001600160a01b031663e0d801dd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d8d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106489190612196565b6001600160a01b03811660009081526006602090815260408083208054825181850281018501909352808352606094929391929091840182156105c65783829060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505081526020019060010190610576565b6040516322b7714360e11b8152306004820152600090732a8e1e676ec238d8a992307b495b45b3feaa5e869063456ee28690602401610607565b610e7861127c565b6000546001600160a01b0316331480610e9b57506002546001600160a01b031633145b610eb75760405162461bcd60e51b815260040161069b90612144565b6000610ed773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee83611805565b600660209081527fa2e5aefc6e2cbe2917a296f0fd89c5f915c487c803db1d98eccb43f14012d7118054600181018255600091825283517f88ec43c8aeea0158611154a0f26516f4128e25817fb653416dd76295041a8377600390920291820155918301517f88ec43c8aeea0158611154a0f26516f4128e25817fb653416dd76295041a83788301556040808401517f88ec43c8aeea0158611154a0f26516f4128e25817fb653416dd76295041a837990930192909255905191925033916108fc85150291859190818181858888f19350505050158015610fbc573d6000803e3d6000fd5b5060408051338152602081018490527f566e45b1c8057e725bf62796a7f1d37ae294393cab069725a09daddd1af98b79910160405180910390a15061077f60018055565b6000546001600160a01b0316331461102a5760405162461bcd60e51b815260040161069b90612173565b6001600160a01b03811661106c5760405162461bcd60e51b815260206004820152600960248201526830206164647265737360b81b604482015260640161069b565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6110cf61127c565b6000546001600160a01b03163314806110f257506002546001600160a01b031633145b61110e5760405162461bcd60e51b815260040161069b90612144565b61084b828261194c565b61112061127c565b6000546001600160a01b031633148061114357506002546001600160a01b031633145b61115f5760405162461bcd60e51b815260040161069b90612144565b600061117f73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34611805565b600560209081527fa1829a9003092132f585b6ccdd167c19fe9774dbdea4260287e8a8e8ca8185d7805460018101825560009190915282517f3134d172b0d7dc56c5e2ded6d8c21c8fca286b81b4ff3ea5fa839f5b1d69f74f600390920291820155828201517f3134d172b0d7dc56c5e2ded6d8c21c8fca286b81b4ff3ea5fa839f5b1d69f7508201556040808401517f3134d172b0d7dc56c5e2ded6d8c21c8fca286b81b4ff3ea5fa839f5b1d69f75190920191909155805133815234928101929092529192507fced5d8bf10823804603bba066e4f53aa6e8f6f4be68bf0114cf7a0e52183e4e9910160405180910390a15061094b60018055565b600260015414156112cf5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161069b565b6002600155565b600480546040516327526a0360e01b81526001600160a01b03888116938201939093529116906327526a0390602401602060405180830381865afa158015611322573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134691906121af565b6113825760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640161069b565b600480546040516327526a0360e01b81526001600160a01b03878116938201939093529116906327526a0390602401602060405180830381865afa1580156113ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f291906121af565b61142e5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640161069b565b600073def171fe48cf0115b1d80b88dc8eab59176fee576001600160a01b031663d2c4b5986040518163ffffffff1660e01b8152600401602060405180830381865afa158015611482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a691906121d1565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038716906370a0823190602401602060405180830381865afa1580156114f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115149190612196565b905061152a6001600160a01b03881683876119e9565b600073def171fe48cf0115b1d80b88dc8eab59176fee576001600160a01b031684604051611558919061221a565b6000604051808303816000865af19150503d8060008114611595576040519150601f19603f3d011682016040523d82523d6000602084013e61159a565b606091505b50509050806115d95760405162461bcd60e51b815260206004820152600b60248201526a1cddd85c0819985a5b195960aa1b604482015260640161069b565b6040516370a0823160e01b81523060048201526000906001600160a01b038916906370a0823190602401602060405180830381865afa158015611620573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116449190612196565b905085611651848361224c565b10156116905760405162461bcd60e51b815260206004820152600e60248201526d736c69707061676520636865636b60901b604482015260640161069b565b6116a56001600160a01b038a168560006119e9565b505050505050505050565b6000546116ca906001600160a01b03848116911683611b36565b60006116d68383611805565b6001600160a01b0384166000818152600660209081526040808320805460018082018355918552938390208651600390950201938455858301519084015584810151600290930192909255815192835282018590529192507f5324e5ca3eab399efb9cff88b357827404aac06c9bebbd13d81f095576581988910160405180910390a1505050565b6117736001600160a01b038316333084611b66565b600061177f8383611805565b6001600160a01b0384166000908152600560209081526040808320805460018082018355918552938390208551600390950201938455848301519084015583810151600290930192909255905184815291925033917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c91015b60405180910390a2505050565b61182960405180606001604052806000815260200160008152602001600081525090565b60006001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146118b657836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561188d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b19190612121565b6118b9565b60125b600354604051636d9af31360e01b81526001600160a01b038781166004830152929350600092611935921690636d9af31390602401602060405180830381865afa15801561190b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192f91906121d1565b83611ba4565b848452426040850152602084015250505b92915050565b6119606001600160a01b0383163383611b36565b600061196c8383611805565b6001600160a01b0384166000908152600660209081526040808320805460018082018355918552938390208551600390950201938455848301519084015583810151600290930192909255905184815291925033917f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436491016117f8565b801580611a635750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611a3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a619190612196565b155b611ace5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161069b565b6040516001600160a01b038316602482015260448101829052611b3190849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611ceb565b505050565b6040516001600160a01b038316602482015260448101829052611b3190849063a9059cbb60e01b90606401611afa565b6040516001600160a01b0380851660248301528316604482015260648101829052611b9e9085906323b872dd60e01b90608401611afa565b50505050565b6000808390506000816001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611bea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0e9190612282565b5050509150506000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c789190612121565b60ff1690508460ff16811115611cb157611c9560ff86168261224c565b611ca090600a6123b6565b611caa90836123c2565b9350611ce2565b8460ff16811015611cde57611cc98160ff871661224c565b611cd490600a6123b6565b611caa90836123e4565b8193505b50505092915050565b6000611d40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611dbd9092919063ffffffff16565b805190915015611b315780806020019051810190611d5e91906121af565b611b315760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161069b565b6060611dcc8484600085611dd4565b949350505050565b606082471015611e355760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161069b565b600080866001600160a01b03168587604051611e51919061221a565b60006040518083038185875af1925050503d8060008114611e8e576040519150601f19603f3d011682016040523d82523d6000602084013e611e93565b606091505b5091509150611ea487838387611eaf565b979650505050505050565b60608315611f1b578251611f14576001600160a01b0385163b611f145760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161069b565b5081611dcc565b611dcc8383815115611f305781518083602001fd5b8060405162461bcd60e51b815260040161069b9190612403565b6001600160a01b038116811461077f57600080fd5b600060208284031215611f7157600080fd5b8135611f7c81611f4a565b9392505050565b602080825282518282018190526000919060409081850190868401855b82811015611fcf5781518051855286810151878601528501518585015260609093019290850190600101611fa0565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b600080600080600060a0868803121561200a57600080fd5b853561201581611f4a565b9450602086013561202581611f4a565b93506040860135925060608601359150608086013567ffffffffffffffff8082111561205057600080fd5b818801915088601f83011261206457600080fd5b81358181111561207657612076611fdc565b604051601f8201601f19908116603f0116810190838211818310171561209e5761209e611fdc565b816040528281528b60208487010111156120b757600080fd5b8260208601602083013760006020848301015280955050505050509295509295909350565b600080604083850312156120ef57600080fd5b82356120fa81611f4a565b946020939093013593505050565b60006020828403121561211a57600080fd5b5035919050565b60006020828403121561213357600080fd5b815160ff81168114611f7c57600080fd5b6020808252601590820152743737ba1037bbb732b91037b91037b832b930ba37b960591b604082015260600190565b6020808252600990820152683737ba1037bbb732b960b91b604082015260600190565b6000602082840312156121a857600080fd5b5051919050565b6000602082840312156121c157600080fd5b81518015158114611f7c57600080fd5b6000602082840312156121e357600080fd5b8151611f7c81611f4a565b60005b838110156122095781810151838201526020016121f1565b83811115611b9e5750506000910152565b6000825161222c8184602087016121ee565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b60008282101561225e5761225e612236565b500390565b805169ffffffffffffffffffff8116811461227d57600080fd5b919050565b600080600080600060a0868803121561229a57600080fd5b6122a386612263565b94506020860151935060408601519250606086015191506122c660808701612263565b90509295509295909350565b600181815b8085111561230d5781600019048211156122f3576122f3612236565b8085161561230057918102915b93841c93908002906122d7565b509250929050565b60008261232457506001611946565b8161233157506000611946565b816001811461234757600281146123515761236d565b6001915050611946565b60ff84111561236257612362612236565b50506001821b611946565b5060208310610133831016604e8410600b8410161715612390575081810a611946565b61239a83836122d2565b80600019048211156123ae576123ae612236565b029392505050565b6000611f7c8383612315565b6000826123df57634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156123fe576123fe612236565b500290565b60208152600082518060208401526124228160408501602087016121ee565b601f01601f1916919091016040019291505056fea26469706673582212200456f7c54fa809855685cea1d5774c3937ea3a34fe70162f20588d308af7c03864736f6c634300080a0033
Deployed Bytecode
0x6080604052600436106101bb5760003560e01c80638165354e116100ec578063e443a4831161008a578063f14210a611610064578063f14210a6146104d6578063f2fde38b146104f6578063f3fef3a314610516578063f6326fb31461053657600080fd5b8063e443a48314610479578063e8b964bc14610499578063ef518a4b146104ae57600080fd5b8063b3ab15fb116100c6578063b3ab15fb14610407578063ceb73b7f14610427578063d54021ae1461044f578063e0d801dd1461046457600080fd5b80638165354e146103a75780638da5cb5b146103c757806397ea951a146103e757600080fd5b806347c62a0d1161015957806354453b1d1161013357806354453b1d1461033257806366c990111461034757806370bb45b31461036f5780637c91d9241461039257600080fd5b806347c62a0d146102dd57806347e7ef24146102fd578063495d77441461031d57600080fd5b806322fdd1951161019557806322fdd195146102615780632506c018146102885780632d6b8e7e1461029d57806335a5af92146102bd57600080fd5b806306eff2fb146101c7578063123b2a401461020c578063175f1c601461023457600080fd5b366101c257005b600080fd5b3480156101d357600080fd5b506101ef732a8e1e676ec238d8a992307b495b45b3feaa5e8681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021857600080fd5b506101ef73856c4efb76c1d1ae02e20ceb03a2a6a08b0b8dc381565b34801561024057600080fd5b5061025461024f366004611f5f565b61053e565b6040516102039190611f83565b34801561026d57600080fd5b506102766105d1565b60405160ff9091168152602001610203565b61029b610296366004611ff2565b61064d565b005b3480156102a957600080fd5b5061029b6102b8366004611f5f565b6106c1565b3480156102c957600080fd5b5061029b6102d8366004611f5f565b610782565b3480156102e957600080fd5b5061029b6102f83660046120dc565b61080f565b34801561030957600080fd5b5061029b6103183660046120dc565b610858565b34801561032957600080fd5b5061029b610894565b34801561033e57600080fd5b5061029b61094d565b34801561035357600080fd5b506101ef7321fb5812d70b3396880d30e90d9e5c1202266c8981565b34801561037b57600080fd5b506103846109e3565b604051908152602001610203565b34801561039e57600080fd5b5061029b610ab2565b3480156103b357600080fd5b5061029b6103c2366004611f5f565b610b48565b3480156103d357600080fd5b506000546101ef906001600160a01b031681565b3480156103f357600080fd5b5061029b610402366004611f5f565b610bc8565b34801561041357600080fd5b5061029b610422366004611f5f565b610c4f565b34801561043357600080fd5b506101ef737d82e86cf1496f9485a8ea04012afeb3c748939781565b34801561045b57600080fd5b5061029b610ca3565b34801561047057600080fd5b50610384610d39565b34801561048557600080fd5b50610254610494366004611f5f565b610db1565b3480156104a557600080fd5b50610276610e36565b3480156104ba57600080fd5b506101ef730d017afa83eace9f10a8ec5b6e13941664a6785c81565b3480156104e257600080fd5b5061029b6104f1366004612108565b610e70565b34801561050257600080fd5b5061029b610511366004611f5f565b611000565b34801561052257600080fd5b5061029b6105313660046120dc565b6110c7565b61029b611118565b6001600160a01b0381166000908152600560209081526040808320805482518185028101850190935280835260609492939192909184015b828210156105c65783829060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505081526020019060010190610576565b505050509050919050565b6040516322b7714360e11b815230600482015260009073856c4efb76c1d1ae02e20ceb03a2a6a08b0b8dc39063456ee286906024015b602060405180830381865afa158015610624573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106489190612121565b905090565b61065561127c565b6002546001600160a01b031633146106a45760405162461bcd60e51b815260206004820152600d60248201526c27b7363c9027b832b930ba37b960991b60448201526064015b60405180910390fd5b6106b185858585856112d6565b6106ba60018055565b5050505050565b6106c961127c565b6000546001600160a01b03163314806106ec57506002546001600160a01b031633145b6107085760405162461bcd60e51b815260040161069b90612144565b60405163548f5ae560e01b81526001600160a01b0382166004820152730d017afa83eace9f10a8ec5b6e13941664a6785c9063548f5ae5906024015b600060405180830381600087803b15801561075e57600080fd5b505af1158015610772573d6000803e3d6000fd5b5050505061077f60018055565b50565b61078a61127c565b6000546001600160a01b031633146107b45760405162461bcd60e51b815260040161069b90612173565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f7f221725f2e949e8562bdbb6a6a90a4cc22b96336ba50962357bf3a27dcb4755906020015b60405180910390a161077f60018055565b61081761127c565b6000546001600160a01b031633146108415760405162461bcd60e51b815260040161069b90612173565b61084b82826116b0565b61085460018055565b5050565b61086061127c565b6000546001600160a01b0316331461088a5760405162461bcd60e51b815260040161069b90612173565b61084b828261175e565b61089c61127c565b6000546001600160a01b03163314806108bf57506002546001600160a01b031633145b6108db5760405162461bcd60e51b815260040161069b90612144565b73856c4efb76c1d1ae02e20ceb03a2a6a08b0b8dc36001600160a01b031663c2376dff6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561092a57600080fd5b505af115801561093e573d6000803e3d6000fd5b5050505061094b60018055565b565b61095561127c565b6000546001600160a01b031633148061097857506002546001600160a01b031633145b6109945760405162461bcd60e51b815260040161069b90612144565b73856c4efb76c1d1ae02e20ceb03a2a6a08b0b8dc36001600160a01b031663f51b0fd46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561092a57600080fd5b60006109ed61127c565b6000546001600160a01b0316331480610a1057506002546001600160a01b031633145b610a2c5760405162461bcd60e51b815260040161069b90612144565b737d82e86cf1496f9485a8ea04012afeb3c74893976001600160a01b03166370bb45b36040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610a80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa49190612196565b9050610aaf60018055565b90565b610aba61127c565b6000546001600160a01b0316331480610add57506002546001600160a01b031633145b610af95760405162461bcd60e51b815260040161069b90612144565b732a8e1e676ec238d8a992307b495b45b3feaa5e866001600160a01b031663f51b0fd46040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561092a57600080fd5b610b5061127c565b6000546001600160a01b03163314610b7a5760405162461bcd60e51b815260040161069b90612173565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527fd7eea7f547123e0693ad16e2016adde5c4b263f3449dc5e8632ef3463aa3e1e1906020016107fe565b610bd061127c565b6000546001600160a01b0316331480610bf357506002546001600160a01b031633145b610c0f5760405162461bcd60e51b815260040161069b90612144565b60405163548f5ae560e01b81526001600160a01b03821660048201527321fb5812d70b3396880d30e90d9e5c1202266c899063548f5ae590602401610744565b610c5761127c565b6000546001600160a01b03163314610c815760405162461bcd60e51b815260040161069b90612173565b600280546001600160a01b0319166001600160a01b0383161790556001805550565b610cab61127c565b6000546001600160a01b0316331480610cce57506002546001600160a01b031633145b610cea5760405162461bcd60e51b815260040161069b90612144565b732a8e1e676ec238d8a992307b495b45b3feaa5e866001600160a01b031663c2376dff6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561092a57600080fd5b6000737d82e86cf1496f9485a8ea04012afeb3c74893976001600160a01b031663e0d801dd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d8d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106489190612196565b6001600160a01b03811660009081526006602090815260408083208054825181850281018501909352808352606094929391929091840182156105c65783829060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505081526020019060010190610576565b6040516322b7714360e11b8152306004820152600090732a8e1e676ec238d8a992307b495b45b3feaa5e869063456ee28690602401610607565b610e7861127c565b6000546001600160a01b0316331480610e9b57506002546001600160a01b031633145b610eb75760405162461bcd60e51b815260040161069b90612144565b6000610ed773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee83611805565b600660209081527fa2e5aefc6e2cbe2917a296f0fd89c5f915c487c803db1d98eccb43f14012d7118054600181018255600091825283517f88ec43c8aeea0158611154a0f26516f4128e25817fb653416dd76295041a8377600390920291820155918301517f88ec43c8aeea0158611154a0f26516f4128e25817fb653416dd76295041a83788301556040808401517f88ec43c8aeea0158611154a0f26516f4128e25817fb653416dd76295041a837990930192909255905191925033916108fc85150291859190818181858888f19350505050158015610fbc573d6000803e3d6000fd5b5060408051338152602081018490527f566e45b1c8057e725bf62796a7f1d37ae294393cab069725a09daddd1af98b79910160405180910390a15061077f60018055565b6000546001600160a01b0316331461102a5760405162461bcd60e51b815260040161069b90612173565b6001600160a01b03811661106c5760405162461bcd60e51b815260206004820152600960248201526830206164647265737360b81b604482015260640161069b565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6110cf61127c565b6000546001600160a01b03163314806110f257506002546001600160a01b031633145b61110e5760405162461bcd60e51b815260040161069b90612144565b61084b828261194c565b61112061127c565b6000546001600160a01b031633148061114357506002546001600160a01b031633145b61115f5760405162461bcd60e51b815260040161069b90612144565b600061117f73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34611805565b600560209081527fa1829a9003092132f585b6ccdd167c19fe9774dbdea4260287e8a8e8ca8185d7805460018101825560009190915282517f3134d172b0d7dc56c5e2ded6d8c21c8fca286b81b4ff3ea5fa839f5b1d69f74f600390920291820155828201517f3134d172b0d7dc56c5e2ded6d8c21c8fca286b81b4ff3ea5fa839f5b1d69f7508201556040808401517f3134d172b0d7dc56c5e2ded6d8c21c8fca286b81b4ff3ea5fa839f5b1d69f75190920191909155805133815234928101929092529192507fced5d8bf10823804603bba066e4f53aa6e8f6f4be68bf0114cf7a0e52183e4e9910160405180910390a15061094b60018055565b600260015414156112cf5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161069b565b6002600155565b600480546040516327526a0360e01b81526001600160a01b03888116938201939093529116906327526a0390602401602060405180830381865afa158015611322573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134691906121af565b6113825760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640161069b565b600480546040516327526a0360e01b81526001600160a01b03878116938201939093529116906327526a0390602401602060405180830381865afa1580156113ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f291906121af565b61142e5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640161069b565b600073def171fe48cf0115b1d80b88dc8eab59176fee576001600160a01b031663d2c4b5986040518163ffffffff1660e01b8152600401602060405180830381865afa158015611482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a691906121d1565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038716906370a0823190602401602060405180830381865afa1580156114f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115149190612196565b905061152a6001600160a01b03881683876119e9565b600073def171fe48cf0115b1d80b88dc8eab59176fee576001600160a01b031684604051611558919061221a565b6000604051808303816000865af19150503d8060008114611595576040519150601f19603f3d011682016040523d82523d6000602084013e61159a565b606091505b50509050806115d95760405162461bcd60e51b815260206004820152600b60248201526a1cddd85c0819985a5b195960aa1b604482015260640161069b565b6040516370a0823160e01b81523060048201526000906001600160a01b038916906370a0823190602401602060405180830381865afa158015611620573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116449190612196565b905085611651848361224c565b10156116905760405162461bcd60e51b815260206004820152600e60248201526d736c69707061676520636865636b60901b604482015260640161069b565b6116a56001600160a01b038a168560006119e9565b505050505050505050565b6000546116ca906001600160a01b03848116911683611b36565b60006116d68383611805565b6001600160a01b0384166000818152600660209081526040808320805460018082018355918552938390208651600390950201938455858301519084015584810151600290930192909255815192835282018590529192507f5324e5ca3eab399efb9cff88b357827404aac06c9bebbd13d81f095576581988910160405180910390a1505050565b6117736001600160a01b038316333084611b66565b600061177f8383611805565b6001600160a01b0384166000908152600560209081526040808320805460018082018355918552938390208551600390950201938455848301519084015583810151600290930192909255905184815291925033917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c91015b60405180910390a2505050565b61182960405180606001604052806000815260200160008152602001600081525090565b60006001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146118b657836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561188d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b19190612121565b6118b9565b60125b600354604051636d9af31360e01b81526001600160a01b038781166004830152929350600092611935921690636d9af31390602401602060405180830381865afa15801561190b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192f91906121d1565b83611ba4565b848452426040850152602084015250505b92915050565b6119606001600160a01b0383163383611b36565b600061196c8383611805565b6001600160a01b0384166000908152600660209081526040808320805460018082018355918552938390208551600390950201938455848301519084015583810151600290930192909255905184815291925033917f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436491016117f8565b801580611a635750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611a3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a619190612196565b155b611ace5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161069b565b6040516001600160a01b038316602482015260448101829052611b3190849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611ceb565b505050565b6040516001600160a01b038316602482015260448101829052611b3190849063a9059cbb60e01b90606401611afa565b6040516001600160a01b0380851660248301528316604482015260648101829052611b9e9085906323b872dd60e01b90608401611afa565b50505050565b6000808390506000816001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611bea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0e9190612282565b5050509150506000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c789190612121565b60ff1690508460ff16811115611cb157611c9560ff86168261224c565b611ca090600a6123b6565b611caa90836123c2565b9350611ce2565b8460ff16811015611cde57611cc98160ff871661224c565b611cd490600a6123b6565b611caa90836123e4565b8193505b50505092915050565b6000611d40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611dbd9092919063ffffffff16565b805190915015611b315780806020019051810190611d5e91906121af565b611b315760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161069b565b6060611dcc8484600085611dd4565b949350505050565b606082471015611e355760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161069b565b600080866001600160a01b03168587604051611e51919061221a565b60006040518083038185875af1925050503d8060008114611e8e576040519150601f19603f3d011682016040523d82523d6000602084013e611e93565b606091505b5091509150611ea487838387611eaf565b979650505050505050565b60608315611f1b578251611f14576001600160a01b0385163b611f145760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161069b565b5081611dcc565b611dcc8383815115611f305781518083602001fd5b8060405162461bcd60e51b815260040161069b9190612403565b6001600160a01b038116811461077f57600080fd5b600060208284031215611f7157600080fd5b8135611f7c81611f4a565b9392505050565b602080825282518282018190526000919060409081850190868401855b82811015611fcf5781518051855286810151878601528501518585015260609093019290850190600101611fa0565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b600080600080600060a0868803121561200a57600080fd5b853561201581611f4a565b9450602086013561202581611f4a565b93506040860135925060608601359150608086013567ffffffffffffffff8082111561205057600080fd5b818801915088601f83011261206457600080fd5b81358181111561207657612076611fdc565b604051601f8201601f19908116603f0116810190838211818310171561209e5761209e611fdc565b816040528281528b60208487010111156120b757600080fd5b8260208601602083013760006020848301015280955050505050509295509295909350565b600080604083850312156120ef57600080fd5b82356120fa81611f4a565b946020939093013593505050565b60006020828403121561211a57600080fd5b5035919050565b60006020828403121561213357600080fd5b815160ff81168114611f7c57600080fd5b6020808252601590820152743737ba1037bbb732b91037b91037b832b930ba37b960591b604082015260600190565b6020808252600990820152683737ba1037bbb732b960b91b604082015260600190565b6000602082840312156121a857600080fd5b5051919050565b6000602082840312156121c157600080fd5b81518015158114611f7c57600080fd5b6000602082840312156121e357600080fd5b8151611f7c81611f4a565b60005b838110156122095781810151838201526020016121f1565b83811115611b9e5750506000910152565b6000825161222c8184602087016121ee565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b60008282101561225e5761225e612236565b500390565b805169ffffffffffffffffffff8116811461227d57600080fd5b919050565b600080600080600060a0868803121561229a57600080fd5b6122a386612263565b94506020860151935060408601519250606086015191506122c660808701612263565b90509295509295909350565b600181815b8085111561230d5781600019048211156122f3576122f3612236565b8085161561230057918102915b93841c93908002906122d7565b509250929050565b60008261232457506001611946565b8161233157506000611946565b816001811461234757600281146123515761236d565b6001915050611946565b60ff84111561236257612362612236565b50506001821b611946565b5060208310610133831016604e8410600b8410161715612390575081810a611946565b61239a83836122d2565b80600019048211156123ae576123ae612236565b029392505050565b6000611f7c8383612315565b6000826123df57634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156123fe576123fe612236565b500290565b60208152600082518060208401526124228160408501602087016121ee565b601f01601f1916919091016040019291505056fea26469706673582212200456f7c54fa809855685cea1d5774c3937ea3a34fe70162f20588d308af7c03864736f6c634300080a0033
Deployed Bytecode Sourcemap
38732:2786:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38784:90;;;;;;;;;;;;38831:42;38784:90;;;;;-1:-1:-1;;;;;178:32:1;;;160:51;;148:2;133:18;38784:90:0;;;;;;;;38881;;;;;;;;;;;;38928:42;38881:90;;37133:155;;;;;;;;;;-1:-1:-1;37133:155:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;41375:140::-;;;;;;;;;;;;;:::i;:::-;;;1644:4:1;1632:17;;;1614:36;;1602:2;1587:18;41375:140:0;1472:184:1;40255:244:0;;;;;;:::i;:::-;;:::i;:::-;;40704:189;;;;;;;;;;-1:-1:-1;40704:189:0;;;;;:::i;:::-;;:::i;31635:188::-;;;;;;;;;;-1:-1:-1;31635:188:0;;;;;:::i;:::-;;:::i;39586:137::-;;;;;;;;;;-1:-1:-1;39586:137:0;;;;;:::i;:::-;;:::i;39316:121::-;;;;;;;;;;-1:-1:-1;39316:121:0;;;;;:::i;:::-;;:::i;40123:124::-;;;;;;;;;;;;;:::i;39861:122::-;;;;;;;;;;;;;:::i;38978:92::-;;;;;;;;;;;;39027:42;38978:92;;40901:169;;;;;;;;;;;;;:::i;:::-;;;3641:25:1;;;3629:2;3614:18;40901:169:0;3495:177:1;39731:122:0;;;;;;;;;;;;;:::i;31287:194::-;;;;;;;;;;-1:-1:-1;31287:194:0;;;;;:::i;:::-;;:::i;26208:20::-;;;;;;;;;;-1:-1:-1;26208:20:0;;;;-1:-1:-1;;;;;26208:20:0;;;40507:189;;;;;;;;;;-1:-1:-1;40507:189:0;;;;;:::i;:::-;;:::i;31014:118::-;;;;;;;;;;-1:-1:-1;31014:118:0;;;;;:::i;:::-;;:::i;39176:96::-;;;;;;;;;;;;39229:42;39176:96;;39991:124;;;;;;;;;;;;;:::i;41078:141::-;;;;;;;;;;;;;:::i;37456:159::-;;;;;;;;;;-1:-1:-1;37456:159:0;;;;;:::i;:::-;;:::i;41227:140::-;;;;;;;;;;;;;:::i;39077:92::-;;;;;;;;;;;;39126:42;39077:92;;36406:379;;;;;;;;;;-1:-1:-1;36406:379:0;;;;;:::i;:::-;;:::i;26820:219::-;;;;;;;;;;-1:-1:-1;26820:219:0;;;;;:::i;:::-;;:::i;39445:133::-;;;;;;;;;;-1:-1:-1;39445:133:0;;;;;:::i;:::-;;:::i;35954:319::-;;;:::i;37133:155::-;-1:-1:-1;;;;;37253:27:0;;;;;;:20;:27;;;;;;;;37246:34;;;;;;;;;;;;;;;;;37204:23;;37246:34;;37253:27;;37246:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37133:155;;;:::o;41375:140::-;41459:48;;-1:-1:-1;;;41459:48:0;;41501:4;41459:48;;;160:51:1;41434:5:0;;38928:42;;41459:33;;133:18:1;;41459:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41452:55;;41375:140;:::o;40255:244::-;20395:21;:19;:21::i;:::-;30417:9:::1;::::0;-1:-1:-1;;;;;30417:9:0::1;30403:10;:23;30395:49;;;::::0;-1:-1:-1;;;30395:49:0;;4342:2:1;30395:49:0::1;::::0;::::1;4324:21:1::0;4381:2;4361:18;;;4354:30;-1:-1:-1;;;4400:18:1;;;4393:43;4453:18;;30395:49:0::1;;;;;;;;;40426:65:::2;40432:8;40442:9;40453;40464:16;40482:8;40426:5;:65::i;:::-;20439:20:::0;19833:1;20959:22;;20776:213;20439:20;40255:244;;;;;:::o;40704:189::-;20395:21;:19;:21::i;:::-;30621:5:::1;::::0;-1:-1:-1;;;;;30621:5:0::1;30607:10;:19;::::0;:46:::1;;-1:-1:-1::0;30644:9:0::1;::::0;-1:-1:-1;;;;;30644:9:0::1;30630:10;:23;30607:46;30599:80;;;;-1:-1:-1::0;;;30599:80:0::1;;;;;;;:::i;:::-;40817:68:::2;::::0;-1:-1:-1;;;40817:68:0;;-1:-1:-1;;;;;178:32:1;;40817:68:0::2;::::0;::::2;160:51:1::0;39126:42:0::2;::::0;40817:54:::2;::::0;133:18:1;;40817:68:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;20439:20:::0;19833:1;20959:22;;20776:213;20439:20;40704:189;:::o;31635:188::-;20395:21;:19;:21::i;:::-;26612:5:::1;::::0;-1:-1:-1;;;;;26612:5:0::1;26621:10;26612:19;26604:41;;;;-1:-1:-1::0;;;26604:41:0::1;;;;;;;:::i;:::-;31731:14:::2;:34:::0;;-1:-1:-1;;;;;;31731:34:0::2;-1:-1:-1::0;;;;;31731:34:0;::::2;::::0;;::::2;::::0;;;31783:32:::2;::::0;160:51:1;;;31783:32:0::2;::::0;148:2:1;133:18;31783:32:0::2;;;;;;;;20439:20:::0;19833:1;20959:22;;20776:213;39586:137;20395:21;:19;:21::i;:::-;26612:5:::1;::::0;-1:-1:-1;;;;;26612:5:0::1;26621:10;26612:19;26604:41;;;;-1:-1:-1::0;;;26604:41:0::1;;;;;;;:::i;:::-;39684:31:::2;39701:5;39708:6;39684:16;:31::i;:::-;20439:20:::0;19833:1;20959:22;;20776:213;20439:20;39586:137;;:::o;39316:121::-;20395:21;:19;:21::i;:::-;26612:5:::1;::::0;-1:-1:-1;;;;;26612:5:0::1;26621:10;26612:19;26604:41;;;;-1:-1:-1::0;;;26604:41:0::1;;;;;;;:::i;:::-;39406:23:::2;39415:5;39422:6;39406:8;:23::i;40123:124::-:0;20395:21;:19;:21::i;:::-;30621:5:::1;::::0;-1:-1:-1;;;;;30621:5:0::1;30607:10;:19;::::0;:46:::1;;-1:-1:-1::0;30644:9:0::1;::::0;-1:-1:-1;;;;;30644:9:0::1;30630:10;:23;30607:46;30599:80;;;;-1:-1:-1::0;;;30599:80:0::1;;;;;;;:::i;:::-;38928:42:::2;-1:-1:-1::0;;;;;40203:34:0::2;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;20439:20:::0;19833:1;20959:22;;20776:213;20439:20;40123:124::o;39861:122::-;20395:21;:19;:21::i;:::-;30621:5:::1;::::0;-1:-1:-1;;;;;30621:5:0::1;30607:10;:19;::::0;:46:::1;;-1:-1:-1::0;30644:9:0::1;::::0;-1:-1:-1;;;;;30644:9:0::1;30630:10;:23;30607:46;30599:80;;;;-1:-1:-1::0;;;30599:80:0::1;;;;;;;:::i;:::-;38928:42:::2;-1:-1:-1::0;;;;;39940:33:0::2;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;40901:169:::0;40978:7;20395:21;:19;:21::i;:::-;30621:5:::1;::::0;-1:-1:-1;;;;;30621:5:0::1;30607:10;:19;::::0;:46:::1;;-1:-1:-1::0;30644:9:0::1;::::0;-1:-1:-1;;;;;30644:9:0::1;30630:10;:23;30607:46;30599:80;;;;-1:-1:-1::0;;;30599:80:0::1;;;;;;;:::i;:::-;39229:42:::2;-1:-1:-1::0;;;;;41005:55:0::2;;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40998:64;;20439:20:::0;19833:1;20959:22;;20776:213;20439:20;40901:169;:::o;39731:122::-;20395:21;:19;:21::i;:::-;30621:5:::1;::::0;-1:-1:-1;;;;;30621:5:0::1;30607:10;:19;::::0;:46:::1;;-1:-1:-1::0;30644:9:0::1;::::0;-1:-1:-1;;;;;30644:9:0::1;30630:10;:23;30607:46;30599:80;;;;-1:-1:-1::0;;;30599:80:0::1;;;;;;;:::i;:::-;38831:42:::2;-1:-1:-1::0;;;;;39810:33:0::2;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;31287:194:::0;20395:21;:19;:21::i;:::-;26612:5:::1;::::0;-1:-1:-1;;;;;26612:5:0::1;26621:10;26612:19;26604:41;;;;-1:-1:-1::0;;;26604:41:0::1;;;;;;;:::i;:::-;31385:15:::2;:36:::0;;-1:-1:-1;;;;;;31385:36:0::2;-1:-1:-1::0;;;;;31385:36:0;::::2;::::0;;::::2;::::0;;;31439:34:::2;::::0;160:51:1;;;31439:34:0::2;::::0;148:2:1;133:18;31439:34:0::2;14:203:1::0;40507:189:0;20395:21;:19;:21::i;:::-;30621:5:::1;::::0;-1:-1:-1;;;;;30621:5:0::1;30607:10;:19;::::0;:46:::1;;-1:-1:-1::0;30644:9:0::1;::::0;-1:-1:-1;;;;;30644:9:0::1;30630:10;:23;30607:46;30599:80;;;;-1:-1:-1::0;;;30599:80:0::1;;;;;;;:::i;:::-;40620:68:::2;::::0;-1:-1:-1;;;40620:68:0;;-1:-1:-1;;;;;178:32:1;;40620:68:0::2;::::0;::::2;160:51:1::0;39027:42:0::2;::::0;40620:54:::2;::::0;133:18:1;;40620:68:0::2;14:203:1::0;31014:118:0;20395:21;:19;:21::i;:::-;26612:5:::1;::::0;-1:-1:-1;;;;;26612:5:0::1;26621:10;26612:19;26604:41;;;;-1:-1:-1::0;;;26604:41:0::1;;;;;;;:::i;:::-;31100:9:::2;:24:::0;;-1:-1:-1;;;;;;31100:24:0::2;-1:-1:-1::0;;;;;31100:24:0;::::2;;::::0;;-1:-1:-1;20959:22:0;;40704:189;:::o;39991:124::-;20395:21;:19;:21::i;:::-;30621:5:::1;::::0;-1:-1:-1;;;;;30621:5:0::1;30607:10;:19;::::0;:46:::1;;-1:-1:-1::0;30644:9:0::1;::::0;-1:-1:-1;;;;;30644:9:0::1;30630:10;:23;30607:46;30599:80;;;;-1:-1:-1::0;;;30599:80:0::1;;;;;;;:::i;:::-;38831:42:::2;-1:-1:-1::0;;;;;40071:34:0::2;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;41078:141:::0;41127:7;39229:42;-1:-1:-1;;;;;41154:55:0;;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;37456:159::-;-1:-1:-1;;;;;37578:29:0;;;;;;:22;:29;;;;;;;;37571:36;;;;;;;;;;;;;;;;;37529:23;;37571:36;;37578:29;;37571:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41227:140;41311:48;;-1:-1:-1;;;41311:48:0;;41353:4;41311:48;;;160:51:1;41286:5:0;;38831:42;;41311:33;;133:18:1;;41311:48:0;14:203:1;36406:379:0;20395:21;:19;:21::i;:::-;30621:5:::1;::::0;-1:-1:-1;;;;;30621:5:0::1;30607:10;:19;::::0;:46:::1;;-1:-1:-1::0;30644:9:0::1;::::0;-1:-1:-1;;;;;30644:9:0::1;30630:10;:23;30607:46;30599:80;;;;-1:-1:-1::0;;;30599:80:0::1;;;;;;;:::i;:::-;36498:37:::2;36538:34;27533:42;36565:6;36538:12;:34::i;:::-;36585:22;:36;::::0;;;;:58;;::::2;::::0;::::2;::::0;;-1:-1:-1;36585:58:0;;;;;;::::2;::::0;;::::2;::::0;;::::2;::::0;;;::::2;::::0;;;;;:36;:58;;::::2;::::0;;;;;;;;;36692:36;;36585:58;;-1:-1:-1;36700:10:0::2;::::0;36692:36:::2;::::0;::::2;;::::0;;;;;-1:-1:-1;36692:36:0;;36700:10;36692:36;::::2;;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;36746:31:0::2;::::0;;36758:10:::2;5532:51:1::0;;5614:2;5599:18;;5592:34;;;36746:31:0::2;::::0;5505:18:1;36746:31:0::2;;;;;;;36485:300;20439:20:::0;19833:1;20959:22;;20776:213;26820:219;26612:5;;-1:-1:-1;;;;;26612:5:0;26621:10;26612:19;26604:41;;;;-1:-1:-1;;;26604:41:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;26911:22:0;::::1;26903:44;;;::::0;-1:-1:-1;;;26903:44:0;;5839:2:1;26903:44:0::1;::::0;::::1;5821:21:1::0;5878:1;5858:18;;;5851:29;-1:-1:-1;;;5896:18:1;;;5889:39;5945:18;;26903:44:0::1;5637:332:1::0;26903:44:0::1;26984:5;::::0;;26963:37:::1;::::0;-1:-1:-1;;;;;26963:37:0;;::::1;::::0;26984:5;::::1;::::0;26963:37:::1;::::0;::::1;27015:5;:16:::0;;-1:-1:-1;;;;;;27015:16:0::1;-1:-1:-1::0;;;;;27015:16:0;;;::::1;::::0;;;::::1;::::0;;26820:219::o;39445:133::-;20395:21;:19;:21::i;:::-;30621:5:::1;::::0;-1:-1:-1;;;;;30621:5:0::1;30607:10;:19;::::0;:46:::1;;-1:-1:-1::0;30644:9:0::1;::::0;-1:-1:-1;;;;;30644:9:0::1;30630:10;:23;30607:46;30599:80;;;;-1:-1:-1::0;;;30599:80:0::1;;;;;;;:::i;:::-;39546:24:::2;39556:5;39563:6;39546:9;:24::i;35954:319::-:0;20395:21;:19;:21::i;:::-;30621:5:::1;::::0;-1:-1:-1;;;;;30621:5:0::1;30607:10;:19;::::0;:46:::1;;-1:-1:-1::0;30644:9:0::1;::::0;-1:-1:-1;;;;;30644:9:0::1;30630:10;:23;30607:46;30599:80;;;;-1:-1:-1::0;;;30599:80:0::1;;;;;;;:::i;:::-;36037:36:::2;36076:37;27533:42;36103:9;36076:12;:37::i;:::-;36126:20;:34;::::0;;;;:55;;::::2;::::0;::::2;::::0;;-1:-1:-1;36126:55:0;;;;;;;::::2;::::0;;::::2;::::0;;::::2;::::0;;;::::2;::::0;;;;;:34;:55;;::::2;::::0;;;;;;;;;36232:33;;36243:10:::2;5532:51:1::0;;36255:9:0::2;5599:18:1::0;;;5592:34;;;;36126:55:0;;-1:-1:-1;36232:33:0::2;::::0;5505:18:1;36232:33:0::2;;;;;;;36026:247;20439:20:::0;19833:1;20959:22;;20776:213;20475:293;19877:1;20609:7;;:19;;20601:63;;;;-1:-1:-1;;;20601:63:0;;6176:2:1;20601:63:0;;;6158:21:1;6215:2;6195:18;;;6188:30;6254:33;6234:18;;;6227:61;6305:18;;20601:63:0;5974:355:1;20601:63:0;19877:1;20742:7;:18;20475:293::o;34724:972::-;34937:14;;;34922:67;;-1:-1:-1;;;34922:67:0;;-1:-1:-1;;;;;178:32:1;;;34922:67:0;;;160:51:1;;;;34937:14:0;;;34922:48;;133:18:1;;34922:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34914:93;;;;-1:-1:-1;;;34914:93:0;;6818:2:1;34914:93:0;;;6800:21:1;6857:2;6837:18;;;6830:30;-1:-1:-1;;;6876:18:1;;;6869:43;6929:18;;34914:93:0;6616:337:1;34914:93:0;35041:14;;;35026:68;;-1:-1:-1;;;35026:68:0;;-1:-1:-1;;;;;178:32:1;;;35026:68:0;;;160:51:1;;;;35041:14:0;;;35026:48;;133:18:1;;35026:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35018:94;;;;-1:-1:-1;;;35018:94:0;;6818:2:1;35018:94:0;;;6800:21:1;6857:2;6837:18;;;6830:30;-1:-1:-1;;;6876:18:1;;;6869:43;6929:18;;35018:94:0;6616:337:1;35018:94:0;35125:26;27452:42;-1:-1:-1;;;;;35154:49:0;;:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35251:34;;-1:-1:-1;;;35251:34:0;;35279:4;35251:34;;;160:51:1;35125:80:0;;-1:-1:-1;35218:30:0;;-1:-1:-1;;;;;35251:19:0;;;;;133:18:1;;35251:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35218:67;-1:-1:-1;35298:51:0;-1:-1:-1;;;;;35298:20:0;;35319:18;35339:9;35298:20;:51::i;:::-;35363:12;27452:42;-1:-1:-1;;;;;35380:13:0;35394:8;35380:23;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35362:41;;;35424:7;35416:31;;;;-1:-1:-1;;;35416:31:0;;7958:2:1;35416:31:0;;;7940:21:1;7997:2;7977:18;;;7970:30;-1:-1:-1;;;8016:18:1;;;8009:41;8067:18;;35416:31:0;7756:335:1;35416:31:0;35492:34;;-1:-1:-1;;;35492:34:0;;35520:4;35492:34;;;160:51:1;35460:29:0;;-1:-1:-1;;;;;35492:19:0;;;;;133:18:1;;35492:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35460:66;-1:-1:-1;35597:16:0;35547:46;35571:22;35460:66;35547:46;:::i;:::-;:66;;35539:93;;;;-1:-1:-1;;;35539:93:0;;8560:2:1;35539:93:0;;;8542:21:1;8599:2;8579:18;;;8572:30;-1:-1:-1;;;8618:18:1;;;8611:44;8672:18;;35539:93:0;8358:338:1;35539:93:0;35645:43;-1:-1:-1;;;;;35645:20:0;;35666:18;35686:1;35645:20;:43::i;:::-;34903:793;;;;34724:972;;;;;:::o;33960:363::-;34055:5;;34036:33;;-1:-1:-1;;;;;34036:18:0;;;;34055:5;34062:6;34036:18;:33::i;:::-;34082:37;34122:36;34143:5;34151:6;34122:12;:36::i;:::-;-1:-1:-1;;;;;34171:38:0;;;;;;:22;:38;;;;;;;;:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34285:30;;5532:51:1;;;5599:18;;5592:34;;;34171:60:0;;-1:-1:-1;34285:30:0;;5505:18:1;34285:30:0;;;;;;;34025:298;33960:363;;:::o;32896:369::-;32964:57;-1:-1:-1;;;;;32964:22:0;;32987:10;33007:4;33014:6;32964:22;:57::i;:::-;33034:36;33073;33094:5;33102:6;33073:12;:36::i;:::-;-1:-1:-1;;;;;33122:36:0;;;;;;:20;:36;;;;;;;;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33230:27;;3641:25:1;;;33122:57:0;;-1:-1:-1;33238:10:0;;33230:27;;3614:18:1;33230:27:0;;;;;;;;32953:312;32896:369;;:::o;32225:513::-;32301:36;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;32301:36:0;32350:14;-1:-1:-1;;;;;32368:21:0;;27533:42;32368:21;32367:63;;32413:5;-1:-1:-1;;;;;32398:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32367:63;;;32393:2;32367:63;32506:15;;32490:67;;-1:-1:-1;;;32490:67:0;;-1:-1:-1;;;;;178:32:1;;;32490:67:0;;;160:51:1;32350:80:0;;-1:-1:-1;32441:13:0;;32470:98;;32506:15;;32490:51;;133:18:1;;32490:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32559:8;32470:19;:98::i;:::-;32579:30;;;32642:15;32620:19;;;:37;32668:20;;;:28;-1:-1:-1;;32225:513:0;;;;;:::o;33426:359::-;33495:38;-1:-1:-1;;;;;33495:18:0;;33514:10;33526:6;33495:18;:38::i;:::-;33546:37;33586:36;33607:5;33615:6;33586:12;:36::i;:::-;-1:-1:-1;;;;;33635:38:0;;;;;;:22;:38;;;;;;;;:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33749:28;;3641:25:1;;;33635:60:0;;-1:-1:-1;33758:10:0;;33749:28;;3614:18:1;33749:28:0;3495:177:1;22909:616:0;23273:10;;;23272:62;;-1:-1:-1;23289:39:0;;-1:-1:-1;;;23289:39:0;;23313:4;23289:39;;;9206:34:1;-1:-1:-1;;;;;9276:15:1;;;9256:18;;;9249:43;23289:15:0;;;;;9141:18:1;;23289:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;23272:62;23250:166;;;;-1:-1:-1;;;23250:166:0;;9505:2:1;23250:166:0;;;9487:21:1;9544:2;9524:18;;;9517:30;9583:34;9563:18;;;9556:62;-1:-1:-1;;;9634:18:1;;;9627:52;9696:19;;23250:166:0;9303:418:1;23250:166:0;23454:62;;-1:-1:-1;;;;;5550:32:1;;23454:62:0;;;5532:51:1;5599:18;;;5592:34;;;23427:90:0;;23447:5;;-1:-1:-1;;;23477:22:0;5505:18:1;;23454:62:0;;;;-1:-1:-1;;23454:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;23454:62:0;-1:-1:-1;;;;;;23454:62:0;;;;;;;;;;23427:19;:90::i;:::-;22909:616;;;:::o;22173:211::-;22317:58;;-1:-1:-1;;;;;5550:32:1;;22317:58:0;;;5532:51:1;5599:18;;;5592:34;;;22290:86:0;;22310:5;;-1:-1:-1;;;22340:23:0;5505:18:1;;22317:58:0;5358:274:1;22392:248:0;22563:68;;-1:-1:-1;;;;;9984:15:1;;;22563:68:0;;;9966:34:1;10036:15;;10016:18;;;10009:43;10068:18;;;10061:34;;;22536:96:0;;22556:5;;-1:-1:-1;;;22586:27:0;9901:18:1;;22563:68:0;9726:375:1;22536:96:0;22392:248;;;;:::o;16651:659::-;16754:18;16785:32;16843:6;16785:65;;16864:12;16883:9;-1:-1:-1;;;;;16883:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16861:49;;;;;;16921:22;16946:9;-1:-1:-1;;;;;16946:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16921:45;;;;17000:13;16983:30;;:14;:30;16979:324;;;17065:30;;;;:14;:30;:::i;:::-;17060:36;;:2;:36;:::i;:::-;17043:53;;17051:5;17043:53;:::i;:::-;17030:66;;16979:324;;;17135:13;17118:30;;:14;:30;17114:189;;;17200:30;17216:14;17200:30;;;;:::i;:::-;17195:36;;:2;:36;:::i;:::-;17178:53;;17186:5;17178:53;:::i;17114:189::-;17285:5;17264:27;;17114:189;16774:536;;;16651:659;;;;:::o;25240:716::-;25664:23;25690:69;25718:4;25690:69;;;;;;;;;;;;;;;;;25698:5;-1:-1:-1;;;;;25690:27:0;;;:69;;;;;:::i;:::-;25774:17;;25664:95;;-1:-1:-1;25774:21:0;25770:179;;25871:10;25860:30;;;;;;;;;;;;:::i;:::-;25852:85;;;;-1:-1:-1;;;25852:85:0;;12739:2:1;25852:85:0;;;12721:21:1;12778:2;12758:18;;;12751:30;12817:34;12797:18;;;12790:62;-1:-1:-1;;;12868:18:1;;;12861:40;12918:19;;25852:85:0;12537:406:1;7877:229:0;8014:12;8046:52;8068:6;8076:4;8082:1;8085:12;8046:21;:52::i;:::-;8039:59;7877:229;-1:-1:-1;;;;7877:229:0:o;8997:455::-;9167:12;9225:5;9200:21;:30;;9192:81;;;;-1:-1:-1;;;9192:81:0;;13150:2:1;9192:81:0;;;13132:21:1;13189:2;13169:18;;;13162:30;13228:34;13208:18;;;13201:62;-1:-1:-1;;;13279:18:1;;;13272:36;13325:19;;9192:81:0;12948:402:1;9192:81:0;9285:12;9299:23;9326:6;-1:-1:-1;;;;;9326:11:0;9345:5;9352:4;9326:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9284:73;;;;9375:69;9402:6;9410:7;9419:10;9431:12;9375:26;:69::i;:::-;9368:76;8997:455;-1:-1:-1;;;;;;;8997:455:0:o;11570:644::-;11755:12;11784:7;11780:427;;;11812:17;;11808:290;;-1:-1:-1;;;;;5411:19:0;;;12022:60;;;;-1:-1:-1;;;12022:60:0;;13557:2:1;12022:60:0;;;13539:21:1;13596:2;13576:18;;;13569:30;13635:31;13615:18;;;13608:59;13684:18;;12022:60:0;13355:353:1;12022:60:0;-1:-1:-1;12119:10:0;12112:17;;11780:427;12162:33;12170:10;12182:12;12917:17;;:21;12913:388;;13149:10;13143:17;13206:15;13193:10;13189:2;13185:19;13178:44;12913:388;13276:12;13269:20;;-1:-1:-1;;;13269:20:0;;;;;;;;:::i;222:131:1:-;-1:-1:-1;;;;;297:31:1;;287:42;;277:70;;343:1;340;333:12;358:247;417:6;470:2;458:9;449:7;445:23;441:32;438:52;;;486:1;483;476:12;438:52;525:9;512:23;544:31;569:5;544:31;:::i;:::-;594:5;358:247;-1:-1:-1;;;358:247:1:o;610:857::-;845:2;897:21;;;967:13;;870:18;;;989:22;;;816:4;;845:2;1030;;1048:18;;;;1089:15;;;816:4;1132:309;1146:6;1143:1;1140:13;1132:309;;;1205:13;;1243:9;;1231:22;;1293:11;;;1287:18;1273:12;;;1266:40;1346:11;;1340:18;1326:12;;;1319:40;1388:4;1379:14;;;;1416:15;;;;1168:1;1161:9;1132:309;;;-1:-1:-1;1458:3:1;;610:857;-1:-1:-1;;;;;;;610:857:1:o;1661:127::-;1722:10;1717:3;1713:20;1710:1;1703:31;1753:4;1750:1;1743:15;1777:4;1774:1;1767:15;1793:1363;1925:6;1933;1941;1949;1957;2010:3;1998:9;1989:7;1985:23;1981:33;1978:53;;;2027:1;2024;2017:12;1978:53;2066:9;2053:23;2085:31;2110:5;2085:31;:::i;:::-;2135:5;-1:-1:-1;2192:2:1;2177:18;;2164:32;2205:33;2164:32;2205:33;:::i;:::-;2257:7;-1:-1:-1;2311:2:1;2296:18;;2283:32;;-1:-1:-1;2362:2:1;2347:18;;2334:32;;-1:-1:-1;2417:3:1;2402:19;;2389:33;2441:18;2471:14;;;2468:34;;;2498:1;2495;2488:12;2468:34;2536:6;2525:9;2521:22;2511:32;;2581:7;2574:4;2570:2;2566:13;2562:27;2552:55;;2603:1;2600;2593:12;2552:55;2639:2;2626:16;2661:2;2657;2654:10;2651:36;;;2667:18;;:::i;:::-;2742:2;2736:9;2710:2;2796:13;;-1:-1:-1;;2792:22:1;;;2816:2;2788:31;2784:40;2772:53;;;2840:18;;;2860:22;;;2837:46;2834:72;;;2886:18;;:::i;:::-;2926:10;2922:2;2915:22;2961:2;2953:6;2946:18;3001:7;2996:2;2991;2987;2983:11;2979:20;2976:33;2973:53;;;3022:1;3019;3012:12;2973:53;3078:2;3073;3069;3065:11;3060:2;3052:6;3048:15;3035:46;3123:1;3118:2;3113;3105:6;3101:15;3097:24;3090:35;3144:6;3134:16;;;;;;;1793:1363;;;;;;;;:::o;3161:329::-;3243:6;3251;3304:2;3292:9;3283:7;3279:23;3275:32;3272:52;;;3320:1;3317;3310:12;3272:52;3359:9;3346:23;3378:31;3403:5;3378:31;:::i;:::-;3428:5;3480:2;3465:18;;;;3452:32;;-1:-1:-1;;;3161:329:1:o;3677:180::-;3736:6;3789:2;3777:9;3768:7;3764:23;3760:32;3757:52;;;3805:1;3802;3795:12;3757:52;-1:-1:-1;3828:23:1;;3677:180;-1:-1:-1;3677:180:1:o;3862:273::-;3930:6;3983:2;3971:9;3962:7;3958:23;3954:32;3951:52;;;3999:1;3996;3989:12;3951:52;4031:9;4025:16;4081:4;4074:5;4070:16;4063:5;4060:27;4050:55;;4101:1;4098;4091:12;4482:345;4684:2;4666:21;;;4723:2;4703:18;;;4696:30;-1:-1:-1;;;4757:2:1;4742:18;;4735:51;4818:2;4803:18;;4482:345::o;4832:332::-;5034:2;5016:21;;;5073:1;5053:18;;;5046:29;-1:-1:-1;;;5106:2:1;5091:18;;5084:39;5155:2;5140:18;;4832:332::o;5169:184::-;5239:6;5292:2;5280:9;5271:7;5267:23;5263:32;5260:52;;;5308:1;5305;5298:12;5260:52;-1:-1:-1;5331:16:1;;5169:184;-1:-1:-1;5169:184:1:o;6334:277::-;6401:6;6454:2;6442:9;6433:7;6429:23;6425:32;6422:52;;;6470:1;6467;6460:12;6422:52;6502:9;6496:16;6555:5;6548:13;6541:21;6534:5;6531:32;6521:60;;6577:1;6574;6567:12;6958:251;7028:6;7081:2;7069:9;7060:7;7056:23;7052:32;7049:52;;;7097:1;7094;7087:12;7049:52;7129:9;7123:16;7148:31;7173:5;7148:31;:::i;7214:258::-;7286:1;7296:113;7310:6;7307:1;7304:13;7296:113;;;7386:11;;;7380:18;7367:11;;;7360:39;7332:2;7325:10;7296:113;;;7427:6;7424:1;7421:13;7418:48;;;-1:-1:-1;;7462:1:1;7444:16;;7437:27;7214:258::o;7477:274::-;7606:3;7644:6;7638:13;7660:53;7706:6;7701:3;7694:4;7686:6;7682:17;7660:53;:::i;:::-;7729:16;;;;;7477:274;-1:-1:-1;;7477:274:1:o;8096:127::-;8157:10;8152:3;8148:20;8145:1;8138:31;8188:4;8185:1;8178:15;8212:4;8209:1;8202:15;8228:125;8268:4;8296:1;8293;8290:8;8287:34;;;8301:18;;:::i;:::-;-1:-1:-1;8338:9:1;;8228:125::o;10106:179::-;10184:13;;10237:22;10226:34;;10216:45;;10206:73;;10275:1;10272;10265:12;10206:73;10106:179;;;:::o;10290:473::-;10393:6;10401;10409;10417;10425;10478:3;10466:9;10457:7;10453:23;10449:33;10446:53;;;10495:1;10492;10485:12;10446:53;10518:39;10547:9;10518:39;:::i;:::-;10508:49;;10597:2;10586:9;10582:18;10576:25;10566:35;;10641:2;10630:9;10626:18;10620:25;10610:35;;10685:2;10674:9;10670:18;10664:25;10654:35;;10708:49;10752:3;10741:9;10737:19;10708:49;:::i;:::-;10698:59;;10290:473;;;;;;;;:::o;10768:422::-;10857:1;10900:5;10857:1;10914:270;10935:7;10925:8;10922:21;10914:270;;;10994:4;10990:1;10986:6;10982:17;10976:4;10973:27;10970:53;;;11003:18;;:::i;:::-;11053:7;11043:8;11039:22;11036:55;;;11073:16;;;;11036:55;11152:22;;;;11112:15;;;;10914:270;;;10918:3;10768:422;;;;;:::o;11195:806::-;11244:5;11274:8;11264:80;;-1:-1:-1;11315:1:1;11329:5;;11264:80;11363:4;11353:76;;-1:-1:-1;11400:1:1;11414:5;;11353:76;11445:4;11463:1;11458:59;;;;11531:1;11526:130;;;;11438:218;;11458:59;11488:1;11479:10;;11502:5;;;11526:130;11563:3;11553:8;11550:17;11547:43;;;11570:18;;:::i;:::-;-1:-1:-1;;11626:1:1;11612:16;;11641:5;;11438:218;;11740:2;11730:8;11727:16;11721:3;11715:4;11712:13;11708:36;11702:2;11692:8;11689:16;11684:2;11678:4;11675:12;11671:35;11668:77;11665:159;;;-1:-1:-1;11777:19:1;;;11809:5;;11665:159;11856:34;11881:8;11875:4;11856:34;:::i;:::-;11926:6;11922:1;11918:6;11914:19;11905:7;11902:32;11899:58;;;11937:18;;:::i;:::-;11975:20;;11195:806;-1:-1:-1;;;11195:806:1:o;12006:131::-;12066:5;12095:36;12122:8;12116:4;12095:36;:::i;12142:217::-;12182:1;12208;12198:132;;12252:10;12247:3;12243:20;12240:1;12233:31;12287:4;12284:1;12277:15;12315:4;12312:1;12305:15;12198:132;-1:-1:-1;12344:9:1;;12142:217::o;12364:168::-;12404:7;12470:1;12466;12462:6;12458:14;12455:1;12452:21;12447:1;12440:9;12433:17;12429:45;12426:71;;;12477:18;;:::i;:::-;-1:-1:-1;12517:9:1;;12364:168::o;13713:383::-;13862:2;13851:9;13844:21;13825:4;13894:6;13888:13;13937:6;13932:2;13921:9;13917:18;13910:34;13953:66;14012:6;14007:2;13996:9;13992:18;13987:2;13979:6;13975:15;13953:66;:::i;:::-;14080:2;14059:15;-1:-1:-1;;14055:29:1;14040:45;;;;14087:2;14036:54;;13713:383;-1:-1:-1;;13713:383:1:o
Swarm Source
ipfs://0456f7c54fa809855685cea1d5774c3937ea3a34fe70162f20588d308af7c038
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.