Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Trading
Compiler Version
v0.7.3+commit.9bfce1f6
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.7.3;
pragma experimental ABIEncoderV2;
import '@openzeppelin/contracts/math/SafeMath.sol';
import './interfaces/IProducts.sol';
import './interfaces/IQueue.sol';
import './interfaces/IToken.sol';
import './interfaces/ITreasury.sol';
import './libraries/Permit.sol';
import './libraries/SafeMathExt.sol';
import './libraries/UintSet.sol';
contract Trading {
/* Libraries */
using SafeMath for uint256;
using SafeMathExt for uint256;
using UintSet for UintSet.Set;
/* Structs */
struct Position {
address sender; // 20 bytes
bytes12 symbol; // 12 bytes
uint64 margin; // 8 bytes
uint64 leverage; // 8 bytes
uint64 price; // 8 bytes
uint48 block; // 7 bytes
bool isBuy; // 1 byte
uint256 id; // not stored
}
/* Variables */
address private products;
address private queue;
address private treasury;
// DAI
address public currency;
// minimum margin to open a position
uint256 public minimumMargin;
// 10^18 for DAI
uint256 public currencyUnit;
// user => balance
mapping(address => uint256) public freeMargins;
// id => Position
mapping(uint256 => Position) public positions;
// user => position ids
mapping(address => UintSet.Set) private userPositionIds;
// positions being liquidated
mapping(uint256 => bool) public liquidatingIds;
// user => bool
mapping(address => uint256) public pausedUsers;
// liquidator reward %
uint256 public liquidatorReward;
address public owner;
bool private initialized;
bool public paused;
/* Events */
event NewContracts(address products, address queue, address treasury);
event NewMinimum(uint256 amount);
event NewLiquidatorReward(uint256 amount);
event Deposited(uint256 amount);
event Withdrew(uint256 amount);
event OrderSubmitted(
uint256 id,
address indexed sender,
bool isBuy,
bytes32 symbol,
uint256 margin,
uint256 leverage,
uint256 positionId
);
event OrderCancelled(
uint256 id,
uint256 positionId,
address indexed sender,
string reason
);
event PositionOpened(
uint256 positionId,
address indexed sender,
bool isBuy,
bytes32 symbol,
uint256 margin,
uint256 leverage,
uint256 price
);
event PositionLiquidated(
uint256 positionId,
address indexed sender,
address indexed liquidator,
uint256 marginLiquidated
);
event PositionClosed(
uint256 positionId,
address indexed sender,
uint256 marginClosed,
uint256 amountToReturn,
uint256 entryPrice,
uint256 price,
uint256 leverage
);
event LiquidationSubmitted(
uint256 id,
uint256 positionId,
address indexed sender
);
/* Initializer (called only once) */
function initialize(address _currency) public {
require(!initialized, '!initialized');
initialized = true;
owner = msg.sender;
liquidatorReward = 10;
currency = _currency;
currencyUnit = SafeMathExt.base10pow(IToken(_currency).decimals());
}
/* Methods called by governance */
function registerContracts(
address _products,
address _queue,
address _treasury
) external onlyOwner {
products = _products;
queue = _queue;
treasury = _treasury;
emit NewContracts(_products, _queue, _treasury);
}
function setCurrencyMin(uint256 _amount) external onlyOwner {
minimumMargin = _amount;
emit NewMinimum(_amount);
}
function setLiquidatorReward(uint256 _amount) external onlyOwner {
require(_amount <= 100, '!percent');
liquidatorReward = _amount;
emit NewLiquidatorReward(_amount);
}
function pauseUsers(address[] calldata users) external onlyOwner {
for (uint256 i = 0; i < users.length; i++) {
pausedUsers[users[i]] = block.number;
}
}
function unpauseUsers(address[] calldata users) external onlyOwner {
for (uint256 i = 0; i < users.length; i++) {
pausedUsers[users[i]] = 0;
}
}
// TODO review
function capUserBalance(
address user,
uint256 newBalanceCap
) external onlyOwner {
// user must be blocked in a previous transaction before we can cap the balance
uint256 pauseBlockNumber = pausedUsers[user];
require(pauseBlockNumber > 0 && pauseBlockNumber < block.number, '!user_not_paused');
uint256 treasuryBalance = ITreasury(treasury).getUserBalance(user);
// trading balance and newBalance are 8 decimals, treasuryBalance 18 decimals (in most cases)
require(newBalanceCap.mulDecimal8(currencyUnit) >= treasuryBalance, '!too_low');
if (freeMargins[user] > newBalanceCap) {
freeMargins[user] = newBalanceCap;
}
}
function pause() external onlyOwner {
paused = true;
}
function unpause() external onlyOwner {
paused = false;
}
/* Methods called by the client */
function deposit(
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external whenNotPaused {
uint256 amt = amount.mulDecimal8(currencyUnit);
Permit.permit(currency, amt, msg.sender, treasury, deadline, v, r, s);
ITreasury(treasury).userDeposit(msg.sender, amt);
freeMargins[msg.sender] = freeMargins[msg.sender].add(amount);
emit Deposited(amount);
}
function withdraw(
uint256 amount
) external whenNotPaused whenNotUserPaused(msg.sender) {
freeMargins[msg.sender] = freeMargins[msg.sender].sub(amount, '!balance');
ITreasury(treasury).userWithdraw(msg.sender, amount.mulDecimal8(currencyUnit));
emit Withdrew(amount);
}
function submitOrder(
bool isBuy,
bytes32 symbol,
uint256 margin,
uint256 leverage
) external whenNotPaused whenNotUserPaused(msg.sender) {
require(margin >= minimumMargin, '!margin');
require(leverage >= SafeMathExt.UNIT8, '!leverage');
uint256 maxLeverage = IProducts(products).getMaxLeverage(symbol, true);
require(maxLeverage > 0, '!symbol');
require(leverage <= maxLeverage, '!max_leverage');
freeMargins[msg.sender] = freeMargins[msg.sender].sub(margin, '!balance');
uint256 id = _queueOrder(isBuy, symbol, margin, leverage, 0, address(0));
positions[id] = Position({isBuy: isBuy, margin: SafeMathExt.safeUint64(margin), leverage: SafeMathExt.safeUint64(leverage), sender: msg.sender, symbol: bytes12(''), price: 0, block: 0, id: 0});
}
function submitOrderUpdate(
uint256 positionId,
uint256 margin
) external whenNotPaused {
Position storage position = positions[positionId];
require(position.price > 0, '!found');
require(position.sender == msg.sender, '!authorized');
// partial or full close
require(margin <= uint256(position.margin), '!margin');
_queueOrder(!position.isBuy, bytes32(position.symbol), margin, uint256(position.leverage), positionId, address(0));
}
function liquidatePositions(uint256[] calldata positionIds) external {
uint256 length = positionIds.length;
require(length < 6, '!too_many');
for (uint256 i = 0; i < length; i++) {
uint256 positionId = positionIds[i];
Position storage position = positions[positionId];
if (position.price > 0 && !liquidatingIds[positionId]) {
liquidatingIds[positionId] = true;
_queueOrder(!position.isBuy, bytes32(position.symbol), 0, 0, positionId, msg.sender);
}
}
}
function getUserPositions(address user) external view returns(Position[] memory _positions) {
uint256 length = userPositionIds[user].length();
_positions = new Position[](length);
for (uint256 i=0; i < length; i++) {
uint256 id = userPositionIds[user].at(i);
Position memory positionWithId = positions[id];
positionWithId.id = id;
_positions[i] = positionWithId;
}
return _positions;
}
function getUserFreeMargin(address user) external view returns(uint256) {
return freeMargins[user];
}
/* Queue methods */
function processOrder(
uint256 id,
bytes32 symbol,
uint256 price,
uint256 margin,
uint256 positionId,
address liquidator
) external whenNotPaused onlyQueue {
if (positionId > 0) {
if (liquidator != address(0)) {
delete liquidatingIds[positionId];
Position memory position = positions[positionId];
require(position.price > 0, '!found');
uint256 positionMargin = uint256(position.margin);
(uint256 pnl, bool isPnlNegative) = _calculatePnl(position, positionMargin, price);
if (isPnlNegative && pnl >= positionMargin) {
_processLiquidation(liquidator, positionId, positionMargin, position.sender);
}
} else {
_processClose(margin, price, positionId);
}
} else {
_processOpen(id, symbol, price);
}
}
function cancelOrder(
uint256 id,
uint256 positionId,
address liquidator,
string calldata reason
) external onlyQueue {
if (positionId == 0) {
// cancelling a new order
Position storage position = positions[id];
address sender = position.sender;
uint256 margin = uint256(position.margin);
delete positions[id];
// release margin back to user
freeMargins[sender] = freeMargins[sender].add(margin);
emit OrderCancelled(id, id, sender, reason);
} else if (liquidator != address(0)) {
// cancelling a liquidation request
delete liquidatingIds[id];
emit OrderCancelled(id, positionId, liquidator, reason);
} else {
// cancelling a full or partial close order (sender could be address zero)
emit OrderCancelled(id, positionId, positions[positionId].sender, reason);
}
}
/* Internal methods */
function _queueOrder(
bool isBuy,
bytes32 symbol,
uint256 margin,
uint256 leverage,
uint256 positionId,
address liquidator
) internal returns (uint256 id) {
id = IQueue(queue).queueOrder(symbol, margin, positionId, liquidator);
if (liquidator != address(0)) {
emit LiquidationSubmitted(id, positionId, msg.sender);
} else {
emit OrderSubmitted(id, msg.sender, isBuy, symbol, margin, leverage, positionId);
}
return id;
}
function _processOpen(
uint256 id,
bytes32 symbol,
uint256 price
) internal {
Position storage position = positions[id];
bool isBuy = position.isBuy;
uint256 margin = uint256(position.margin);
uint256 leverage = uint256(position.leverage);
address sender = position.sender;
// calculate execution price
uint256 spread = IProducts(products).getSpread(symbol);
if (isBuy) {
price = price.mulDecimal8(SafeMathExt.UNIT8.add(spread));
} else {
price = price.mulDecimal8(SafeMathExt.UNIT8.sub(spread));
}
// complete the Position struct started in submitOrder
position.symbol = bytes12(symbol);
position.price = SafeMathExt.safeUint64(price);
position.block = uint48(block.number);
// user to position ID
userPositionIds[sender].add(id);
// event
emit PositionOpened(id, sender, isBuy, symbol, margin, leverage, price);
}
function _processClose(
uint256 margin,
uint256 price,
uint256 positionId
) internal {
Position memory mPosition = positions[positionId];
uint256 positionMargin = uint256(mPosition.margin);
require(margin <= positionMargin, '!margin');
uint256 spread = IProducts(products).getSpread(bytes32(mPosition.symbol));
// execution price
if (mPosition.isBuy) {
price = price.mulDecimal8(SafeMathExt.UNIT8.sub(spread));
} else {
price = price.mulDecimal8(SafeMathExt.UNIT8.add(spread));
}
// pnl
(uint256 pnl, bool isPnlNegative) = _calculatePnl(mPosition, margin, price);
uint256 amountToReturn;
if (isPnlNegative && pnl >= margin) {
// position is liquidated
delete positions[positionId];
userPositionIds[mPosition.sender].remove(positionId);
// transfer user margin to surplus
ITreasury(treasury).collectFromUser(mPosition.sender, positionMargin.mulDecimal8(currencyUnit));
} else {
if (margin < positionMargin) {
// partial close, update position margin
Position storage position = positions[positionId];
position.margin = SafeMathExt.safeUint64(positionMargin.sub(margin));
} else {
// full close, remove from mappings
delete positions[positionId];
userPositionIds[mPosition.sender].remove(positionId);
}
if (isPnlNegative) {
amountToReturn = margin.sub(pnl);
// return amountToReturn to free margin
freeMargins[mPosition.sender] = freeMargins[mPosition.sender].add(amountToReturn);
// collect pnl
ITreasury(treasury).collectFromUser(mPosition.sender, pnl.mulDecimal8(currencyUnit));
} else {
amountToReturn = margin.add(pnl);
freeMargins[mPosition.sender] = freeMargins[mPosition.sender].add(amountToReturn);
}
}
emit PositionClosed(positionId, mPosition.sender, margin, amountToReturn, mPosition.price, price, mPosition.leverage);
}
function _processLiquidation(
address liquidator,
uint256 positionId,
uint256 positionMargin,
address positionSender
) internal {
delete positions[positionId];
userPositionIds[positionSender].remove(positionId);
// collect margin from user
ITreasury(treasury).collectFromUser(positionSender, positionMargin.mulDecimal8(currencyUnit));
// pay liquidatorReward % of margin to liquidator
uint256 liquidatorMargin = positionMargin.mul(liquidatorReward).div(100);
freeMargins[liquidator] = freeMargins[liquidator].add(liquidatorMargin);
emit PositionLiquidated(positionId, positionSender, liquidator, positionMargin);
}
/* Helpers */
function _calculatePnl(
Position memory position,
uint256 margin,
uint256 price
) internal view returns (uint256 pnl, bool isPnlNegative) {
uint256 positionLeverage = uint256(position.leverage);
uint256 positionPrice = uint256(position.price);
if (position.isBuy) {
if (price >= position.price) {
pnl = margin.mul(positionLeverage).mul(price.sub(positionPrice)).div(positionPrice).div(SafeMathExt.UNIT8);
} else {
pnl = margin.mul(positionLeverage).mul(positionPrice.sub(price)).div(positionPrice).div(SafeMathExt.UNIT8);
isPnlNegative = true;
}
} else {
if (price > position.price) {
pnl = margin.mul(positionLeverage).mul(price.sub(positionPrice)).div(positionPrice).div(SafeMathExt.UNIT8);
isPnlNegative = true;
} else {
pnl = margin.mul(positionLeverage).mul(positionPrice.sub(price)).div(positionPrice).div(SafeMathExt.UNIT8);
}
}
// Calculate funding to apply on this position
uint256 fundingToApply = margin.mul(positionLeverage).mul(block.number.sub(uint256(position.block))).mul(IProducts(products).getFundingRate(bytes32(position.symbol))).div(1e16);
// Subtract funding from pnl
if (isPnlNegative) {
pnl = pnl.add(fundingToApply);
} else if (fundingToApply > pnl) {
isPnlNegative = true;
pnl = fundingToApply.sub(pnl);
} else {
pnl = pnl.sub(fundingToApply);
}
return (pnl, isPnlNegative);
}
/* Modifiers */
modifier onlyOwner() {
require(msg.sender == owner, '!authorized');
_;
}
modifier onlyQueue() {
require(msg.sender == queue, '!authorized');
_;
}
modifier whenNotUserPaused(address user) {
require(pausedUsers[user] == 0, '!pausedUser');
_;
}
modifier whenNotPaused() {
require(!paused, '!paused');
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}pragma solidity ^0.7.3;
interface IProducts {
function getMaxLeverage(bytes32 symbol, bool checkDisabled) external view returns (uint256);
function getFundingRate(bytes32 symbol) external view returns (uint256);
function getSpread(bytes32 symbol) external view returns (uint256);
}pragma solidity ^0.7.3;
interface IQueue {
function firstOrderId() external view returns (uint256);
function nextOrderId() external view returns (uint256);
function processedOrdersCount() external view returns (uint256);
function queueOrder(bytes32 symbol, uint256 margin, uint256 positionId, address liquidator) external returns (uint256);
}pragma solidity ^0.7.3;
import './IEIP712.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
interface IToken is IERC20, IEIP712 {
/* ========== OPTIONAL VIEWS ========== */
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
/* ========== VIEWS ========== */
function paused() external view returns (bool);
/* ========== MUTATIVE FUNCTIONS ========== */
function initialize(address synthTrading, string memory _name, string memory _symbol) external;
function increaseAllowance(address spender, uint256 addedValue) external returns (bool);
function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);
function mint(address to, uint256 amount) external;
function burn(uint256 amount) external;
function burnFrom(address account, uint256 amount) external;
function pause() external;
function unpause() external;
}pragma solidity ^0.7.3;
interface ITreasury {
function userDeposit(address user, uint256 amount) external;
function userWithdraw(address user, uint256 amount) external;
function collectFromUser(address user, uint256 amount) external;
function payToUser(address user, uint256 amount) external;
function getUserBalance(address user) external view returns (uint256);
}pragma solidity ^0.7.3;
import '../interfaces/IToken.sol';
import '../interfaces/IEIP712_DAI.sol';
library Permit {
function permit(
address currency,
uint256 amount,
address sender,
address spender,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
if (IToken(currency).allowance(sender, spender) < amount) {
if (keccak256(bytes(IToken(currency).symbol())) == 0xa5e92f3efb6826155f1f728e162af9d7cda33a574a1153b58f03ea01cc37e568) {
// DAI has a custom permit method
uint256 nonce = IToken(currency).nonces(sender);
IEIP712_DAI(currency).permit(sender, spender, nonce, deadline, true, v, r, s);
}/* else {
IToken(currency).permit(sender, spender, uint256(-1), deadline, v, r, s);
}*/
}
}
}pragma solidity ^0.7.3;
import '@openzeppelin/contracts/math/SafeMath.sol';
library SafeMathExt {
using SafeMath for uint256;
uint256 public constant UNIT8 = 1e8;
uint256 public constant UNIT18 = 1e18;
function base10pow(uint8 exponent) internal pure returns (uint256) {
// very common
if (exponent == 18) return 1e18;
if (exponent == 6) return 1e6;
uint256 result = 1;
while (exponent >= 10) {
result = result.mul(uint256(1e10));
exponent -= 10;
}
while (exponent > 0) {
result = result.mul(uint256(10));
exponent--;
}
return result;
}
function mulDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
return x.mul(y) / UNIT18;
}
function divDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
return x.mul(UNIT18).div(y);
}
function mulDecimal8(uint256 x, uint256 y) internal pure returns (uint256) {
return x.mul(y) / UNIT8;
}
function divDecimal8(uint256 x, uint256 y) internal pure returns (uint256) {
return x.mul(UNIT8).div(y);
}
function safeUint64(uint256 x) internal pure returns (uint64) {
require(x <= uint64(-1), 'SafeMath: cast overflow');
return uint64(x);
}
}pragma solidity ^0.7.3;
library UintSet {
struct Set {
uint256[] _values;
// Position of the value in the `values` array, plus 1 because index 0 means a value is not in the set
mapping (uint256 => uint256) _indexes;
}
function add(Set storage set, uint256 value) internal returns (bool) {
if (!contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function remove(Set storage set, uint256 value) internal returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) { // Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
uint256 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
function contains(Set storage set, uint256 value) internal view returns (bool) {
return set._indexes[value] != 0;
}
function length(Set storage set) internal view returns (uint256) {
return set._values.length;
}
function at(Set storage set, uint256 index) internal view returns (uint256) {
require(set._values.length > index, 'UintEnumerableSet: OUT_OF_BOUNDS');
return set._values[index];
}
}pragma solidity ^0.7.3;
interface IEIP712 {
/* ========== OPTIONAL VIEWS ========== */
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external view returns (bytes32);
function nonces(address wallet) external view returns (uint256);
/* ========== MUTATIVE FUNCTIONS ========== */
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}pragma solidity ^0.7.3;
interface IEIP712_DAI {
function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"LiquidationSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"products","type":"address"},{"indexed":false,"internalType":"address","name":"queue","type":"address"},{"indexed":false,"internalType":"address","name":"treasury","type":"address"}],"name":"NewContracts","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NewLiquidatorReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NewMinimum","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"OrderCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bool","name":"isBuy","type":"bool"},{"indexed":false,"internalType":"bytes32","name":"symbol","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"margin","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"leverage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"positionId","type":"uint256"}],"name":"OrderSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"marginClosed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountToReturn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"entryPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"leverage","type":"uint256"}],"name":"PositionClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"liquidator","type":"address"},{"indexed":false,"internalType":"uint256","name":"marginLiquidated","type":"uint256"}],"name":"PositionLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bool","name":"isBuy","type":"bool"},{"indexed":false,"internalType":"bytes32","name":"symbol","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"margin","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"leverage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"PositionOpened","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"string","name":"reason","type":"string"}],"name":"cancelOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"newBalanceCap","type":"uint256"}],"name":"capUserBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currency","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currencyUnit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"freeMargins","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserFreeMargin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserPositions","outputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bytes12","name":"symbol","type":"bytes12"},{"internalType":"uint64","name":"margin","type":"uint64"},{"internalType":"uint64","name":"leverage","type":"uint64"},{"internalType":"uint64","name":"price","type":"uint64"},{"internalType":"uint48","name":"block","type":"uint48"},{"internalType":"bool","name":"isBuy","type":"bool"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct Trading.Position[]","name":"_positions","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_currency","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"positionIds","type":"uint256[]"}],"name":"liquidatePositions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"liquidatingIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidatorReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumMargin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"}],"name":"pauseUsers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pausedUsers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"positions","outputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bytes12","name":"symbol","type":"bytes12"},{"internalType":"uint64","name":"margin","type":"uint64"},{"internalType":"uint64","name":"leverage","type":"uint64"},{"internalType":"uint64","name":"price","type":"uint64"},{"internalType":"uint48","name":"block","type":"uint48"},{"internalType":"bool","name":"isBuy","type":"bool"},{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes32","name":"symbol","type":"bytes32"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"margin","type":"uint256"},{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"address","name":"liquidator","type":"address"}],"name":"processOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_products","type":"address"},{"internalType":"address","name":"_queue","type":"address"},{"internalType":"address","name":"_treasury","type":"address"}],"name":"registerContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setCurrencyMin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setLiquidatorReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isBuy","type":"bool"},{"internalType":"bytes32","name":"symbol","type":"bytes32"},{"internalType":"uint256","name":"margin","type":"uint256"},{"internalType":"uint256","name":"leverage","type":"uint256"}],"name":"submitOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"uint256","name":"margin","type":"uint256"}],"name":"submitOrderUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"}],"name":"unpauseUsers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50613159806100206000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80638456cb59116100f9578063b75fd83d11610097578063cc389d8611610071578063cc389d86146103a2578063d6bdf9e9146103aa578063e5a6b10f146103bd578063e9e441bb146103c5576101c4565b8063b75fd83d14610369578063ba537f811461037c578063c4d66de81461038f576101c4565b806399fbab88116100d357806399fbab88146103145780639e0db2a21461033b578063b10a821e1461034e578063b72db2b314610356576101c4565b80638456cb59146102e457806389e64630146102ec5780638da5cb5b146102ff576101c4565b80634d452ec011610166578063621a438511610140578063621a43851461029857806368d822c6146102ab5780636f609bdd146102be5780637e34dbe0146102d1576101c4565b80634d452ec01461026a5780635c975abb1461027d5780635f90734b14610285576101c4565b80632e1a7d4d116101a25780632e1a7d4d1461021c5780633a3da55a1461022f5780633e39a8be1461024f5780633f4ba83a14610262576101c4565b806305c0608c146101c957806319785225146101e75780632a6bc2dd146101fc575b600080fd5b6101d16103d8565b6040516101de9190612d19565b60405180910390f35b6101fa6101f536600461286e565b6103de565b005b61020f61020a3660046127e9565b61046a565b6040516101de9190612c3d565b6101fa61022a366004612977565b6105f3565b61024261023d366004612977565b610747565b6040516101de9190612d0e565b6101d161025d3660046127e9565b61075c565b6101fa61076e565b6101fa61027836600461286e565b6107a7565b61024261089b565b6101fa6102933660046129a7565b6108ab565b6101fa6102a63660046128ad565b610a6a565b6101d16102b93660046127e9565b610d91565b6101fa6102cc3660046129f7565b610dac565b6101fa6102df366004612aa6565b610eb1565b6101fa610feb565b6101fa6102fa36600461286e565b61102a565b6103076110a7565b6040516101de9190612b29565b610327610322366004612977565b6110b6565b6040516101de989796959493929190612bdc565b6101fa610349366004612845565b611128565b6101d161128b565b6101fa610364366004612803565b611291565b6101fa610377366004612977565b611339565b6101fa61038a366004612a18565b6113a3565b6101fa61039d3660046127e9565b611566565b6101d1611649565b6101d16103b83660046127e9565b61164f565b610307611661565b6101fa6103d3366004612977565b611670565b60045481565b600c546001600160a01b031633146104115760405162461bcd60e51b815260040161040890612f46565b60405180910390fd5b60005b81811015610465576000600a600085858581811061042e57fe5b905060200201602081019061044391906127e9565b6001600160a01b03168152602081019190915260400160002055600101610414565b505050565b6001600160a01b03811660009081526008602052604081206060919061048f906116f0565b9050806001600160401b03811180156104a757600080fd5b506040519080825280602002602001820160405280156104e157816020015b6104ce612746565b8152602001906001900390816104c65790505b50915060005b818110156105eb576001600160a01b038416600090815260086020526040812061051190836116f4565b905061051b612746565b5060008181526007602090815260409182902082516101008101845281546001600160a01b0381168252600160a01b900460a090811b6001600160a01b031916938201939093526001909101546001600160401b0380821694830194909452600160401b810484166060830152600160801b81049093166080820152600160c01b830465ffffffffffff1691810191909152600160f01b90910460ff16151560c082015260e08101829052845181908690859081106105d657fe5b602090810291909101015250506001016104e7565b50505b919050565b600c54600160a81b900460ff161561061d5760405162461bcd60e51b815260040161040890612e08565b336000818152600a60205260409020541561064a5760405162461bcd60e51b815260040161040890612ed4565b60408051808201825260088152672162616c616e636560c01b6020808301919091523360009081526006909152919091205461068791849061173a565b336000818152600660205260409020919091556002546005546001600160a01b0390911691633e458a8e916106bd908690611766565b6040518363ffffffff1660e01b81526004016106da929190612b3d565b600060405180830381600087803b1580156106f457600080fd5b505af1158015610708573d6000803e3d6000fd5b505050507fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a232518260405161073b9190612d19565b60405180910390a15050565b60096020526000908152604090205460ff1681565b600a6020526000908152604090205481565b600c546001600160a01b031633146107985760405162461bcd60e51b815260040161040890612f46565b600c805460ff60a81b19169055565b80600681106107c85760405162461bcd60e51b815260040161040890612f6b565b60005b818110156108955760008484838181106107e157fe5b60209081029290920135600081815260079093526040909220600181015492935091600160801b90046001600160401b03161580159150610831575060008281526009602052604090205460ff16155b1561088b576000828152600960205260408120805460ff19166001908117909155820154825461088992600160f01b90920460ff1615916001600160a01b0319600160a01b90920460a01b9190911690808633611786565b505b50506001016107cb565b50505050565b600c54600160a81b900460ff1681565b600c54600160a81b900460ff16156108d55760405162461bcd60e51b815260040161040890612e08565b6001546001600160a01b031633146108ff5760405162461bcd60e51b815260040161040890612f46565b8115610a57576001600160a01b03811615610a47576000828152600960205260409020805460ff19169055610932612746565b5060008281526007602090815260409182902082516101008101845281546001600160a01b0381168252600160a01b900460a090811b6001600160a01b0319169382019390935260018201546001600160401b0380821695830195909552600160401b810485166060830152600160801b810490941660808201819052600160c01b850465ffffffffffff1693820193909352600160f01b90930460ff16151560c08401526002015460e08301526109fc5760405162461bcd60e51b815260040161040890612ffa565b60408101516001600160401b0316600080610a1884848a6118be565b91509150808015610a295750828210155b15610a3e57610a3e8587858760000151611ab5565b50505050610a52565b610a52838584611c18565b610a62565b610a62868686612064565b505050505050565b600c54600160a81b900460ff1615610a945760405162461bcd60e51b815260040161040890612e08565b336000818152600a602052604090205415610ac15760405162461bcd60e51b815260040161040890612ed4565b600454831015610ae35760405162461bcd60e51b815260040161040890612eb3565b6305f5e100821015610b075760405162461bcd60e51b815260040161040890612ef9565b6000805460405163188cac2d60e31b81526001600160a01b039091169063c465616890610b3b908890600190600401612d22565b60206040518083038186803b158015610b5357600080fd5b505afa158015610b67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8b919061298f565b905060008111610bad5760405162461bcd60e51b81526004016104089061301a565b80831115610bcd5760405162461bcd60e51b815260040161040890612e6a565b60408051808201825260088152672162616c616e636560c01b60208083019190915233600090815260069091529190912054610c0a91869061173a565b33600090815260066020526040812091909155610c2b878787878580611786565b6040805161010081018252338152600060208201529192508101610c4e8761222d565b6001600160401b03168152602001610c658661222d565b6001600160401b0390811682526000602080840182905260408085018390529b1515606080860191909152608094850183905295825260078152908b902084518154928601516001600160a01b03199093166001600160a01b039182161716600160a01b60a093841c021781559a84015160018c01805496860151948601519286015160c087015167ffffffffffffffff19909816928516929092176fffffffffffffffff00000000000000001916600160401b958516959095029490941767ffffffffffffffff60801b1916600160801b92909316919091029190911765ffffffffffff60c01b1916600160c01b65ffffffffffff909216919091021760ff60f01b1916600160f01b931515939093029290921790915560e001516002909601959095555050505050565b6001600160a01b031660009081526006602052604090205490565b600c54600160a81b900460ff1615610dd65760405162461bcd60e51b815260040161040890612e08565b60008281526007602052604090206001810154600160801b90046001600160401b0316610e155760405162461bcd60e51b815260040161040890612ffa565b80546001600160a01b03163314610e3e5760405162461bcd60e51b815260040161040890612f46565b60018101546001600160401b0316821115610e6b5760405162461bcd60e51b815260040161040890612eb3565b6001810154815461089591600160f01b810460ff161591600160a01b900460a01b6001600160a01b031916908590600160401b90046001600160401b0316876000611786565b600c54600160a81b900460ff1615610edb5760405162461bcd60e51b815260040161040890612e08565b6000610ef26005548761176690919063ffffffff16565b600354600254919250610f19916001600160a01b039182169184913391168989898961225a565b60025460405163b52d734360e01b81526001600160a01b039091169063b52d734390610f4b9033908590600401612b3d565b600060405180830381600087803b158015610f6557600080fd5b505af1158015610f79573d6000803e3d6000fd5b505033600090815260066020526040902054610f98925090508761247e565b336000908152600660205260409081902091909155517f2a89b2e3d580398d6dc2db5e0f336b52602bbaa51afa9bb5cdf59239cf0d2bea90610fdb908890612d19565b60405180910390a1505050505050565b600c546001600160a01b031633146110155760405162461bcd60e51b815260040161040890612f46565b600c805460ff60a81b1916600160a81b179055565b600c546001600160a01b031633146110545760405162461bcd60e51b815260040161040890612f46565b60005b818110156104655743600a600085858581811061107057fe5b905060200201602081019061108591906127e9565b6001600160a01b03168152602081019190915260400160002055600101611057565b600c546001600160a01b031681565b6007602052600090815260409020805460018201546002909201546001600160a01b03821692600160a01b90920460a01b916001600160401b0380821692600160401b8304821692600160801b810490921691600160c01b810465ffffffffffff1691600160f01b90910460ff169088565b600c546001600160a01b031633146111525760405162461bcd60e51b815260040161040890612f46565b6001600160a01b0382166000908152600a6020526040902054801580159061117957504381105b6111955760405162461bcd60e51b815260040161040890612f1c565b6002546040516323b9a44960e11b81526000916001600160a01b0316906347734892906111c6908790600401612b29565b60206040518083038186803b1580156111de57600080fd5b505afa1580156111f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611216919061298f565b90508061122e6005548561176690919063ffffffff16565b101561124c5760405162461bcd60e51b815260040161040890612e91565b6001600160a01b0384166000908152600660205260409020548310156108955750506001600160a01b0391909116600090815260066020526040902055565b600b5481565b600c546001600160a01b031633146112bb5760405162461bcd60e51b815260040161040890612f46565b600080546001600160a01b038086166001600160a01b0319928316179092556001805485841690831617905560028054928416929091169190911790556040517fab89ae7c33202f499ee63ff28e56285c9c67716e8a6fdcbcce8f73bfadd6b2439061132c90859085908590612b70565b60405180910390a1505050565b600c546001600160a01b031633146113635760405162461bcd60e51b815260040161040890612f46565b60048190556040517f334b167d1f7f5e3c74a46551e4002af2b3b38d53072d67aa67e691f43591687b90611398908390612d19565b60405180910390a150565b6001546001600160a01b031633146113cd5760405162461bcd60e51b815260040161040890612f46565b8361149357600085815260076020908152604080832080546001820180548684556001600160f81b03198116909155600283018690556001600160a01b03909116808652600690945291909320546001600160401b0390911690611431908261247e565b6001600160a01b038316600081815260066020526040908190209290925590517ef7bcdad0753e20ba80e87c6efe2385dd122fae77e6219e92368c4ba0cd7ce390611483908b9081908a908a90613071565b60405180910390a250505061155f565b6001600160a01b038316156115055760008581526009602052604090819020805460ff19169055516001600160a01b038416907ef7bcdad0753e20ba80e87c6efe2385dd122fae77e6219e92368c4ba0cd7ce3906114f8908890889087908790613071565b60405180910390a261155f565b600084815260076020526040908190205490516001600160a01b03909116907ef7bcdad0753e20ba80e87c6efe2385dd122fae77e6219e92368c4ba0cd7ce390611556908890889087908790613071565b60405180910390a25b5050505050565b600c54600160a01b900460ff16156115905760405162461bcd60e51b815260040161040890612d89565b600c80546001600160a01b031960ff60a01b19909116600160a01b1781163317909155600a600b55600380546001600160a01b0384169216821790556040805163313ce56760e01b81529051611643929163313ce567916004808301926020929190829003018186803b15801561160657600080fd5b505afa15801561161a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163e9190612aee565b6124aa565b60055550565b60055481565b60066020526000908152604090205481565b6003546001600160a01b031681565b600c546001600160a01b0316331461169a5760405162461bcd60e51b815260040161040890612f46565b60648111156116bb5760405162461bcd60e51b815260040161040890612daf565b600b8190556040517f234f84cb45c3f3ae398218c31d7e8bf5f31b037e05fc5961d3569f4fa6616d7c90611398908390612d19565b5490565b815460009082106117175760405162461bcd60e51b815260040161040890612fc5565b82600001828154811061172657fe5b906000526020600020015490505b92915050565b6000818484111561175e5760405162461bcd60e51b81526004016104089190612d56565b505050900390565b60006305f5e1006117778484612529565b8161177e57fe5b049392505050565b60015460405163332463ad60e21b81526000916001600160a01b03169063cc918eb4906117bd908990899088908890600401612d32565b602060405180830381600087803b1580156117d757600080fd5b505af11580156117eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180f919061298f565b90506001600160a01b0382161561186857336001600160a01b03167f15c7da4af2133090a14dba8b02646e4d2ded2b9e8173addcd1b8d42719635112828560405161185b929190613063565b60405180910390a26118b4565b336001600160a01b03167f383af269d455c7ea93aa547244a2d345d395985c71392361c9e08b134826a65d8289898989896040516118ab9695949392919061303b565b60405180910390a25b9695505050505050565b600080600085606001516001600160401b03169050600086608001516001600160401b031690508660c001511561195a5786608001516001600160401b03168510611937576119306305f5e10061192a838161191a8a83612563565b6119248c89612529565b90612529565b906125a5565b9350611955565b61194e6305f5e10061192a838161191a828b612563565b9350600192505b6119a0565b86608001516001600160401b03168511156119865761194e6305f5e10061192a838161191a8a83612563565b61199d6305f5e10061192a838161191a828b612563565b93505b6000805460208901516040516384f6e7b360e01b8152611a6e92662386f26fc100009261192a926001600160a01b03909216916384f6e7b3916119f2916001600160a01b031990911690600401612d19565b60206040518083038186803b158015611a0a57600080fd5b505afa158015611a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a42919061298f565b611924611a648d60a0015165ffffffffffff164361256390919063ffffffff16565b6119248d8a612529565b90508315611a8757611a80858261247e565b9450611aaa565b84811115611a9d5760019350611a808186612563565b611aa78582612563565b94505b505050935093915050565b60008381526007602090815260408083208381556001810180546001600160f81b03191690556002018390556001600160a01b038416835260089091529020611afe90846125e7565b506002546005546001600160a01b039091169063b5c20dd3908390611b24908690611766565b6040518363ffffffff1660e01b8152600401611b41929190612b3d565b600060405180830381600087803b158015611b5b57600080fd5b505af1158015611b6f573d6000803e3d6000fd5b505050506000611b8f606461192a600b548661252990919063ffffffff16565b6001600160a01b038616600090815260066020526040902054909150611bb5908261247e565b6001600160a01b0380871660008181526006602052604090819020939093559151908416907f9f843df2e2b0c791e0c3993c883e11d06a6fcc960fb3a2765a6f4ab8a1bd07ca90611c099088908890613063565b60405180910390a35050505050565b611c20612746565b5060008181526007602090815260409182902082516101008101845281546001600160a01b0381168252600160a01b900460a090811b6001600160a01b0319169382019390935260018201546001600160401b03808216958301869052600160401b820481166060840152600160801b8204166080830152600160c01b810465ffffffffffff1693820193909352600160f01b90920460ff16151560c08301526002015460e08201529080851115611cea5760405162461bcd60e51b815260040161040890612eb3565b60008054602084015160405163443182fd60e01b81526001600160a01b039092169163443182fd91611d2b916001600160a01b031990911690600401612d19565b60206040518083038186803b158015611d4357600080fd5b505afa158015611d57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7b919061298f565b90508260c0015115611da657611d9f611d986305f5e10083612563565b8690611766565b9450611dba565b611db7611d986305f5e1008361247e565b94505b600080611dc88589896118be565b915091506000818015611ddb5750888310155b15611ea55760008781526007602090815260408083208381556001810180546001600160f81b031916905560020183905588516001600160a01b0316835260089091529020611e2a90886125e7565b5060025486516005546001600160a01b039092169163b5c20dd39190611e51908990611766565b6040518363ffffffff1660e01b8152600401611e6e929190612b3d565b600060405180830381600087803b158015611e8857600080fd5b505af1158015611e9c573d6000803e3d6000fd5b50505050612002565b84891015611ef6576000878152600760205260409020611ecd611ec8878c612563565b61222d565b600191909101805467ffffffffffffffff19166001600160401b03909216919091179055611f42565b60008781526007602090815260408083208381556001810180546001600160f81b031916905560020183905588516001600160a01b0316835260089091529020611f4090886125e7565b505b8115611fb657611f528984612563565b86516001600160a01b0316600090815260066020526040902054909150611f79908261247e565b86516001600160a01b039081166000908152600660205260409020919091556002548751600554919092169163b5c20dd391611e51908790611766565b611fc0898461247e565b86516001600160a01b0316600090815260066020526040902054909150611fe7908261247e565b86516001600160a01b03166000908152600660205260409020555b85600001516001600160a01b03167fb740da1ca3b7364c36886a66a0a5a33c31a8985a91673f3bc2ae6ae876007657888b848a608001518d8c60600151604051612051969594939291906130ae565b60405180910390a2505050505050505050565b600083815260076020526040808220600181015481548454935163443182fd60e01b81529294600160f01b830460ff16946001600160401b0380851695600160401b90950416936001600160a01b03938416939091169063443182fd906120cf908b90600401612d19565b60206040518083038186803b1580156120e757600080fd5b505afa1580156120fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211f919061298f565b905084156121465761213f6121386305f5e1008361247e565b8890611766565b965061215a565b6121576121386305f5e10083612563565b96505b85546001600160a01b0316600160a01b60a08a901c0217865561217c8761222d565b60018701805467ffffffffffffffff60801b1916600160801b6001600160401b0393909316929092029190911765ffffffffffff60c01b1916600160c01b4365ffffffffffff16021790556001600160a01b03821660009081526008602052604090206121e9908a6126ad565b50816001600160a01b03167f94046b799d1f5befe29f320688602f36227b2884ebbfa15c12ad25f6aede27c58a878b88888d6040516120519695949392919061303b565b60006001600160401b038211156122565760405162461bcd60e51b815260040161040890612f8e565b5090565b604051636eb1769f60e11b815287906001600160a01b038a169063dd62ed3e9061228a908a908a90600401612b56565b60206040518083038186803b1580156122a257600080fd5b505afa1580156122b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122da919061298f565b101561247457876001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561231957600080fd5b505afa15801561232d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261235591908101906128eb565b80516020909101207fa5e92f3efb6826155f1f728e162af9d7cda33a574a1153b58f03ea01cc37e568141561247457604051623f675f60e91b81526000906001600160a01b038a1690637ecebe00906123b2908a90600401612b29565b60206040518083038186803b1580156123ca57600080fd5b505afa1580156123de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612402919061298f565b6040516323f2ebc360e21b81529091506001600160a01b038a1690638fcbaf0c90612440908a908a9086908b906001908c908c908c90600401612b93565b600060405180830381600087803b15801561245a57600080fd5b505af115801561246e573d6000803e3d6000fd5b50505050505b5050505050505050565b6000828201838110156124a35760405162461bcd60e51b815260040161040890612dd1565b9392505050565b60008160ff16601214156124c75750670de0b6b3a76400006105ee565b8160ff16600614156124dd5750620f42406105ee565b60015b600a8360ff1610612507576124fa816402540be400612529565b9050600a830392506124e0565b60ff8316156117345761251b81600a612529565b600019909301929050612507565b60008261253857506000611734565b8282028284828161254557fe5b04146124a35760405162461bcd60e51b815260040161040890612e29565b60006124a383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061173a565b60006124a383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506126f7565b600081815260018301602052604081205480156126a3578354600019808301919081019060009087908390811061261a57fe5b906000526020600020015490508087600001848154811061263757fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061266757fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611734565b6000915050611734565b60006126b9838361272e565b6126ef57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611734565b506000611734565b600081836127185760405162461bcd60e51b81526004016104089190612d56565b50600083858161272457fe5b0495945050505050565b60009081526001919091016020526040902054151590565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b80356001600160a01b03811681146105ee57600080fd5b60008083601f8401126127b2578182fd5b5081356001600160401b038111156127c8578182fd5b60208301915083602080830285010111156127e257600080fd5b9250929050565b6000602082840312156127fa578081fd5b6124a38261278a565b600080600060608486031215612817578182fd5b6128208461278a565b925061282e6020850161278a565b915061283c6040850161278a565b90509250925092565b60008060408385031215612857578182fd5b6128608361278a565b946020939093013593505050565b60008060208385031215612880578182fd5b82356001600160401b03811115612895578283fd5b6128a1858286016127a1565b90969095509350505050565b600080600080608085870312156128c2578081fd5b843580151581146128d1578182fd5b966020860135965060408601359560600135945092505050565b6000602082840312156128fc578081fd5b81516001600160401b0380821115612912578283fd5b818401915084601f830112612925578283fd5b81518181111561293157fe5b604051601f8201601f19168101602001838111828210171561294f57fe5b604052818152838201602001871015612966578485fd5b6118b48260208301602087016130e5565b600060208284031215612988578081fd5b5035919050565b6000602082840312156129a0578081fd5b5051919050565b60008060008060008060c087890312156129bf578182fd5b86359550602087013594506040870135935060608701359250608087013591506129eb60a0880161278a565b90509295509295509295565b60008060408385031215612a09578182fd5b50508035926020909101359150565b600080600080600060808688031215612a2f578081fd5b8535945060208601359350612a466040870161278a565b925060608601356001600160401b0380821115612a61578283fd5b818801915088601f830112612a74578283fd5b813581811115612a82578384fd5b896020828501011115612a93578384fd5b9699959850939650602001949392505050565b600080600080600060a08688031215612abd578283fd5b85359450602086013593506040860135612ad681613111565b94979396509394606081013594506080013592915050565b600060208284031215612aff578081fd5b81516124a381613111565b15159052565b65ffffffffffff169052565b6001600160401b03169052565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0393841681529183166020830152909116604082015260600190565b6001600160a01b039889168152969097166020870152604086019490945260608501929092521515608084015260ff1660a083015260c082015260e08101919091526101000190565b6001600160a01b039890981688526001600160a01b03199690961660208801526001600160401b03948516604088015292841660608701529216608085015265ffffffffffff90911660a0840152151560c083015260e08201526101000190565b602080825282518282018190526000919060409081850190868401855b82811015612d0157815180516001600160a01b03168552868101516001600160a01b03191687860152858101516001600160401b031686860152606080820151612ca682880182612b1c565b5050608080820151612cba82880182612b1c565b505060a080820151612cce82880182612b10565b505060c080820151612ce282880182612b0a565b505060e090810151908501526101009093019290850190600101612c5a565b5091979650505050505050565b901515815260200190565b90815260200190565b9182521515602082015260400190565b938452602084019290925260408301526001600160a01b0316606082015260800190565b6000602082528251806020840152612d758160408501602087016130e5565b601f01601f19169190910160400192915050565b6020808252600c908201526b085a5b9a5d1a585b1a5e995960a21b604082015260600190565b602080825260089082015267085c195c98d95b9d60c21b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b602080825260079082015266085c185d5cd95960ca1b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252600d908201526c216d61785f6c6576657261676560981b604082015260600190565b60208082526008908201526721746f6f5f6c6f7760c01b604082015260600190565b60208082526007908201526610b6b0b933b4b760c91b604082015260600190565b6020808252600b908201526a10b830bab9b2b22ab9b2b960a91b604082015260600190565b602080825260099082015268216c6576657261676560b81b604082015260600190565b60208082526010908201526f085d5cd95c97db9bdd17dc185d5cd95960821b604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b60208082526009908201526821746f6f5f6d616e7960b81b604082015260600190565b60208082526017908201527f536166654d6174683a2063617374206f766572666c6f77000000000000000000604082015260600190565b6020808252818101527f55696e74456e756d657261626c655365743a204f55545f4f465f424f554e4453604082015260600190565b60208082526006908201526508599bdd5b9960d21b604082015260600190565b602080825260079082015266085cde5b589bdb60ca1b604082015260600190565b958652931515602086015260408501929092526060840152608083015260a082015260c00190565b918252602082015260400190565b60008582528460208301526060604083015282606083015282846080840137818301608090810191909152601f909201601f191601019392505050565b958652602086019490945260408501929092526001600160401b03908116606085015260808401919091521660a082015260c00190565b60005b838110156131005781810151838201526020016130e8565b838111156108955750506000910152565b60ff8116811461312057600080fd5b5056fea2646970667358221220a90a35f9a76195efe9dffbde0f321e645ef3f8aef0745e67fbbe75a7a19ea28b64736f6c63430007030033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80638456cb59116100f9578063b75fd83d11610097578063cc389d8611610071578063cc389d86146103a2578063d6bdf9e9146103aa578063e5a6b10f146103bd578063e9e441bb146103c5576101c4565b8063b75fd83d14610369578063ba537f811461037c578063c4d66de81461038f576101c4565b806399fbab88116100d357806399fbab88146103145780639e0db2a21461033b578063b10a821e1461034e578063b72db2b314610356576101c4565b80638456cb59146102e457806389e64630146102ec5780638da5cb5b146102ff576101c4565b80634d452ec011610166578063621a438511610140578063621a43851461029857806368d822c6146102ab5780636f609bdd146102be5780637e34dbe0146102d1576101c4565b80634d452ec01461026a5780635c975abb1461027d5780635f90734b14610285576101c4565b80632e1a7d4d116101a25780632e1a7d4d1461021c5780633a3da55a1461022f5780633e39a8be1461024f5780633f4ba83a14610262576101c4565b806305c0608c146101c957806319785225146101e75780632a6bc2dd146101fc575b600080fd5b6101d16103d8565b6040516101de9190612d19565b60405180910390f35b6101fa6101f536600461286e565b6103de565b005b61020f61020a3660046127e9565b61046a565b6040516101de9190612c3d565b6101fa61022a366004612977565b6105f3565b61024261023d366004612977565b610747565b6040516101de9190612d0e565b6101d161025d3660046127e9565b61075c565b6101fa61076e565b6101fa61027836600461286e565b6107a7565b61024261089b565b6101fa6102933660046129a7565b6108ab565b6101fa6102a63660046128ad565b610a6a565b6101d16102b93660046127e9565b610d91565b6101fa6102cc3660046129f7565b610dac565b6101fa6102df366004612aa6565b610eb1565b6101fa610feb565b6101fa6102fa36600461286e565b61102a565b6103076110a7565b6040516101de9190612b29565b610327610322366004612977565b6110b6565b6040516101de989796959493929190612bdc565b6101fa610349366004612845565b611128565b6101d161128b565b6101fa610364366004612803565b611291565b6101fa610377366004612977565b611339565b6101fa61038a366004612a18565b6113a3565b6101fa61039d3660046127e9565b611566565b6101d1611649565b6101d16103b83660046127e9565b61164f565b610307611661565b6101fa6103d3366004612977565b611670565b60045481565b600c546001600160a01b031633146104115760405162461bcd60e51b815260040161040890612f46565b60405180910390fd5b60005b81811015610465576000600a600085858581811061042e57fe5b905060200201602081019061044391906127e9565b6001600160a01b03168152602081019190915260400160002055600101610414565b505050565b6001600160a01b03811660009081526008602052604081206060919061048f906116f0565b9050806001600160401b03811180156104a757600080fd5b506040519080825280602002602001820160405280156104e157816020015b6104ce612746565b8152602001906001900390816104c65790505b50915060005b818110156105eb576001600160a01b038416600090815260086020526040812061051190836116f4565b905061051b612746565b5060008181526007602090815260409182902082516101008101845281546001600160a01b0381168252600160a01b900460a090811b6001600160a01b031916938201939093526001909101546001600160401b0380821694830194909452600160401b810484166060830152600160801b81049093166080820152600160c01b830465ffffffffffff1691810191909152600160f01b90910460ff16151560c082015260e08101829052845181908690859081106105d657fe5b602090810291909101015250506001016104e7565b50505b919050565b600c54600160a81b900460ff161561061d5760405162461bcd60e51b815260040161040890612e08565b336000818152600a60205260409020541561064a5760405162461bcd60e51b815260040161040890612ed4565b60408051808201825260088152672162616c616e636560c01b6020808301919091523360009081526006909152919091205461068791849061173a565b336000818152600660205260409020919091556002546005546001600160a01b0390911691633e458a8e916106bd908690611766565b6040518363ffffffff1660e01b81526004016106da929190612b3d565b600060405180830381600087803b1580156106f457600080fd5b505af1158015610708573d6000803e3d6000fd5b505050507fb6b476da71cea8275cac6b1720c04966afaff5e637472cedb6cbd32c43a232518260405161073b9190612d19565b60405180910390a15050565b60096020526000908152604090205460ff1681565b600a6020526000908152604090205481565b600c546001600160a01b031633146107985760405162461bcd60e51b815260040161040890612f46565b600c805460ff60a81b19169055565b80600681106107c85760405162461bcd60e51b815260040161040890612f6b565b60005b818110156108955760008484838181106107e157fe5b60209081029290920135600081815260079093526040909220600181015492935091600160801b90046001600160401b03161580159150610831575060008281526009602052604090205460ff16155b1561088b576000828152600960205260408120805460ff19166001908117909155820154825461088992600160f01b90920460ff1615916001600160a01b0319600160a01b90920460a01b9190911690808633611786565b505b50506001016107cb565b50505050565b600c54600160a81b900460ff1681565b600c54600160a81b900460ff16156108d55760405162461bcd60e51b815260040161040890612e08565b6001546001600160a01b031633146108ff5760405162461bcd60e51b815260040161040890612f46565b8115610a57576001600160a01b03811615610a47576000828152600960205260409020805460ff19169055610932612746565b5060008281526007602090815260409182902082516101008101845281546001600160a01b0381168252600160a01b900460a090811b6001600160a01b0319169382019390935260018201546001600160401b0380821695830195909552600160401b810485166060830152600160801b810490941660808201819052600160c01b850465ffffffffffff1693820193909352600160f01b90930460ff16151560c08401526002015460e08301526109fc5760405162461bcd60e51b815260040161040890612ffa565b60408101516001600160401b0316600080610a1884848a6118be565b91509150808015610a295750828210155b15610a3e57610a3e8587858760000151611ab5565b50505050610a52565b610a52838584611c18565b610a62565b610a62868686612064565b505050505050565b600c54600160a81b900460ff1615610a945760405162461bcd60e51b815260040161040890612e08565b336000818152600a602052604090205415610ac15760405162461bcd60e51b815260040161040890612ed4565b600454831015610ae35760405162461bcd60e51b815260040161040890612eb3565b6305f5e100821015610b075760405162461bcd60e51b815260040161040890612ef9565b6000805460405163188cac2d60e31b81526001600160a01b039091169063c465616890610b3b908890600190600401612d22565b60206040518083038186803b158015610b5357600080fd5b505afa158015610b67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8b919061298f565b905060008111610bad5760405162461bcd60e51b81526004016104089061301a565b80831115610bcd5760405162461bcd60e51b815260040161040890612e6a565b60408051808201825260088152672162616c616e636560c01b60208083019190915233600090815260069091529190912054610c0a91869061173a565b33600090815260066020526040812091909155610c2b878787878580611786565b6040805161010081018252338152600060208201529192508101610c4e8761222d565b6001600160401b03168152602001610c658661222d565b6001600160401b0390811682526000602080840182905260408085018390529b1515606080860191909152608094850183905295825260078152908b902084518154928601516001600160a01b03199093166001600160a01b039182161716600160a01b60a093841c021781559a84015160018c01805496860151948601519286015160c087015167ffffffffffffffff19909816928516929092176fffffffffffffffff00000000000000001916600160401b958516959095029490941767ffffffffffffffff60801b1916600160801b92909316919091029190911765ffffffffffff60c01b1916600160c01b65ffffffffffff909216919091021760ff60f01b1916600160f01b931515939093029290921790915560e001516002909601959095555050505050565b6001600160a01b031660009081526006602052604090205490565b600c54600160a81b900460ff1615610dd65760405162461bcd60e51b815260040161040890612e08565b60008281526007602052604090206001810154600160801b90046001600160401b0316610e155760405162461bcd60e51b815260040161040890612ffa565b80546001600160a01b03163314610e3e5760405162461bcd60e51b815260040161040890612f46565b60018101546001600160401b0316821115610e6b5760405162461bcd60e51b815260040161040890612eb3565b6001810154815461089591600160f01b810460ff161591600160a01b900460a01b6001600160a01b031916908590600160401b90046001600160401b0316876000611786565b600c54600160a81b900460ff1615610edb5760405162461bcd60e51b815260040161040890612e08565b6000610ef26005548761176690919063ffffffff16565b600354600254919250610f19916001600160a01b039182169184913391168989898961225a565b60025460405163b52d734360e01b81526001600160a01b039091169063b52d734390610f4b9033908590600401612b3d565b600060405180830381600087803b158015610f6557600080fd5b505af1158015610f79573d6000803e3d6000fd5b505033600090815260066020526040902054610f98925090508761247e565b336000908152600660205260409081902091909155517f2a89b2e3d580398d6dc2db5e0f336b52602bbaa51afa9bb5cdf59239cf0d2bea90610fdb908890612d19565b60405180910390a1505050505050565b600c546001600160a01b031633146110155760405162461bcd60e51b815260040161040890612f46565b600c805460ff60a81b1916600160a81b179055565b600c546001600160a01b031633146110545760405162461bcd60e51b815260040161040890612f46565b60005b818110156104655743600a600085858581811061107057fe5b905060200201602081019061108591906127e9565b6001600160a01b03168152602081019190915260400160002055600101611057565b600c546001600160a01b031681565b6007602052600090815260409020805460018201546002909201546001600160a01b03821692600160a01b90920460a01b916001600160401b0380821692600160401b8304821692600160801b810490921691600160c01b810465ffffffffffff1691600160f01b90910460ff169088565b600c546001600160a01b031633146111525760405162461bcd60e51b815260040161040890612f46565b6001600160a01b0382166000908152600a6020526040902054801580159061117957504381105b6111955760405162461bcd60e51b815260040161040890612f1c565b6002546040516323b9a44960e11b81526000916001600160a01b0316906347734892906111c6908790600401612b29565b60206040518083038186803b1580156111de57600080fd5b505afa1580156111f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611216919061298f565b90508061122e6005548561176690919063ffffffff16565b101561124c5760405162461bcd60e51b815260040161040890612e91565b6001600160a01b0384166000908152600660205260409020548310156108955750506001600160a01b0391909116600090815260066020526040902055565b600b5481565b600c546001600160a01b031633146112bb5760405162461bcd60e51b815260040161040890612f46565b600080546001600160a01b038086166001600160a01b0319928316179092556001805485841690831617905560028054928416929091169190911790556040517fab89ae7c33202f499ee63ff28e56285c9c67716e8a6fdcbcce8f73bfadd6b2439061132c90859085908590612b70565b60405180910390a1505050565b600c546001600160a01b031633146113635760405162461bcd60e51b815260040161040890612f46565b60048190556040517f334b167d1f7f5e3c74a46551e4002af2b3b38d53072d67aa67e691f43591687b90611398908390612d19565b60405180910390a150565b6001546001600160a01b031633146113cd5760405162461bcd60e51b815260040161040890612f46565b8361149357600085815260076020908152604080832080546001820180548684556001600160f81b03198116909155600283018690556001600160a01b03909116808652600690945291909320546001600160401b0390911690611431908261247e565b6001600160a01b038316600081815260066020526040908190209290925590517ef7bcdad0753e20ba80e87c6efe2385dd122fae77e6219e92368c4ba0cd7ce390611483908b9081908a908a90613071565b60405180910390a250505061155f565b6001600160a01b038316156115055760008581526009602052604090819020805460ff19169055516001600160a01b038416907ef7bcdad0753e20ba80e87c6efe2385dd122fae77e6219e92368c4ba0cd7ce3906114f8908890889087908790613071565b60405180910390a261155f565b600084815260076020526040908190205490516001600160a01b03909116907ef7bcdad0753e20ba80e87c6efe2385dd122fae77e6219e92368c4ba0cd7ce390611556908890889087908790613071565b60405180910390a25b5050505050565b600c54600160a01b900460ff16156115905760405162461bcd60e51b815260040161040890612d89565b600c80546001600160a01b031960ff60a01b19909116600160a01b1781163317909155600a600b55600380546001600160a01b0384169216821790556040805163313ce56760e01b81529051611643929163313ce567916004808301926020929190829003018186803b15801561160657600080fd5b505afa15801561161a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163e9190612aee565b6124aa565b60055550565b60055481565b60066020526000908152604090205481565b6003546001600160a01b031681565b600c546001600160a01b0316331461169a5760405162461bcd60e51b815260040161040890612f46565b60648111156116bb5760405162461bcd60e51b815260040161040890612daf565b600b8190556040517f234f84cb45c3f3ae398218c31d7e8bf5f31b037e05fc5961d3569f4fa6616d7c90611398908390612d19565b5490565b815460009082106117175760405162461bcd60e51b815260040161040890612fc5565b82600001828154811061172657fe5b906000526020600020015490505b92915050565b6000818484111561175e5760405162461bcd60e51b81526004016104089190612d56565b505050900390565b60006305f5e1006117778484612529565b8161177e57fe5b049392505050565b60015460405163332463ad60e21b81526000916001600160a01b03169063cc918eb4906117bd908990899088908890600401612d32565b602060405180830381600087803b1580156117d757600080fd5b505af11580156117eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180f919061298f565b90506001600160a01b0382161561186857336001600160a01b03167f15c7da4af2133090a14dba8b02646e4d2ded2b9e8173addcd1b8d42719635112828560405161185b929190613063565b60405180910390a26118b4565b336001600160a01b03167f383af269d455c7ea93aa547244a2d345d395985c71392361c9e08b134826a65d8289898989896040516118ab9695949392919061303b565b60405180910390a25b9695505050505050565b600080600085606001516001600160401b03169050600086608001516001600160401b031690508660c001511561195a5786608001516001600160401b03168510611937576119306305f5e10061192a838161191a8a83612563565b6119248c89612529565b90612529565b906125a5565b9350611955565b61194e6305f5e10061192a838161191a828b612563565b9350600192505b6119a0565b86608001516001600160401b03168511156119865761194e6305f5e10061192a838161191a8a83612563565b61199d6305f5e10061192a838161191a828b612563565b93505b6000805460208901516040516384f6e7b360e01b8152611a6e92662386f26fc100009261192a926001600160a01b03909216916384f6e7b3916119f2916001600160a01b031990911690600401612d19565b60206040518083038186803b158015611a0a57600080fd5b505afa158015611a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a42919061298f565b611924611a648d60a0015165ffffffffffff164361256390919063ffffffff16565b6119248d8a612529565b90508315611a8757611a80858261247e565b9450611aaa565b84811115611a9d5760019350611a808186612563565b611aa78582612563565b94505b505050935093915050565b60008381526007602090815260408083208381556001810180546001600160f81b03191690556002018390556001600160a01b038416835260089091529020611afe90846125e7565b506002546005546001600160a01b039091169063b5c20dd3908390611b24908690611766565b6040518363ffffffff1660e01b8152600401611b41929190612b3d565b600060405180830381600087803b158015611b5b57600080fd5b505af1158015611b6f573d6000803e3d6000fd5b505050506000611b8f606461192a600b548661252990919063ffffffff16565b6001600160a01b038616600090815260066020526040902054909150611bb5908261247e565b6001600160a01b0380871660008181526006602052604090819020939093559151908416907f9f843df2e2b0c791e0c3993c883e11d06a6fcc960fb3a2765a6f4ab8a1bd07ca90611c099088908890613063565b60405180910390a35050505050565b611c20612746565b5060008181526007602090815260409182902082516101008101845281546001600160a01b0381168252600160a01b900460a090811b6001600160a01b0319169382019390935260018201546001600160401b03808216958301869052600160401b820481166060840152600160801b8204166080830152600160c01b810465ffffffffffff1693820193909352600160f01b90920460ff16151560c08301526002015460e08201529080851115611cea5760405162461bcd60e51b815260040161040890612eb3565b60008054602084015160405163443182fd60e01b81526001600160a01b039092169163443182fd91611d2b916001600160a01b031990911690600401612d19565b60206040518083038186803b158015611d4357600080fd5b505afa158015611d57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7b919061298f565b90508260c0015115611da657611d9f611d986305f5e10083612563565b8690611766565b9450611dba565b611db7611d986305f5e1008361247e565b94505b600080611dc88589896118be565b915091506000818015611ddb5750888310155b15611ea55760008781526007602090815260408083208381556001810180546001600160f81b031916905560020183905588516001600160a01b0316835260089091529020611e2a90886125e7565b5060025486516005546001600160a01b039092169163b5c20dd39190611e51908990611766565b6040518363ffffffff1660e01b8152600401611e6e929190612b3d565b600060405180830381600087803b158015611e8857600080fd5b505af1158015611e9c573d6000803e3d6000fd5b50505050612002565b84891015611ef6576000878152600760205260409020611ecd611ec8878c612563565b61222d565b600191909101805467ffffffffffffffff19166001600160401b03909216919091179055611f42565b60008781526007602090815260408083208381556001810180546001600160f81b031916905560020183905588516001600160a01b0316835260089091529020611f4090886125e7565b505b8115611fb657611f528984612563565b86516001600160a01b0316600090815260066020526040902054909150611f79908261247e565b86516001600160a01b039081166000908152600660205260409020919091556002548751600554919092169163b5c20dd391611e51908790611766565b611fc0898461247e565b86516001600160a01b0316600090815260066020526040902054909150611fe7908261247e565b86516001600160a01b03166000908152600660205260409020555b85600001516001600160a01b03167fb740da1ca3b7364c36886a66a0a5a33c31a8985a91673f3bc2ae6ae876007657888b848a608001518d8c60600151604051612051969594939291906130ae565b60405180910390a2505050505050505050565b600083815260076020526040808220600181015481548454935163443182fd60e01b81529294600160f01b830460ff16946001600160401b0380851695600160401b90950416936001600160a01b03938416939091169063443182fd906120cf908b90600401612d19565b60206040518083038186803b1580156120e757600080fd5b505afa1580156120fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211f919061298f565b905084156121465761213f6121386305f5e1008361247e565b8890611766565b965061215a565b6121576121386305f5e10083612563565b96505b85546001600160a01b0316600160a01b60a08a901c0217865561217c8761222d565b60018701805467ffffffffffffffff60801b1916600160801b6001600160401b0393909316929092029190911765ffffffffffff60c01b1916600160c01b4365ffffffffffff16021790556001600160a01b03821660009081526008602052604090206121e9908a6126ad565b50816001600160a01b03167f94046b799d1f5befe29f320688602f36227b2884ebbfa15c12ad25f6aede27c58a878b88888d6040516120519695949392919061303b565b60006001600160401b038211156122565760405162461bcd60e51b815260040161040890612f8e565b5090565b604051636eb1769f60e11b815287906001600160a01b038a169063dd62ed3e9061228a908a908a90600401612b56565b60206040518083038186803b1580156122a257600080fd5b505afa1580156122b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122da919061298f565b101561247457876001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b15801561231957600080fd5b505afa15801561232d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261235591908101906128eb565b80516020909101207fa5e92f3efb6826155f1f728e162af9d7cda33a574a1153b58f03ea01cc37e568141561247457604051623f675f60e91b81526000906001600160a01b038a1690637ecebe00906123b2908a90600401612b29565b60206040518083038186803b1580156123ca57600080fd5b505afa1580156123de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612402919061298f565b6040516323f2ebc360e21b81529091506001600160a01b038a1690638fcbaf0c90612440908a908a9086908b906001908c908c908c90600401612b93565b600060405180830381600087803b15801561245a57600080fd5b505af115801561246e573d6000803e3d6000fd5b50505050505b5050505050505050565b6000828201838110156124a35760405162461bcd60e51b815260040161040890612dd1565b9392505050565b60008160ff16601214156124c75750670de0b6b3a76400006105ee565b8160ff16600614156124dd5750620f42406105ee565b60015b600a8360ff1610612507576124fa816402540be400612529565b9050600a830392506124e0565b60ff8316156117345761251b81600a612529565b600019909301929050612507565b60008261253857506000611734565b8282028284828161254557fe5b04146124a35760405162461bcd60e51b815260040161040890612e29565b60006124a383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061173a565b60006124a383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506126f7565b600081815260018301602052604081205480156126a3578354600019808301919081019060009087908390811061261a57fe5b906000526020600020015490508087600001848154811061263757fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061266757fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611734565b6000915050611734565b60006126b9838361272e565b6126ef57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611734565b506000611734565b600081836127185760405162461bcd60e51b81526004016104089190612d56565b50600083858161272457fe5b0495945050505050565b60009081526001919091016020526040902054151590565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b80356001600160a01b03811681146105ee57600080fd5b60008083601f8401126127b2578182fd5b5081356001600160401b038111156127c8578182fd5b60208301915083602080830285010111156127e257600080fd5b9250929050565b6000602082840312156127fa578081fd5b6124a38261278a565b600080600060608486031215612817578182fd5b6128208461278a565b925061282e6020850161278a565b915061283c6040850161278a565b90509250925092565b60008060408385031215612857578182fd5b6128608361278a565b946020939093013593505050565b60008060208385031215612880578182fd5b82356001600160401b03811115612895578283fd5b6128a1858286016127a1565b90969095509350505050565b600080600080608085870312156128c2578081fd5b843580151581146128d1578182fd5b966020860135965060408601359560600135945092505050565b6000602082840312156128fc578081fd5b81516001600160401b0380821115612912578283fd5b818401915084601f830112612925578283fd5b81518181111561293157fe5b604051601f8201601f19168101602001838111828210171561294f57fe5b604052818152838201602001871015612966578485fd5b6118b48260208301602087016130e5565b600060208284031215612988578081fd5b5035919050565b6000602082840312156129a0578081fd5b5051919050565b60008060008060008060c087890312156129bf578182fd5b86359550602087013594506040870135935060608701359250608087013591506129eb60a0880161278a565b90509295509295509295565b60008060408385031215612a09578182fd5b50508035926020909101359150565b600080600080600060808688031215612a2f578081fd5b8535945060208601359350612a466040870161278a565b925060608601356001600160401b0380821115612a61578283fd5b818801915088601f830112612a74578283fd5b813581811115612a82578384fd5b896020828501011115612a93578384fd5b9699959850939650602001949392505050565b600080600080600060a08688031215612abd578283fd5b85359450602086013593506040860135612ad681613111565b94979396509394606081013594506080013592915050565b600060208284031215612aff578081fd5b81516124a381613111565b15159052565b65ffffffffffff169052565b6001600160401b03169052565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0393841681529183166020830152909116604082015260600190565b6001600160a01b039889168152969097166020870152604086019490945260608501929092521515608084015260ff1660a083015260c082015260e08101919091526101000190565b6001600160a01b039890981688526001600160a01b03199690961660208801526001600160401b03948516604088015292841660608701529216608085015265ffffffffffff90911660a0840152151560c083015260e08201526101000190565b602080825282518282018190526000919060409081850190868401855b82811015612d0157815180516001600160a01b03168552868101516001600160a01b03191687860152858101516001600160401b031686860152606080820151612ca682880182612b1c565b5050608080820151612cba82880182612b1c565b505060a080820151612cce82880182612b10565b505060c080820151612ce282880182612b0a565b505060e090810151908501526101009093019290850190600101612c5a565b5091979650505050505050565b901515815260200190565b90815260200190565b9182521515602082015260400190565b938452602084019290925260408301526001600160a01b0316606082015260800190565b6000602082528251806020840152612d758160408501602087016130e5565b601f01601f19169190910160400192915050565b6020808252600c908201526b085a5b9a5d1a585b1a5e995960a21b604082015260600190565b602080825260089082015267085c195c98d95b9d60c21b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b602080825260079082015266085c185d5cd95960ca1b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252600d908201526c216d61785f6c6576657261676560981b604082015260600190565b60208082526008908201526721746f6f5f6c6f7760c01b604082015260600190565b60208082526007908201526610b6b0b933b4b760c91b604082015260600190565b6020808252600b908201526a10b830bab9b2b22ab9b2b960a91b604082015260600190565b602080825260099082015268216c6576657261676560b81b604082015260600190565b60208082526010908201526f085d5cd95c97db9bdd17dc185d5cd95960821b604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b60208082526009908201526821746f6f5f6d616e7960b81b604082015260600190565b60208082526017908201527f536166654d6174683a2063617374206f766572666c6f77000000000000000000604082015260600190565b6020808252818101527f55696e74456e756d657261626c655365743a204f55545f4f465f424f554e4453604082015260600190565b60208082526006908201526508599bdd5b9960d21b604082015260600190565b602080825260079082015266085cde5b589bdb60ca1b604082015260600190565b958652931515602086015260408501929092526060840152608083015260a082015260c00190565b918252602082015260400190565b60008582528460208301526060604083015282606083015282846080840137818301608090810191909152601f909201601f191601019392505050565b958652602086019490945260408501929092526001600160401b03908116606085015260808401919091521660a082015260c00190565b60005b838110156131005781810151838201526020016130e8565b838111156108955750506000910152565b60ff8116811461312057600080fd5b5056fea2646970667358221220a90a35f9a76195efe9dffbde0f321e645ef3f8aef0745e67fbbe75a7a19ea28b64736f6c63430007030033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.