Contract Overview
Balance:
0 ETH
ETH Value:
$0.00
My Name Tag:
Not Available
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x685472725bee9ce49126b2fc24ff50621886d3179d5f624da0a46426855d25fc | 0x60806040 | 2806979 | 456 days 2 hrs ago | 0x0f3bf5c241b6625c0fa781ed137fde6786b2e66f | IN | Create: MCDEXLemma | 0 ETH | 0.151301538048 ETH |
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
MCDEXLemma
Compiler Version
v0.8.3+commit.8d00100c
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity =0.8.3; import { ILiquidityPool, PerpetualState } from "../interfaces/MCDEX/ILiquidityPool.sol"; import { SafeCastUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { ERC2771ContextUpgradeable } from "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol"; import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import { SafeERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import { Utils } from "../libraries/Utils.sol"; import { SafeMathExt } from "../libraries/SafeMathExt.sol"; import { IPerpetualDEXWrapper } from "../interfaces/IPerpetualDEXWrapper.sol"; interface IUSDLemma { function lemmaTreasury() external view returns (address); } /// @author Lemma Finance contract MCDEXLemma is OwnableUpgradeable, ERC2771ContextUpgradeable, IPerpetualDEXWrapper { using SafeCastUpgradeable for uint256; using SafeCastUpgradeable for int256; using Utils for int256; using SafeMathExt for int256; uint256 public constant MAX_UINT256 = type(uint256).max; int256 public constant MAX_INT256 = type(int256).max; // address of Mai3 liquidity pool ILiquidityPool public liquidityPool; // pereptual index in the liquidity pool uint256 public perpetualIndex; IERC20Upgradeable public collateral; uint256 public collateralDecimals; address public usdLemma; address public reBalancer; address public referrer; int256 public entryFunding; int256 public realizedFundingPNL; uint256 public positionAtSettlement; uint256 public maxPosition; //events event USDLemmaUpdated(address usdlAddress); event ReferrerUpdated(address referrerAddress); event RebalancerUpdated(address rebalancerAddress); event MaxPositionUpdated(uint256 maxPos); function initialize( address _trustedForwarder, ILiquidityPool _liquidityPool, uint256 _perpetualIndex, address _usdlemma, address _reBalancer, uint256 _maxPosition ) external initializer { __Ownable_init(); __ERC2771Context_init(_trustedForwarder); liquidityPool = _liquidityPool; perpetualIndex = _perpetualIndex; { (bool isRunning, , address[7] memory addresses, , uint256[4] memory uintNums) = liquidityPool .getLiquidityPoolInfo(); require(isRunning, "pool is not running"); collateral = IERC20Upgradeable(addresses[5]); collateralDecimals = uintNums[0]; } setReBalancer(_reBalancer); setUSDLemma(_usdlemma); setMaxPosition(_maxPosition); //approve collateral to SafeERC20Upgradeable.safeApprove(collateral, address(liquidityPool), MAX_UINT256); //target leverage = 1 liquidityPool.setTargetLeverage(perpetualIndex, address(this), 1 ether); //1 } ///@notice sets USDLemma address - only owner can set ///@param _usdlemma USDLemma address to set function setUSDLemma(address _usdlemma) public onlyOwner { usdLemma = _usdlemma; emit USDLemmaUpdated(usdLemma); } ///@notice sets refferer address - only owner can set ///@param _referrer refferer address to set function setReferrer(address _referrer) external onlyOwner { referrer = _referrer; emit ReferrerUpdated(referrer); } ///@notice sets reBalncer address - only owner can set ///@param _reBalancer reBalancer address to set function setReBalancer(address _reBalancer) public onlyOwner { reBalancer = _reBalancer; emit RebalancerUpdated(reBalancer); } ///@notice sets Max Positions - only owner can set ///@param _maxPosition reBalancer address to set function setMaxPosition(uint256 _maxPosition) public onlyOwner { maxPosition = _maxPosition; emit MaxPositionUpdated(maxPosition); } /// @notice reset approvals function resetApprovals() external { SafeERC20Upgradeable.safeApprove(collateral, address(liquidityPool), 0); SafeERC20Upgradeable.safeApprove(collateral, address(liquidityPool), MAX_UINT256); } //this needs to be done before the first withdrawal happens //Keeper gas reward needs to be handled seperately which owner can get back when perpetual has settled /// @notice Deposit Keeper gas reward for the perpetual - only owner can call function depositKeeperGasReward() external onlyOwner { int256 keeperGasReward; { (, , int256[39] memory nums) = liquidityPool.getPerpetualInfo(perpetualIndex); keeperGasReward = nums[11]; } SafeERC20Upgradeable.safeTransferFrom( collateral, _msgSender(), address(this), getAmountInCollateralDecimals(keeperGasReward.toUint256(), true) ); liquidityPool.deposit(perpetualIndex, address(this), keeperGasReward); } //go short to open /// @notice Open short position on dex and deposit collateral /// @param amount worth in USD short position which is to be opened /// @param collateralAmountRequired collateral amount required to open the position function open(uint256 amount, uint256 collateralAmountRequired) external override { require(_msgSender() == usdLemma, "only usdLemma is allowed"); require( collateral.balanceOf(address(this)) >= getAmountInCollateralDecimals(collateralAmountRequired, true), "not enough collateral" ); liquidityPool.deposit(perpetualIndex, address(this), collateralAmountRequired.toInt256()); (, int256 position, , , , , , , ) = liquidityPool.getMarginAccount(perpetualIndex, address(this)); require(position.abs().toUint256() + amount <= maxPosition, "max position reached"); liquidityPool.trade(perpetualIndex, address(this), amount.toInt256(), MAX_INT256, MAX_UINT256, referrer, 0); updateEntryFunding(position, amount.toInt256()); } //go long and withdraw collateral /// @notice Close short position on dex and withdraw collateral /// @param amount worth in USD short position which is to be closed /// @param collateralAmountToGetBack collateral amount freed up after closing the position function close(uint256 amount, uint256 collateralAmountToGetBack) external override { require(_msgSender() == usdLemma, "only usdLemma is allowed"); (PerpetualState perpetualState, , ) = liquidityPool.getPerpetualInfo(perpetualIndex); if (perpetualState != PerpetualState.CLEARED) { //means perpetual settled (, int256 position, , , , , , , ) = liquidityPool.getMarginAccount(perpetualIndex, address(this)); liquidityPool.trade( perpetualIndex, address(this), -amount.toInt256(), //negative means you want to go short (on USD, that in turn means long on ETH) 0, MAX_UINT256, referrer, 0 ); liquidityPool.withdraw(perpetualIndex, address(this), collateralAmountToGetBack.toInt256()); updateEntryFunding(position, -amount.toInt256()); } SafeERC20Upgradeable.safeTransfer( collateral, usdLemma, getAmountInCollateralDecimals(collateralAmountToGetBack, false) ); } //// @notice when perpetual is in CLEARED state, withdraw the collateral function settle() public { (, int256 position, , , , , , , ) = liquidityPool.getMarginAccount(perpetualIndex, address(this)); positionAtSettlement = position.abs().toUint256(); liquidityPool.settle(perpetualIndex, address(this)); } /// @notice Collateral amount required/to get back for amount in USD to open/close position on dex /// @param amount worth in USD short position which is to be closed or opened /// @param isShorting true if opening short position, false if closing short position /// @return collateralAmountRequired equivalent collateral amount function getCollateralAmountGivenUnderlyingAssetAmount(uint256 amount, bool isShorting) external override returns (uint256 collateralAmountRequired) { liquidityPool.forceToSyncState(); int256 tradeAmount = isShorting ? amount.toInt256() : -amount.toInt256(); //handle the case when perpetual has settled (PerpetualState perpetualState, , ) = liquidityPool.getPerpetualInfo(perpetualIndex); if (perpetualState == PerpetualState.CLEARED) { require(!isShorting, "cannot open when perpetual has settled"); ( , , , , int256 settleableMargin, // bankrupt , , , ) = liquidityPool.getMarginAccount(perpetualIndex, address(this)); if (settleableMargin != 0) { settle(); } collateralAmountRequired = (collateral.balanceOf(address(this)) * amount) / positionAtSettlement; } else { (int256 tradePrice, int256 totalFee, ) = liquidityPool.queryTrade( perpetualIndex, address(this), tradeAmount, referrer, 0 ); int256 deltaCash = amount.toInt256().wmul(tradePrice); collateralAmountRequired = isShorting ? (deltaCash + totalFee).toUint256() : (deltaCash - totalFee).toUint256(); } } /// @notice Rebalance position of dex based on accumulated funding, since last rebalancing /// @param _reBalancer Address of rebalancer who called function on USDL contract /// @param amount Amount of accumulated funding fees used to rebalance by opening or closing a short position /// @param data Abi encoded data to call respective mcdex function, contains limitPrice and deadline /// @return True if successful, False if unsuccessful function reBalance( address _reBalancer, int256 amount, bytes calldata data ) external override returns (bool) { liquidityPool.forceToSyncState(); require(_msgSender() == usdLemma, "only usdLemma is allowed"); require(_reBalancer == reBalancer, "only rebalancer is allowed"); (int256 limitPrice, uint256 deadline) = abi.decode(data, (int256, uint256)); int256 fundingPNL = getFundingPNL(); (int256 tradePrice, int256 totalFee, ) = liquidityPool.queryTrade( perpetualIndex, address(this), amount, referrer, 0 ); int256 deltaCash = amount.abs().wmul(tradePrice); uint256 collateralAmount = (deltaCash + totalFee).toUint256(); if (amount < 0) { realizedFundingPNL -= collateralAmount.toInt256(); } else { realizedFundingPNL += collateralAmount.toInt256(); } int256 difference = fundingPNL - realizedFundingPNL; //error +-10**12 is allowed in calculation require(difference.abs() <= 10**12, "not allowed"); liquidityPool.trade(perpetualIndex, address(this), amount, limitPrice, deadline, referrer, 0); return true; } /// @notice calculate entryFunding to be able to calculate the fundingPNL easily /// @param position Current position on MCDEX /// @param tradeAmount Change in current position on MCDEX function updateEntryFunding(int256 position, int256 tradeAmount) internal { (int256 closeAmount, int256 openAmount) = Utils.splitAmount(position, tradeAmount); int256 unitAccumulativeFunding; { (, , int256[39] memory nums) = liquidityPool.getPerpetualInfo(perpetualIndex); unitAccumulativeFunding = nums[4]; } if (closeAmount != 0) { int256 oldPosition = position; int256 newPosition = position + closeAmount; entryFunding = entryFunding.wmul(newPosition).wdiv(oldPosition); } if (openAmount != 0) { entryFunding = entryFunding + unitAccumulativeFunding.wmul(openAmount); } } /// @notice Get funding PnL for this address till now /// @return fundingPNL Funding PnL accumulated till now function getFundingPNL() public view returns (int256 fundingPNL) { int256 unitAccumulativeFunding; { (, , int256[39] memory nums) = liquidityPool.getPerpetualInfo(perpetualIndex); unitAccumulativeFunding = nums[4]; } (, int256 position, , , , , , , ) = liquidityPool.getMarginAccount(perpetualIndex, address(this)); fundingPNL = entryFunding - position.wmul(unitAccumulativeFunding); } /// @notice Get Amount in collateral decimals, provided amount is in 18 decimals /// @param amount Amount in 18 decimals /// @param roundUp If needs to round up /// @return decimal adjusted value function getAmountInCollateralDecimals(uint256 amount, bool roundUp) public view override returns (uint256) { if (roundUp && (amount % (uint256(10**(18 - collateralDecimals))) != 0)) { return amount / uint256(10**(18 - collateralDecimals)) + 1; } return amount / uint256(10**(18 - collateralDecimals)); } ///@notice send MCB tokens that we may get to lemmaTreasury function sendMCBToTreasury() external { IERC20Upgradeable mcbToken = IERC20Upgradeable(0x4e352cF164E64ADCBad318C3a1e222E9EBa4Ce42); address lemmaTreasury = IUSDLemma(usdLemma).lemmaTreasury(); SafeERC20Upgradeable.safeTransfer(mcbToken, lemmaTreasury, mcbToken.balanceOf(address(this))); } function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (address sender) { //ERC2771ContextUpgradeable._msgSender(); return super._msgSender(); } function _msgData() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (bytes calldata) { //ERC2771ContextUpgradeable._msgData(); return super._msgData(); } }
// SPDX-License-Identifier: MIT pragma solidity =0.8.3; /** * @notice Perpetual state: * - INVALID: Uninitialized or not non-existent perpetual; * - INITIALIZING: Only when LiquidityPoolStorage.isRunning == false. Traders cannot perform operations; * - NORMAL: Full functional state. Traders is able to perform all operations; * - EMERGENCY: Perpetual is unsafe and only clear is available; * - CLEARED: All margin account is cleared. Trade could withdraw remaining margin balance. */ enum PerpetualState { INVALID, INITIALIZING, NORMAL, EMERGENCY, CLEARED } interface ILiquidityPool { /** * @notice Get the info of the liquidity pool * @return isRunning True if the liquidity pool is running * @return isFastCreationEnabled True if the operator of the liquidity pool is allowed to create new perpetual * when the liquidity pool is running * @return addresses The related addresses of the liquidity pool * @return intNums Int type properties, see below for details. * @return uintNums Uint type properties, see below for details. */ function getLiquidityPoolInfo() external view returns ( bool isRunning, bool isFastCreationEnabled, // [0] creator, // [1] operator, // [2] transferringOperator, // [3] governor, // [4] shareToken, // [5] collateralToken, // [6] vault, address[7] memory addresses, // [0] vaultFeeRate, // [1] poolCash, // [2] insuranceFundCap, // [3] insuranceFund, // [4] donatedInsuranceFund, int256[5] memory intNums, // [0] collateralDecimals, // [1] perpetualCount // [2] fundingTime, // [3] operatorExpiration, uint256[4] memory uintNums ); /** * @notice Get the info of the perpetual. Need to update the funding state and the oracle price * of each perpetual before and update the funding rate of each perpetual after * @param perpetualIndex The index of the perpetual in the liquidity pool * @return state The state of the perpetual * @return oracle The oracle's address of the perpetual * @return nums The related numbers of the perpetual */ function getPerpetualInfo(uint256 perpetualIndex) external view returns ( PerpetualState state, address oracle, // [0] totalCollateral // [1] markPrice, (return settlementPrice if it is in EMERGENCY state) // [2] indexPrice, // [3] fundingRate, // [4] unitAccumulativeFunding, // [5] initialMarginRate, // [6] maintenanceMarginRate, // [7] operatorFeeRate, // [8] lpFeeRate, // [9] referralRebateRate, // [10] liquidationPenaltyRate, // [11] keeperGasReward, // [12] insuranceFundRate, // [13-15] halfSpread value, min, max, // [16-18] openSlippageFactor value, min, max, // [19-21] closeSlippageFactor value, min, max, // [22-24] fundingRateLimit value, min, max, // [25-27] ammMaxLeverage value, min, max, // [28-30] maxClosePriceDiscount value, min, max, // [31] openInterest, // [32] maxOpenInterestRate, // [33-35] fundingRateFactor value, min, max, // [36-38] defaultTargetLeverage value, min, max, int256[39] memory nums ); /** * @notice Get the account info of the trader. Need to update the funding state and the oracle price * of each perpetual before and update the funding rate of each perpetual after * @param perpetualIndex The index of the perpetual in the liquidity pool * @param trader The address of the trader * @return cash The cash(collateral) of the account * @return position The position of the account * @return availableMargin The available margin of the account * @return margin The margin of the account * @return settleableMargin The settleable margin of the account * @return isInitialMarginSafe True if the account is initial margin safe * @return isMaintenanceMarginSafe True if the account is maintenance margin safe * @return isMarginSafe True if the total value of margin account is beyond 0 * @return targetLeverage The target leverage for openning position. */ function getMarginAccount(uint256 perpetualIndex, address trader) external view returns ( int256 cash, int256 position, int256 availableMargin, int256 margin, int256 settleableMargin, bool isInitialMarginSafe, bool isMaintenanceMarginSafe, bool isMarginSafe, // bankrupt int256 targetLeverage ); /** * @notice Initialize the liquidity pool and set up its configuration. * * @param operator The operator's address of the liquidity pool. * @param collateral The collateral's address of the liquidity pool. * @param collateralDecimals The collateral's decimals of the liquidity pool. * @param governor The governor's address of the liquidity pool. * @param initData A bytes array contains data to initialize new created liquidity pool. */ function initialize( address operator, address collateral, uint256 collateralDecimals, address governor, bytes calldata initData ) external; /** * @notice Deposit collateral to the perpetual. * Can only called when the perpetual's state is "NORMAL". * This method will always increase `cash` amount in trader's margin account. * * @param perpetualIndex The index of the perpetual in the liquidity pool. * @param trader The address of the trader. * @param amount The amount of collatetal to deposit. The amount always use decimals 18. */ function deposit( uint256 perpetualIndex, address trader, int256 amount ) external; /** * @notice Withdraw collateral from the trader's account of the perpetual. * After withdrawn, trader shall at least has maintenance margin left in account. * Can only called when the perpetual's state is "NORMAL". * Margin account must at least keep * The trader's cash will decrease in the perpetual. * Need to update the funding state and the oracle price of each perpetual before * and update the funding rate of each perpetual after * * @param perpetualIndex The index of the perpetual in the liquidity pool. * @param trader The address of the trader. * @param amount The amount of collatetal to withdraw. The amount always use decimals 18. */ function withdraw( uint256 perpetualIndex, address trader, int256 amount ) external; /** * @notice Trade with AMM in the perpetual, require sender is granted the trade privilege by the trader. * The trading price is determined by the AMM based on the index price of the perpetual. * Trader must be initial margin safe if opening position and margin safe if closing position * @param perpetualIndex The index of the perpetual in the liquidity pool * @param trader The address of trader * @param amount The position amount of the trade * @param limitPrice The worst price the trader accepts * @param deadline The deadline of the trade * @param referrer The referrer's address of the trade * @param flags The flags of the trade * @return int256 The update position amount of the trader after the trade */ function trade( uint256 perpetualIndex, address trader, int256 amount, int256 limitPrice, uint256 deadline, address referrer, uint32 flags ) external returns (int256); /** * @notice Trade with AMM by the order, initiated by the broker. * The trading price is determined by the AMM based on the index price of the perpetual. * Trader must be initial margin safe if opening position and margin safe if closing position * @param orderData The order data object * @param amount The position amount of the trade * @return int256 The update position amount of the trader after the trade */ function brokerTrade(bytes memory orderData, int256 amount) external returns (int256); /** * @notice Get the number of active accounts in the perpetual. * Active means the trader's account is not empty in the perpetual. * Empty means cash and position are zero * @param perpetualIndex The index of the perpetual in the liquidity pool * @return activeAccountCount The number of active accounts in the perpetual */ function getActiveAccountCount(uint256 perpetualIndex) external view returns (uint256); /** * @notice Get the active accounts in the perpetual whose index between begin and end. * Active means the trader's account is not empty in the perpetual. * Empty means cash and position are zero * @param perpetualIndex The index of the perpetual in the liquidity pool * @param begin The begin index * @param end The end index * @return result The active accounts in the perpetual whose index between begin and end */ function listActiveAccounts( uint256 perpetualIndex, uint256 begin, uint256 end ) external view returns (address[] memory result); /** * @notice Get the progress of clearing active accounts. * Return the number of total active accounts and the number of active accounts not cleared * @param perpetualIndex The index of the perpetual in the liquidity pool * @return left The left active accounts * @return total The total active accounts */ function getClearProgress(uint256 perpetualIndex) external view returns (uint256 left, uint256 total); /** * @notice Get the pool margin of the liquidity pool. * Pool margin is how much collateral of the pool considering the AMM's positions of perpetuals * @return poolMargin The pool margin of the liquidity pool */ function getPoolMargin() external view returns (int256 poolMargin, bool isSafe); /** * @notice Get the update cash amount and the update position amount of trader * if trader trades with AMM in the perpetual * @param perpetualIndex The index of the perpetual in the liquidity pool * @param amount The trading amount of position * @return deltaCash The update cash(collateral) of the trader after the trade * @return deltaPosition The update position of the trader after the trade */ function queryTradeWithAMM(uint256 perpetualIndex, int256 amount) external view returns (int256 deltaCash, int256 deltaPosition); /** * @notice Query the price, fees and cost when trade agaist amm. * The trading price is determined by the AMM based on the index price of the perpetual. * This method should returns the same result as a 'read-only' trade. * WARN: the result of this function is base on current storage of liquidityPool, not the latest. * To get the latest status, call `syncState` first. * * Flags is a 32 bit uint value which indicates: (from highest bit) * - close only only close position during trading; * - market order do not check limit price during trading; * - stop loss only available in brokerTrade mode; * - take profit only available in brokerTrade mode; * For stop loss and take profit, see `validateTriggerPrice` in OrderModule.sol for details. * * @param perpetualIndex The index of the perpetual in liquidity pool. * @param trader The address of trader. * @param amount The amount of position to trader, positive for buying and negative for selling. The amount always use decimals 18. * @param referrer The address of referrer who will get rebate from the deal. * @param flags The flags of the trade. * @return tradePrice The average fill price. * @return totalFee The total fee collected from the trader after the trade. * @return cost Deposit or withdraw to let effective leverage == targetLeverage if flags contain USE_TARGET_LEVERAGE. > 0 if deposit, < 0 if withdraw. */ function queryTrade( uint256 perpetualIndex, address trader, int256 amount, address referrer, uint32 flags ) external view returns ( int256 tradePrice, int256 totalFee, int256 cost ); /** * @notice Get claimable fee of the operator in the liquidity pool * @return int256 The claimable fee of the operator in the liquidity pool */ function getClaimableOperatorFee() external view returns (int256); /** * @notice Get claimable fee of the claimer in the liquidity pool * @param claimer The address of the claimer * @return int256 The claimable fee of the claimer in the liquidity pool. always use decimals 18. */ function getClaimableFee(address claimer) external view returns (int256); /** * @notice If you want to get the real-time data, call this function first */ function forceToSyncState() external; /** * @notice Returns the current implementation of UpgradeableProxy. */ function implementation() external view returns (address); /** * @notice Query cash to add / share to mint when adding liquidity to the liquidity pool. * Only one of cashToAdd or shareToMint may be non-zero. * * @param cashToAdd The amount of cash to add, always use decimals 18. * @param shareToMint The amount of share token to mint, always use decimals 18. * @return cashToAddResult The amount of cash to add, always use decimals 18. Equal to cashToAdd if cashToAdd is non-zero. * @return shareToMintResult The amount of cash to add, always use decimals 18. Equal to shareToMint if shareToMint is non-zero. */ function queryAddLiquidity(int256 cashToAdd, int256 shareToMint) external view returns (int256 cashToAddResult, int256 shareToMintResult); /** * @notice Query cash to return / share to redeem when removing liquidity from the liquidity pool. * Only one of shareToRemove or cashToReturn may be non-zero. * Can only called when the pool is running. * * @param shareToRemove The amount of share token to redeem, always use decimals 18. * @param cashToReturn The amount of cash to return, always use decimals 18. * @return shareToRemoveResult The amount of share token to redeem, always use decimals 18. Equal to shareToRemove if shareToRemove is non-zero. * @return cashToReturnResult The amount of cash to return, always use decimals 18. Equal to cashToReturn if cashToReturn is non-zero. */ function queryRemoveLiquidity(int256 shareToRemove, int256 cashToReturn) external view returns (int256 shareToRemoveResult, int256 cashToReturnResult); function settle(uint256 perpetualIndex, address trader) external; /** * @dev Get the fees of the trade. If the margin of the trader is not enough for fee: * 1. If trader open position, the trade will be reverted. * 2. If trader close position, the fee will be decreasing in proportion according to * the margin left in the trader's account * The rebate of referral will only calculate the lpFee and operatorFee. * The vault fee will not be counted in. * * @param liquidityPool The reference of liquidity pool storage. * @param perpetual The reference of pereptual storage. * @param trader The address of trader. * @param referrer The address of referrer who will get rebate from the deal. * @param tradeValue The amount of trading value, measured by collateral, abs of deltaCash. * @return lpFee The amount of fee to the Liquidity provider. * @return operatorFee The amount of fee to the operator. * @return vaultFee The amount of fee to the vault. * @return referralRebate The amount of rebate of the refferral. */ function getFees( address liquidityPool, address perpetual, address trader, address referrer, int256 tradeValue, bool hasOpened ) external view returns ( int256 lpFee, int256 operatorFee, int256 vaultFee, int256 referralRebate ); function setTargetLeverage( uint256 perpetualIndex, address trader, int256 targetLeverage ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such 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. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCastUpgradeable { /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Context variant with ERC2771 support. */ abstract contract ERC2771ContextUpgradeable is Initializable, ContextUpgradeable { address private _trustedForwarder; function __ERC2771Context_init(address trustedForwarder) internal initializer { __Context_init_unchained(); __ERC2771Context_init_unchained(trustedForwarder); } function __ERC2771Context_init_unchained(address trustedForwarder) internal initializer { _trustedForwarder = trustedForwarder; } function isTrustedForwarder(address forwarder) public view virtual returns (bool) { return forwarder == _trustedForwarder; } function _msgSender() internal view virtual override returns (address sender) { if (isTrustedForwarder(msg.sender)) { // The assembly code is more direct than the Solidity version using `abi.decode`. assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) } } else { return super._msgSender(); } } function _msgData() internal view virtual override returns (bytes calldata) { if (isTrustedForwarder(msg.sender)) { return msg.data[:msg.data.length - 20]; } else { return super._msgData(); } } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; import "../../../utils/AddressUpgradeable.sol"; /** * @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 SafeERC20Upgradeable { using AddressUpgradeable for address; function safeTransfer( IERC20Upgradeable token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20Upgradeable 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( IERC20Upgradeable 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( IERC20Upgradeable 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( IERC20Upgradeable 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)); } } /** * @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(IERC20Upgradeable 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"); } } }
// SPDX-License-Identifier: MIT pragma solidity =0.8.3; import "./SafeMathExt.sol"; import "@openzeppelin/contracts-upgradeable/utils/math/SignedSafeMathUpgradeable.sol"; //recreating https://github.com/mcdexio/mai-protocol-v3/blob/master/contracts/libraries/Utils.sol library Utils { using SafeMathExt for int256; using SignedSafeMathUpgradeable for int256; /* * @dev Check if two numbers have the same sign. Zero has the same sign with any number */ function hasTheSameSign(int256 x, int256 y) internal pure returns (bool) { if (x == 0 || y == 0) { return true; } return (x ^ y) >> 255 == 0; } /* * @dev Split the delta to two numbers. * Use for splitting the trading amount to the amount to close position and the amount to open position. * Examples: 2, 1 => 0, 1; 2, -1 => -1, 0; 2, -3 => -2, -1 */ function splitAmount(int256 amount, int256 delta) internal pure returns (int256, int256) { if (Utils.hasTheSameSign(amount, delta)) { return (0, delta); } else if (amount.abs() >= delta.abs()) { return (delta, 0); } else { return (amount.neg(), amount.add(delta)); } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.3; import "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/math/SignedSafeMathUpgradeable.sol"; import "./Constant.sol"; import "./Utils.sol"; enum Round { CEIL, FLOOR } library SafeMathExt { using SafeMathUpgradeable for uint256; using SignedSafeMathUpgradeable for int256; /* * @dev Always half up for uint256 */ function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x.mul(y).add(Constant.UNSIGNED_ONE / 2) / Constant.UNSIGNED_ONE; } /* * @dev Always half up for uint256 */ function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x.mul(Constant.UNSIGNED_ONE).add(y / 2).div(y); } /* * @dev Always half up for uint256 */ function wfrac( uint256 x, uint256 y, uint256 z ) internal pure returns (uint256 r) { r = x.mul(y).add(z / 2).div(z); } /* * @dev Always half up if no rounding parameter */ function wmul(int256 x, int256 y) internal pure returns (int256 z) { z = roundHalfUp(x.mul(y), Constant.SIGNED_ONE) / Constant.SIGNED_ONE; } /* * @dev Always half up if no rounding parameter */ function wdiv(int256 x, int256 y) internal pure returns (int256 z) { if (y < 0) { y = neg(y); x = neg(x); } z = roundHalfUp(x.mul(Constant.SIGNED_ONE), y).div(y); } /* * @dev Always half up if no rounding parameter */ function wfrac( int256 x, int256 y, int256 z ) internal pure returns (int256 r) { int256 t = x.mul(y); if (z < 0) { z = neg(z); t = neg(t); } r = roundHalfUp(t, z).div(z); } function wmul( int256 x, int256 y, Round round ) internal pure returns (int256 z) { z = div(x.mul(y), Constant.SIGNED_ONE, round); } function wdiv( int256 x, int256 y, Round round ) internal pure returns (int256 z) { z = div(x.mul(Constant.SIGNED_ONE), y, round); } function wfrac( int256 x, int256 y, int256 z, Round round ) internal pure returns (int256 r) { int256 t = x.mul(y); r = div(t, z, round); } function abs(int256 x) internal pure returns (int256) { return x >= 0 ? x : neg(x); } function neg(int256 a) internal pure returns (int256) { return SignedSafeMathUpgradeable.sub(int256(0), a); } /* * @dev ROUND_HALF_UP rule helper. * You have to call roundHalfUp(x, y) / y to finish the rounding operation. * 0.5 ≈ 1, 0.4 ≈ 0, -0.5 ≈ -1, -0.4 ≈ 0 */ function roundHalfUp(int256 x, int256 y) internal pure returns (int256) { require(y > 0, "roundHalfUp only supports y > 0"); if (x >= 0) { return x.add(y / 2); } return x.sub(y / 2); } /* * @dev Division, rounding ceil or rounding floor */ function div( int256 x, int256 y, Round round ) internal pure returns (int256 divResult) { require(y != 0, "division by zero"); divResult = x.div(y); if (x % y == 0) { return divResult; } bool isSameSign = Utils.hasTheSameSign(x, y); if (round == Round.CEIL && isSameSign) { divResult = divResult.add(1); } if (round == Round.FLOOR && !isSameSign) { divResult = divResult.sub(1); } } function max(int256 a, int256 b) internal pure returns (int256) { return a >= b ? a : b; } function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } }
// SPDX-License-Identifier: MIT pragma solidity =0.8.3; interface IPerpetualDEXWrapper { function open(uint256 amount, uint256 collateralAmountRequired) external; function close(uint256 amount, uint256 collateralAmountToGetBack) external; function getCollateralAmountGivenUnderlyingAssetAmount(uint256 amount, bool isShorting) external returns (uint256 collateralAmountRequired); function reBalance( address _reBalancer, int256 amount, bytes calldata data ) external returns (bool); function getAmountInCollateralDecimals(uint256 amount, bool roundUp) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SignedSafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SignedSafeMathUpgradeable { /** * @dev Returns the multiplication of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { return a * b; } /** * @dev Returns the integer division of two signed integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(int256 a, int256 b) internal pure returns (int256) { return a / b; } /** * @dev Returns the subtraction of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { return a - b; } /** * @dev Returns the addition of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { return a + b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMathUpgradeable { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @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 a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * 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) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.3; library Constant { address internal constant INVALID_ADDRESS = address(0); int256 internal constant SIGNED_ONE = 10**18; uint256 internal constant UNSIGNED_ONE = 10**18; uint256 internal constant PRIVILEGE_DEPOSIT = 0x1; uint256 internal constant PRIVILEGE_WITHDRAW = 0x2; uint256 internal constant PRIVILEGE_TRADE = 0x4; uint256 internal constant PRIVILEGE_LIQUIDATE = 0x8; uint256 internal constant PRIVILEGE_GUARD = PRIVILEGE_DEPOSIT | PRIVILEGE_WITHDRAW | PRIVILEGE_TRADE | PRIVILEGE_LIQUIDATE; // max number of uint256 uint256 internal constant SET_ALL_PERPETUALS_TO_EMERGENCY_STATE = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxPos","type":"uint256"}],"name":"MaxPositionUpdated","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":"rebalancerAddress","type":"address"}],"name":"RebalancerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"referrerAddress","type":"address"}],"name":"ReferrerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"usdlAddress","type":"address"}],"name":"USDLemmaUpdated","type":"event"},{"inputs":[],"name":"MAX_INT256","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_UINT256","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"collateralAmountToGetBack","type":"uint256"}],"name":"close","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collateral","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateralDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositKeeperGasReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"entryFunding","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"roundUp","type":"bool"}],"name":"getAmountInCollateralDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"isShorting","type":"bool"}],"name":"getCollateralAmountGivenUnderlyingAssetAmount","outputs":[{"internalType":"uint256","name":"collateralAmountRequired","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getFundingPNL","outputs":[{"internalType":"int256","name":"fundingPNL","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_trustedForwarder","type":"address"},{"internalType":"contract ILiquidityPool","name":"_liquidityPool","type":"address"},{"internalType":"uint256","name":"_perpetualIndex","type":"uint256"},{"internalType":"address","name":"_usdlemma","type":"address"},{"internalType":"address","name":"_reBalancer","type":"address"},{"internalType":"uint256","name":"_maxPosition","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityPool","outputs":[{"internalType":"contract ILiquidityPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPosition","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"collateralAmountRequired","type":"uint256"}],"name":"open","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"perpetualIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"positionAtSettlement","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_reBalancer","type":"address"},{"internalType":"int256","name":"amount","type":"int256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"reBalance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reBalancer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"realizedFundingPNL","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referrer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetApprovals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sendMCBToTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxPosition","type":"uint256"}],"name":"setMaxPosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_reBalancer","type":"address"}],"name":"setReBalancer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_referrer","type":"address"}],"name":"setReferrer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_usdlemma","type":"address"}],"name":"setUSDLemma","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdLemma","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506130a7806100206000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063bcc9c0f6116100a2578063d555f62311610071578063d555f623146103c7578063d8dfeb45146103da578063ec9c6c30146103ed578063f2fde38b146103f6576101f0565b8063bcc9c0f614610385578063beba14e114610398578063beeb9dfb146103ab578063d1870db9146103b4576101f0565b80639a919991116100de5780639a91999114610344578063a18a7bfc14610357578063a1f9637d1461036a578063a29558341461037d576101f0565b80638da5cb5b146103185780638ed59fd01461032057806392f72def1461032957806399cbad761461033c576101f0565b80634082de6711610187578063665a11ca11610156578063665a11ca146102bf57806368447c93146102ea578063715018a6146102fd578063851b137b14610305576101f0565b80634082de671461025e57806342bf732514610271578063572b6c051461027a578063596c8976146102ac576101f0565b80631d868875116101c35780631d8688751461023b57806333a581d214610244578063379afccc1461024d5780633d7bfaaa14610255576101f0565b80630d7e5a79146101f557806310dd5686146101ff57806311da60b414610212578063122e7b071461021a575b600080fd5b6101fd610409565b005b6101fd61020d366004612b28565b61052a565b6101fd6105ae565b6102286001600160ff1b0381565b6040519081526020015b60405180910390f35b61022860a05481565b61022860001981565b6101fd6106c0565b61022860a15481565b6101fd61026c366004612b07565b6106ff565b61022860985481565b61029c610288366004612794565b6065546001600160a01b0390811691161490565b6040519015158152602001610232565b6101fd6102ba366004612b07565b610a4c565b6097546102d2906001600160a01b031681565b6040516001600160a01b039091168152602001610232565b609d546102d2906001600160a01b031681565b6101fd610d42565b6101fd610313366004612794565b610d8b565b6102d2610e18565b610228609f5481565b610228610337366004612b40565b610e28565b6102286111ee565b610228610352366004612b40565b611335565b6101fd610365366004612794565b6113cb565b609c546102d2906001600160a01b031681565b6101fd611458565b61029c61039336600461283b565b6115a0565b609b546102d2906001600160a01b031681565b610228609e5481565b6101fd6103c23660046127cc565b6118f4565b6101fd6103d5366004612794565b611b36565b6099546102d2906001600160a01b031681565b610228609a5481565b6101fd610404366004612794565b611bc3565b609b546040805163019cd46760e71b81529051734e352cf164e64adcbad318c3a1e222e9eba4ce42926000926001600160a01b039091169163ce6a338091600480820192602092909190829003018186803b15801561046757600080fd5b505afa15801561047b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049f91906127b0565b6040516370a0823160e01b815230600482015290915061052690839083906001600160a01b038316906370a082319060240160206040518083038186803b1580156104e957600080fd5b505afa1580156104fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105219190612a3b565b611c73565b5050565b610532611cd6565b6001600160a01b0316610543610e18565b6001600160a01b0316146105725760405162461bcd60e51b815260040161056990612c43565b60405180910390fd5b60a18190556040518181527feb5034f650e091336850d826e4106a3b618d7d113464b5ad3d1f432900a0283c906020015b60405180910390a150565b609754609854604051637d3ba80f60e01b815260048101919091523060248201526000916001600160a01b031690637d3ba80f906044016101206040518083038186803b1580156105fe57600080fd5b505afa158015610612573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106369190612a80565b5050505050505091505061065161064c82611ce5565b611d01565b60a0556097546098546040516312c5a32760e31b815260048101919091523060248201526001600160a01b039091169063962d1938906044015b600060405180830381600087803b1580156106a557600080fd5b505af11580156106b9573d6000803e3d6000fd5b5050505050565b6099546097546106de916001600160a01b0390811691166000611d53565b6099546097546106fd916001600160a01b039081169116600019611d53565b565b609b546001600160a01b0316610713611cd6565b6001600160a01b0316146107395760405162461bcd60e51b815260040161056990612bbe565b610744816001611335565b6099546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561078757600080fd5b505afa15801561079b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bf9190612a3b565b10156108055760405162461bcd60e51b81526020600482015260156024820152741b9bdd08195b9bdd59da0818dbdb1b185d195c985b605a1b6044820152606401610569565b6097546098546001600160a01b03909116906378f140ea903061082785611e77565b6040516001600160e01b031960e086901b16815260048101939093526001600160a01b0390911660248301526044820152606401600060405180830381600087803b15801561087557600080fd5b505af1158015610889573d6000803e3d6000fd5b5050609754609854604051637d3ba80f60e01b81526004810191909152306024820152600093506001600160a01b039091169150637d3ba80f906044016101206040518083038186803b1580156108df57600080fd5b505afa1580156108f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109179190612a80565b5050505050505091505060a1548361093161064c84611ce5565b61093b9190612d4c565b11156109805760405162461bcd60e51b81526020600482015260146024820152731b585e081c1bdcda5d1a5bdb881c995858da195960621b6044820152606401610569565b6097546098546001600160a01b039091169063709240c490306109a287611e77565b609d546040516001600160e01b031960e087901b1681526109e2949392916001600160ff1b0391600019916001600160a01b031690600090600401612c78565b602060405180830381600087803b1580156109fc57600080fd5b505af1158015610a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a349190612a3b565b50610a4781610a4285611e77565b611ee1565b505050565b609b546001600160a01b0316610a60611cd6565b6001600160a01b031614610a865760405162461bcd60e51b815260040161056990612bbe565b6097546098546040516204966760e11b815260048101919091526000916001600160a01b03169062092cce906024016105206040518083038186803b158015610ace57600080fd5b505afa158015610ae2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0691906129a1565b5090915060049050816004811115610b2e57634e487b7160e01b600052602160045260246000fd5b14610d2057609754609854604051637d3ba80f60e01b815260048101919091523060248201526000916001600160a01b031690637d3ba80f906044016101206040518083038186803b158015610b8357600080fd5b505afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190612a80565b50506097546098549698506001600160a01b0316965063709240c4959450309350610beb92508a9150611e779050565b610bf490612ff2565b609d546040516001600160e01b031960e087901b168152610c2d94939291600091600019916001600160a01b0316908390600401612c78565b602060405180830381600087803b158015610c4757600080fd5b505af1158015610c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7f9190612a3b565b506097546098546001600160a01b0390911690636ef05a409030610ca287611e77565b6040516001600160e01b031960e086901b16815260048101939093526001600160a01b0390911660248301526044820152606401600060405180830381600087803b158015610cf057600080fd5b505af1158015610d04573d6000803e3d6000fd5b50505050610d1e81610d1586611e77565b610a4290612ff2565b505b609954609b54610a47916001600160a01b039081169116610521856000611335565b610d4a611cd6565b6001600160a01b0316610d5b610e18565b6001600160a01b031614610d815760405162461bcd60e51b815260040161056990612c43565b6106fd6000611fe2565b610d93611cd6565b6001600160a01b0316610da4610e18565b6001600160a01b031614610dca5760405162461bcd60e51b815260040161056990612c43565b609b80546001600160a01b0319166001600160a01b0383169081179091556040519081527fad0d6ee71196e4951edb077b61a235f17f0399e1bbd7bd8b7433fc34702ade79906020016105a3565b6033546001600160a01b03165b90565b609754604080516338437e9960e11b815290516000926001600160a01b031691637086fd32916004808301928692919082900301818387803b158015610e6d57600080fd5b505af1158015610e81573d6000803e3d6000fd5b50505050600082610ea357610e9584611e77565b610e9e90612ff2565b610eac565b610eac84611e77565b6097546098546040516204966760e11b81529293506000926001600160a01b039092169162092cce91610ee59160040190815260200190565b6105206040518083038186803b158015610efe57600080fd5b505afa158015610f12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3691906129a1565b5090915060049050816004811115610f5e57634e487b7160e01b600052602160045260246000fd5b14156110fd578315610fc15760405162461bcd60e51b815260206004820152602660248201527f63616e6e6f74206f70656e207768656e2070657270657475616c206861732073604482015265195d1d1b195960d21b6064820152608401610569565b609754609854604051637d3ba80f60e01b815260048101919091523060248201526000916001600160a01b031690637d3ba80f906044016101206040518083038186803b15801561101157600080fd5b505afa158015611025573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110499190612a80565b5050505094505050505080600014611063576110636105ae565b60a0546099546040516370a0823160e01b815230600482015288916001600160a01b0316906370a082319060240160206040518083038186803b1580156110a957600080fd5b505afa1580156110bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e19190612a3b565b6110eb9190612f3d565b6110f59190612d92565b9350506111e6565b609754609854609d546040516342ee6b0560e11b81526004810192909252306024830152604482018590526001600160a01b0390811660648301526000608483018190529283929116906385dcd60a9060a40160606040518083038186803b15801561116857600080fd5b505afa15801561117c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a09190612a53565b509150915060006111ba836111b48a611e77565b90612034565b9050866111d3576111ce61064c8383612f5c565b6111e0565b6111e061064c8383612d0b565b95505050505b505092915050565b6097546098546040516204966760e11b81526004810191909152600091829182916001600160a01b03169062092cce906024016105206040518083038186803b15801561123a57600080fd5b505afa15801561124e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127291906129a1565b60800151609754609854604051637d3ba80f60e01b81526004810191909152306024820152919550600094506001600160a01b03169250637d3ba80f91506044016101206040518083038186803b1580156112cc57600080fd5b505afa1580156112e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113049190612a80565b50505050505050915050611321828261203490919063ffffffff16565b609e5461132e9190612f5c565b9250505090565b60008180156113655750609a5461134d906012612f9b565b61135890600a612dec565b6113629084612fde565b15155b1561139f57609a54611378906012612f9b565b61138390600a612dec565b61138d9084612d92565b611398906001612d4c565b90506113c5565b609a546113ad906012612f9b565b6113b890600a612dec565b6113c29084612d92565b90505b92915050565b6113d3611cd6565b6001600160a01b03166113e4610e18565b6001600160a01b03161461140a5760405162461bcd60e51b815260040161056990612c43565b609d80546001600160a01b0319166001600160a01b0383169081179091556040519081527f3568f651c15bce2b453765b9ef9c58098f430d7c749b81132e5661a20fbc12fe906020016105a3565b611460611cd6565b6001600160a01b0316611471610e18565b6001600160a01b0316146114975760405162461bcd60e51b815260040161056990612c43565b6097546098546040516204966760e11b815260009283926001600160a01b039091169162092cce916114cf9160040190815260200190565b6105206040518083038186803b1580156114e857600080fd5b505afa1580156114fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152091906129a1565b610160015160995490945061155e93506001600160a01b031691506115459050611cd6565b3061155961155286611d01565b6001611335565b612064565b609754609854604051633c78a07560e11b81526004810191909152306024820152604481018390526001600160a01b03909116906378f140ea9060640161068b565b609754604080516338437e9960e11b815290516000926001600160a01b031691637086fd32916004808301928692919082900301818387803b1580156115e557600080fd5b505af11580156115f9573d6000803e3d6000fd5b5050609b546001600160a01b031691506116139050611cd6565b6001600160a01b0316146116395760405162461bcd60e51b815260040161056990612bbe565b609c546001600160a01b038681169116146116965760405162461bcd60e51b815260206004820152601a60248201527f6f6e6c7920726562616c616e63657220697320616c6c6f7765640000000000006044820152606401610569565b6000806116a584860186612b07565b9150915060006116b36111ee565b609754609854609d546040516342ee6b0560e11b81526004810192909252306024830152604482018b90526001600160a01b039081166064830152600060848301819052939450839216906385dcd60a9060a40160606040518083038186803b15801561171f57600080fd5b505afa158015611733573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117579190612a53565b5091509150600061176b836111b48c611ce5565b9050600061177c61064c8484612d0b565b905060008b12156117ac5761179081611e77565b609f60008282546117a19190612f5c565b909155506117cc9050565b6117b581611e77565b609f60008282546117c69190612d0b565b90915550505b6000609f54866117dc9190612f5c565b905064e8d4a510006117ed82611ce5565b13156118295760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd08185b1b1bddd95960aa1b6044820152606401610569565b609760009054906101000a90046001600160a01b03166001600160a01b031663709240c4609854308f8c8c609d60009054906101000a90046001600160a01b031660006040518863ffffffff1660e01b815260040161188e9796959493929190612c78565b602060405180830381600087803b1580156118a857600080fd5b505af11580156118bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e09190612a3b565b5060019d9c50505050505050505050505050565b600054610100900460ff168061190d575060005460ff16155b6119295760405162461bcd60e51b815260040161056990612bf5565b600054610100900460ff1615801561194b576000805461ffff19166101011790555b6119536120a2565b61195c8761211d565b609780546001600160a01b0319166001600160a01b03881690811790915560988690556040805163066e082d60e11b8152905160009283928392630cdc105a9160048082019261024092909190829003018186803b1580156119bd57600080fd5b505afa1580156119d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f591906128db565b945050935050925082611a405760405162461bcd60e51b8152602060048201526013602482015272706f6f6c206973206e6f742072756e6e696e6760681b6044820152606401610569565b60a09190910151609980546001600160a01b0319166001600160a01b0390921691909117905551609a5550611a7483611b36565b611a7d84610d8b565b611a868261052a565b609954609754611aa5916001600160a01b039081169116600019611d53565b609754609854604051632d47ba5760e01b81526004810191909152306024820152670de0b6b3a764000060448201526001600160a01b0390911690632d47ba5790606401600060405180830381600087803b158015611b0357600080fd5b505af1158015611b17573d6000803e3d6000fd5b505050508015611b2d576000805461ff00191690555b50505050505050565b611b3e611cd6565b6001600160a01b0316611b4f610e18565b6001600160a01b031614611b755760405162461bcd60e51b815260040161056990612c43565b609c80546001600160a01b0319166001600160a01b0383169081179091556040519081527f82932c2bbe344307ce4c4d0134c032fd62927625f9603697984f4f2668bc1ddc906020016105a3565b611bcb611cd6565b6001600160a01b0316611bdc610e18565b6001600160a01b031614611c025760405162461bcd60e51b815260040161056990612c43565b6001600160a01b038116611c675760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610569565b611c7081611fe2565b50565b6040516001600160a01b038316602482015260448101829052610a4790849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261219a565b6000611ce061226c565b905090565b600080821215611cfd57611cf882612298565b6113c5565b5090565b600080821215611cfd5760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610569565b801580611ddc5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015611da257600080fd5b505afa158015611db6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dda9190612a3b565b155b611e475760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610569565b6040516001600160a01b038316602482015260448101829052610a4790849063095ea7b360e01b90606401611c9f565b60006001600160ff1b03821115611cfd5760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b6064820152608401610569565b600080611eee84846122a5565b6097546098546040516204966760e11b8152600481019190915292945090925060009182916001600160a01b03169062092cce906024016105206040518083038186803b158015611f3e57600080fd5b505afa158015611f52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7691906129a1565b6080015193505084159150611fbb905057846000611f948583612d0b565b9050611fb582611faf83609e5461203490919063ffffffff16565b90612303565b609e5550505b81156106b957611fcb8183612034565b609e54611fd89190612d0b565b609e555050505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000670de0b6b3a764000061205a61204c8585612349565b670de0b6b3a7640000612355565b6113c29190612d64565b6040516001600160a01b038085166024830152831660448201526064810182905261209c9085906323b872dd60e01b90608401611c9f565b50505050565b600054610100900460ff16806120bb575060005460ff16155b6120d75760405162461bcd60e51b815260040161056990612bf5565b600054610100900460ff161580156120f9576000805461ffff19166101011790555b6121016123d8565b612109612442565b8015611c70576000805461ff001916905550565b600054610100900460ff1680612136575060005460ff16155b6121525760405162461bcd60e51b815260040161056990612bf5565b600054610100900460ff16158015612174576000805461ffff19166101011790555b61217c6123d8565b612185826124a9565b8015610526576000805461ff00191690555050565b60006121ef826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166125309092919063ffffffff16565b805190915015610a47578080602001905181019061220d91906128bf565b610a475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610569565b6065546000906001600160a01b0316331415612291575060131936013560601c610e25565b5033610e25565b60006113c5600083612549565b6000806122b28484612555565b156122c2575060009050816122fc565b6122cb83611ce5565b6122d485611ce5565b126122e4575081905060006122fc565b6122ed84612298565b6122f78585612578565b915091505b9250929050565b6000808212156123245761231682612298565b915061232183612298565b92505b6113c28261234361233d86670de0b6b3a7640000612349565b85612355565b90612584565b60006113c28284612eba565b60008082136123a65760405162461bcd60e51b815260206004820152601f60248201527f726f756e6448616c665570206f6e6c7920737570706f7274732079203e2030006044820152606401610569565b600083126123c3576113986123bc600284612d64565b8490612578565b6113c26123d1600284612d64565b8490612549565b600054610100900460ff16806123f1575060005460ff16155b61240d5760405162461bcd60e51b815260040161056990612bf5565b600054610100900460ff16158015612109576000805461ffff19166101011790558015611c70576000805461ff001916905550565b600054610100900460ff168061245b575060005460ff16155b6124775760405162461bcd60e51b815260040161056990612bf5565b600054610100900460ff16158015612499576000805461ffff19166101011790555b6121096124a4611cd6565b611fe2565b600054610100900460ff16806124c2575060005460ff16155b6124de5760405162461bcd60e51b815260040161056990612bf5565b600054610100900460ff16158015612500576000805461ffff19166101011790555b606580546001600160a01b0319166001600160a01b0384161790558015610526576000805461ff00191690555050565b606061253f8484600085612590565b90505b9392505050565b60006113c28284612f5c565b6000821580612562575081155b1561256f575060016113c5565b501860ff1d1590565b60006113c28284612d0b565b60006113c28284612d64565b6060824710156125f15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610569565b843b61263f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610569565b600080866001600160a01b0316858760405161265b9190612b6f565b60006040518083038185875af1925050503d8060008114612698576040519150601f19603f3d011682016040523d82523d6000602084013e61269d565b606091505b50915091506126ad8282866126b8565b979650505050505050565b606083156126c7575081612542565b8251156126d75782518084602001fd5b8160405162461bcd60e51b81526004016105699190612b8b565b600082601f830112612701578081fd5b61270b60a0612cb9565b80838560a08601111561271c578384fd5b835b600581101561273d57815184526020938401939091019060010161271e565b509095945050505050565b600082601f830112612758578081fd5b6127626080612cb9565b808385608086011115612773578384fd5b835b600481101561273d578151845260209384019390910190600101612775565b6000602082840312156127a5578081fd5b81356125428161304e565b6000602082840312156127c1578081fd5b81516125428161304e565b60008060008060008060c087890312156127e4578182fd5b86356127ef8161304e565b955060208701356127ff8161304e565b94506040870135935060608701356128168161304e565b925060808701356128268161304e565b8092505060a087013590509295509295509295565b60008060008060608587031215612850578384fd5b843561285b8161304e565b935060208501359250604085013567ffffffffffffffff8082111561287e578384fd5b818701915087601f830112612891578384fd5b81358181111561289f578485fd5b8860208285010111156128b0578485fd5b95989497505060200194505050565b6000602082840312156128d0578081fd5b815161254281613063565b600080600080600061024086880312156128f3578283fd5b85516128fe81613063565b8095505060208087015161291181613063565b9450605f87018813612921578384fd5b600761293461292f82612cea565b612cb9565b8060408a016101208b018c81111561294a578889fd5b885b8581101561297157825161295f8161304e565b8552938601939186019160010161294c565b5082985061297f8d826126f1565b9750505050505050612995876101c08801612748565b90509295509295909350565b60008060006105208085870312156129b7578182fd5b8451600581106129c5578283fd5b809450506020808601516129d88161304e565b9350605f860187136129e8578283fd5b60276129f661292f82612cea565b80604089018a868b011115612a09578687fd5b8695505b83861015612a2b578051835260019590950194918401918401612a0d565b5080955050505050509250925092565b600060208284031215612a4c578081fd5b5051919050565b600080600060608486031215612a67578081fd5b8351925060208401519150604084015190509250925092565b60008060008060008060008060006101208a8c031215612a9e578687fd5b8951985060208a0151975060408a0151965060608a0151955060808a0151945060a08a0151612acc81613063565b60c08b0151909450612add81613063565b60e08b0151909350612aee81613063565b809250506101008a015190509295985092959850929598565b60008060408385031215612b19578182fd5b50508035926020909101359150565b600060208284031215612b39578081fd5b5035919050565b60008060408385031215612b52578182fd5b823591506020830135612b6481613063565b809150509250929050565b60008251612b81818460208701612fb2565b9190910192915050565b6000602082528251806020840152612baa816040850160208701612fb2565b601f01601f19169190910160400192915050565b60208082526018908201527f6f6e6c79207573644c656d6d6120697320616c6c6f7765640000000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b9687526001600160a01b03958616602088015260408701949094526060860192909252608085015290911660a083015263ffffffff1660c082015260e00190565b604051601f8201601f1916810167ffffffffffffffff81118282101715612ce257612ce2613038565b604052919050565b600067ffffffffffffffff821115612d0457612d04613038565b5060051b90565b600080821280156001600160ff1b0384900385131615612d2d57612d2d61300c565b600160ff1b8390038412811615612d4657612d4661300c565b50500190565b60008219821115612d5f57612d5f61300c565b500190565b600082612d7357612d73613022565b600160ff1b821460001984141615612d8d57612d8d61300c565b500590565b600082612da157612da1613022565b500490565b80825b6001808611612db85750612de3565b818704821115612dca57612dca61300c565b80861615612dd757918102915b9490941c938002612da9565b94509492505050565b60006113c26000198484600082612e0557506001612542565b81612e1257506000612542565b8160018114612e285760028114612e3257612e5f565b6001915050612542565b60ff841115612e4357612e4361300c565b6001841b915084821115612e5957612e5961300c565b50612542565b5060208310610133831016604e8410600b8410161715612e92575081810a83811115612e8d57612e8d61300c565b612542565b612e9f8484846001612da6565b808604821115612eb157612eb161300c565b02949350505050565b60006001600160ff1b0381841382841380821686840486111615612ee057612ee061300c565b600160ff1b84871282811687830589121615612efe57612efe61300c565b858712925087820587128484161615612f1957612f1961300c565b87850587128184161615612f2f57612f2f61300c565b505050929093029392505050565b6000816000190483118215151615612f5757612f5761300c565b500290565b60008083128015600160ff1b850184121615612f7a57612f7a61300c565b6001600160ff1b0384018313811615612f9557612f9561300c565b50500390565b600082821015612fad57612fad61300c565b500390565b60005b83811015612fcd578181015183820152602001612fb5565b8381111561209c5750506000910152565b600082612fed57612fed613022565b500690565b6000600160ff1b8214156130085761300861300c565b0390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611c7057600080fd5b8015158114611c7057600080fdfea2646970667358221220d284b3caf5e7fb3058740f5daf4b698f904d727333ef9e2b5e9d2a6a238a373064736f6c63430008030033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.