@ethersproject/providers#JsonRpcProvider JavaScript Examples
The following examples show how to use
@ethersproject/providers#JsonRpcProvider.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js From acy-dex-interface with MIT License | 6 votes |
export function getProvider(library, chainId) {
if (library) {
return library.getSigner();
}
// let provider;
// provider = _.sample(RPC_PROVIDERS[chainId]);
// return new ethers.providers.StaticJsonRpcProvider(provider, { chainId });
return new JsonRpcProvider('https://arb1.arbitrum.io/rpc');
}
Example #2
Source File: UserSigner.js From Tai-Shang-NFT-Wallet with MIT License | 6 votes |
parseProviderOrSigner = async providerOrSigner => {
let signer = undefined;
let provider;
let providerNetwork;
if (providerOrSigner && (providerOrSigner instanceof JsonRpcProvider || providerOrSigner instanceof Web3Provider)) {
const accounts = await providerOrSigner.listAccounts();
if (accounts && accounts.length > 0) {
signer = providerOrSigner.getSigner();
}
provider = providerOrSigner;
providerNetwork = await providerOrSigner.getNetwork();
}
if (!signer && providerOrSigner instanceof Signer) {
signer = providerOrSigner;
provider = signer.provider;
providerNetwork = provider && (await provider.getNetwork());
}
return { signer, provider, providerNetwork };
}
Example #3
Source File: constants.js From acy-dex-interface with MIT License | 5 votes |
tempLibrary = new JsonRpcProvider('https://arb1.arbitrum.io/rpc')
Example #4
Source File: index.js From acy-dex-interface with MIT License | 5 votes |
defaultLibrary = new JsonRpcProvider('https://bsc-dataseed1.defibit.io/')
Example #5
Source File: index.js From acy-dex-interface with MIT License | 4 votes |
SwapComponent = props => {
const {
account,
library,
chainId,
tokenList: INITIAL_TOKEN_LIST,
farmSetting: { INITIAL_ALLOWED_SLIPPAGE },
perpetuals
} = useConstantLoader(props);
const {
swapOption: mode,
setSwapOption: setMode,
activeToken0,
setActiveToken0,
activeToken1,
setActiveToken1,
toTokenAddress,
setToTokenAddress,
fromTokenAddress,
setFromTokenAddress,
positionsMap,
pendingTxns,
setPendingTxns,
savedIsPnlInLeverage,
approveOrderBook,
isWaitingForPluginApproval,
setIsWaitingForPluginApproval,
isPluginApproving,
isConfirming,
setIsConfirming,
isPendingConfirmation,
setIsPendingConfirmation,
isBuying,
setIsBuying,
onChangeMode,
swapTokenAddress,
setSwapTokenAddress,
glp_isWaitingForApproval,
glp_setIsWaitingForApproval,
orders,
minExecutionFee
} = props;
const connectWalletByLocalStorage = useConnectWallet();
const { active, activate } = useWeb3React();
const [type, setType] = useState(MARKET);
const [fromValue, setFromValue] = useState("");
const [toValue, setToValue] = useState("");
const [anchorOnFromAmount, setAnchorOnFromAmount] = useState(true);
const [isApproving, setIsApproving] = useState(false);
const [isWaitingForApproval, setIsWaitingForApproval] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
// const [isConfirming, setIsConfirming] = useState(false);
const [modalError, setModalError] = useState(false);
const [ordersToaOpen, setOrdersToaOpen] = useState(false);
const [isHigherSlippageAllowed, setIsHigherSlippageAllowed] = useState(false);
const savedSlippageAmount = getSavedSlippageAmount(chainId)
let allowedSlippage = savedSlippageAmount;
if (isHigherSlippageAllowed) {
allowedSlippage = DEFAULT_HIGHER_SLIPPAGE_AMOUNT;
}
const tokens = perpetuals.tokenList;
const whitelistedTokens = tokens.filter(t => t.symbol !== "USDG")
const stableTokens = tokens.filter(token => token.isStable);
const indexTokens = whitelistedTokens.filter(token => !token.isStable && !token.isWrapped);
const shortableTokens = indexTokens.filter(token => token.isShortable);
let toTokens = tokens;
const isLong = mode === LONG;
const isShort = mode === SHORT;
if (isLong) {
toTokens = indexTokens;
}
if (isShort) {
toTokens = shortableTokens;
}
// const [fromTokenAddress, setFromTokenAddress] = useState("0x0000000000000000000000000000000000000000");
const initialToToken = perpetuals.getTokenBySymBol("BTC").address;
console.log("initialToToken: ", initialToToken, chainId)
// const [toTokenAddress, setToTokenAddress] = useState(initialToToken);
// const [fromTokenInfo, setFromTokenInfo] = useState();
// const [toTokenInfo, setToTokenInfo] = useState();
// const [fees, setFees] = useState(0.1);
// const [leverage, setLeverage] = useState(5);
// const [isLeverageSliderEnabled, setIsLeverageSliderEnabled] = useState(true);
// const [entryPriceLimit, setEntryPriceLimit] = useState(0);
// const [priceValue, setPriceValue] = useState('');
// const [shortCollateralAddress, setShortCollateralAddress] = useState('0xf97f4df75117a78c1A5a0DBb814Af92458539FB4');
// const [isWaitingForPluginApproval, setIsWaitingForPluginApproval] = useState(false);
const tokenAddresses = tokens.map(token => token.address)
const readerAddress = perpetuals.getContract("Reader")
const vaultAddress = perpetuals.getContract("Vault")
const usdgAddress = perpetuals.getContract("USDG")
const nativeTokenAddress = perpetuals.getContract("NATIVE_TOKEN")
const routerAddress = perpetuals.getContract("Router")
const orderBookAddress = perpetuals.getContract("OrderBook")
const glpManagerAddress = perpetuals.getContract("GlpManager")
const glpAddress = perpetuals.getContract("GLP")
const { farmSetting: { RPC_URL }} = useConstantLoader();
const provider = new JsonRpcProvider(RPC_URL, chainId);
const { data: tokenBalances, mutate: updateTokenBalances } = useSWR([chainId, readerAddress, "getTokenBalances", account || PLACEHOLDER_ACCOUNT], {
fetcher: fetcher(library, Reader, [tokenAddresses]),
})
const whitelistedTokenAddresses = whitelistedTokens.map(token => token.address)
const { data: vaultTokenInfo, mutate: updateVaultTokenInfo } = useSWR([chainId, readerAddress, "getFullVaultTokenInfo"], {
fetcher: fetcher(library, Reader, [vaultAddress, nativeTokenAddress, expandDecimals(1, 18), whitelistedTokenAddresses]),
})
const { data: fundingRateInfo, mutate: updateFundingRateInfo } = useSWR([chainId, readerAddress, "getFundingRates"], {
fetcher: fetcher(library, Reader, [vaultAddress, nativeTokenAddress, whitelistedTokenAddresses]),
})
const { data: totalTokenWeights, mutate: updateTotalTokenWeights } = useSWR([chainId, vaultAddress, "totalTokenWeights"], {
fetcher: fetcher(library, Vault),
})
const { data: usdgSupply, mutate: updateUsdgSupply } = useSWR([chainId, usdgAddress, "totalSupply"], {
fetcher: fetcher(library, Glp),
})
const { data: orderBookApproved, mutate: updateOrderBookApproved } = useSWR([chainId, routerAddress, "approvedPlugins", account || PLACEHOLDER_ACCOUNT, orderBookAddress], {
fetcher: fetcher(library, Router)
});
console.log("test orderbook approved: ", routerAddress, account, orderBookAddress, orderBookApproved)
useEffect(() => {
if (active) {
function onBlock() {
updateVaultTokenInfo()
updateTokenBalances()
// updatePositionData(undefined, true)
updateFundingRateInfo()
updateTotalTokenWeights()
updateUsdgSupply()
updateOrderBookApproved()
}
library.on('block', onBlock)
return () => {
library.removeListener('block', onBlock)
}
}
}, [active, library, chainId,
updateVaultTokenInfo, updateTokenBalances, updateFundingRateInfo, updateTotalTokenWeights, updateUsdgSupply,
updateOrderBookApproved])
const tokenAllowanceAddress = fromTokenAddress === AddressZero ? nativeTokenAddress : fromTokenAddress;
const { data: tokenAllowance, mutate: updateTokenAllowance } = useSWR([chainId, tokenAllowanceAddress, "allowance", account || PLACEHOLDER_ACCOUNT, routerAddress], {
fetcher: fetcher(library, Glp)
});
console.log("test needOrderBookApproval: ", type!==MARKET, !orderBookApproved)
const needOrderBookApproval = type !== MARKET && !orderBookApproved;
const prevNeedOrderBookApproval = usePrevious(needOrderBookApproval);
useEffect(() => {
if (
!needOrderBookApproval &&
prevNeedOrderBookApproval &&
isWaitingForPluginApproval
) {
setIsWaitingForPluginApproval(false);
helperToast.success(<div>Orders enabled!</div>);
}
}, [
needOrderBookApproval,
prevNeedOrderBookApproval,
setIsWaitingForPluginApproval,
isWaitingForPluginApproval
]);
const [triggerPriceValue, setTriggerPriceValue] = useState("");
const triggerPriceUsd = type === MARKET ? 0 : parseValue(triggerPriceValue, USD_DECIMALS);
const onTriggerPriceChange = evt => {
setTriggerPriceValue(evt.target.value || "");
};
const onTriggerRatioChange = evt => {
setTriggerRatioValue(evt.target.value || "");
};
// default collateral address on ARBITRUM
const [shortCollateralAddress, setShortCollateralAddress] = useState(fromTokenAddress);
const infoTokens = getInfoTokens(tokens, tokenBalances, whitelistedTokens, vaultTokenInfo, fundingRateInfo)
console.log("test multichain: tokens", infoTokens, tokens)
const fromToken = perpetuals.getToken(fromTokenAddress);
const toToken = perpetuals.getToken(toTokenAddress);
const shortCollateralToken = getTokenInfo(infoTokens, shortCollateralAddress);
const fromTokenInfo = getTokenInfo(infoTokens, fromTokenAddress);
const toTokenInfo = getTokenInfo(infoTokens, toTokenAddress);
const fromBalance = fromTokenInfo ? fromTokenInfo.balance : bigNumberify(0);
const toBalance = toTokenInfo ? toTokenInfo.balance : bigNumberify(0);
const fromAmount = parseValue(fromValue, fromToken && fromToken.decimals);
const toAmount = parseValue(toValue, toToken && toToken.decimals);
const isPotentialWrap = (fromToken.isNative && toToken.isWrapped) || (fromToken.isWrapped && toToken.isNative);
const isWrapOrUnwrap = mode === SWAP && isPotentialWrap;
const needApproval =
fromTokenAddress !== AddressZero &&
tokenAllowance &&
fromAmount &&
fromAmount.gt(tokenAllowance) &&
!isWrapOrUnwrap;
console.log("needApproval? ", needApproval)
const prevFromTokenAddress = usePrevious(fromTokenAddress);
const prevNeedApproval = usePrevious(needApproval);
const prevToTokenAddress = usePrevious(toTokenAddress);
const fromUsdMin = getUsd(fromAmount, fromTokenAddress, false, infoTokens);
const toUsdMax = getUsd(toAmount, toTokenAddress, true, infoTokens, type, triggerPriceUsd);
const indexTokenAddress = toTokenAddress === AddressZero ? nativeTokenAddress : toTokenAddress;
// const collateralTokenAddress = isLong
// ? indexTokenAddress
// : shortCollateralAddress;
const collateralTokenAddress = shortCollateralAddress;
const collateralToken = perpetuals.getToken(collateralTokenAddress);
const [triggerRatioValue, setTriggerRatioValue] = useState("");
const triggerRatioInverted = useMemo(() => {
return isTriggerRatioInverted(fromTokenInfo, toTokenInfo);
}, [toTokenInfo, fromTokenInfo]);
const triggerRatio = useMemo(() => {
if (!triggerRatioValue) {
return bigNumberify(0);
}
let ratio = parseValue(triggerRatioValue, USD_DECIMALS);
if (ratio.eq(0)) {
return bigNumberify(0);
}
if (triggerRatioInverted) {
ratio = PRECISION.mul(PRECISION).div(ratio);
}
return ratio;
}, [triggerRatioValue, triggerRatioInverted]);
const getTokenLabel = () => {
if (isLong) {
return "Long";
}
return "Short";
};
const leverageMarks = {
// 0.1: {
// style: { color: '#b5b6b6', },
// label: '0.1x'
// },
1: {
style: { color: '#b5b6b6', },
label: '1x'
},
// 2: {
// style: { color: '#b5b6b6', },
// label: '2x'
// },
5: {
style: { color: '#b5b6b6', },
label: '5x'
},
10: {
style: { color: '#b5b6b6', },
label: '10x'
},
15: {
style: { color: '#b5b6b6', },
label: '15x'
},
20: {
style: { color: '#b5b6b6', },
label: '20x'
},
25: {
style: { color: '#b5b6b6', },
label: '25x'
},
30: {
style: { color: '#b5b6b6', },
label: '30x'
}
};
const [leverageOption, setLeverageOption] = useLocalStorageSerializeKey([chainId, "Exchange-swap-leverage-option"], "2");
useEffect(() => console.log("leverageOption ", leverageOption), [leverageOption])
const [isLeverageSliderEnabled, setIsLeverageSliderEnabled] = useLocalStorageSerializeKey([chainId, "Exchange-swap-leverage-slider-enabled"], true);
const hasLeverageOption = isLeverageSliderEnabled && !isNaN(parseFloat(leverageOption));
useEffect(() => {
if (
fromToken &&
fromTokenAddress === prevFromTokenAddress &&
!needApproval &&
prevNeedApproval &&
isWaitingForApproval
) {
setIsWaitingForApproval(false);
helperToast.success(<div>{fromToken.symbol} approved!</div>);
}
}, [
fromTokenAddress,
prevFromTokenAddress,
needApproval,
prevNeedApproval,
setIsWaitingForApproval,
fromToken.symbol,
isWaitingForApproval,
fromToken
]);
useEffect(() => {
if (!toTokens.find(token => token.address === toTokenAddress)) {
setToTokenAddress(mode, toTokens[0].address);
}
}, [mode, toTokens, toTokenAddress, setToTokenAddress]);
useEffect(() => {
if (active) {
function onBlock() {
console.log("onBlock, updateTokenAllowance");
updateTokenAllowance(undefined, true);
}
library.on("block", onBlock);
return () => {
library.removeListener("block", onBlock);
};
}
}, [active, library, updateTokenAllowance]);
useEffect(() => {
if (mode !== SHORT) {
return;
}
if (toTokenAddress === prevToTokenAddress) {
return;
}
for (let i = 0; i < stableTokens.length; i++) {
const stableToken = stableTokens[i];
const key = getPositionKey(
stableToken.address,
toTokenAddress,
false,
nativeTokenAddress
);
const position = positionsMap[key];
if (position && position.size && position.size.gt(0)) {
setShortCollateralAddress(position.collateralToken.address);
return;
}
}
}, [
toTokenAddress,
prevToTokenAddress,
mode,
positionsMap,
stableTokens,
nativeTokenAddress,
shortCollateralAddress,
setShortCollateralAddress
]);
useEffect(() => {
const updateLeverageAmounts = () => {
if (!hasLeverageOption) {
return;
}
if (anchorOnFromAmount) {
if (!fromAmount) {
setToValue("");
return;
}
const toTokenInfo = getTokenInfo(infoTokens, toTokenAddress);
if (
toTokenInfo &&
toTokenInfo.maxPrice &&
fromUsdMin &&
fromUsdMin.gt(0)
) {
const leverageMultiplier = parseInt(
leverageOption * BASIS_POINTS_DIVISOR
);
const toTokenPriceUsd =
type !== MARKET && triggerPriceUsd && triggerPriceUsd.gt(0)
? triggerPriceUsd
: toTokenInfo.maxPrice;
const { feeBasisPoints } = getNextToAmount(
chainId,
fromAmount,
fromTokenAddress,
collateralTokenAddress,
infoTokens,
undefined,
undefined,
usdgSupply,
totalTokenWeights
);
let fromUsdMinAfterFee = fromUsdMin;
if (feeBasisPoints) {
fromUsdMinAfterFee = fromUsdMin
.mul(BASIS_POINTS_DIVISOR - feeBasisPoints)
.div(BASIS_POINTS_DIVISOR);
}
const toNumerator = fromUsdMinAfterFee.mul(leverageMultiplier).mul(BASIS_POINTS_DIVISOR)
const toDenominator = bigNumberify(MARGIN_FEE_BASIS_POINTS).mul(leverageMultiplier).add(bigNumberify(BASIS_POINTS_DIVISOR).mul(BASIS_POINTS_DIVISOR))
const nextToUsd = toNumerator.div(toDenominator)
const nextToAmount = nextToUsd
.mul(expandDecimals(1, toToken.decimals))
.div(toTokenPriceUsd);
const nextToValue = formatAmountFree(
nextToAmount,
toToken.decimals,
toToken.decimals
);
setToValue(nextToValue);
}
return;
}
if (!toAmount) {
setFromValue("");
return;
}
const fromTokenInfo = getTokenInfo(infoTokens, fromTokenAddress);
if (
fromTokenInfo &&
fromTokenInfo.minPrice &&
toUsdMax &&
toUsdMax.gt(0)
) {
const leverageMultiplier = parseInt(
leverageOption * BASIS_POINTS_DIVISOR
);
const baseFromAmountUsd = toUsdMax
.mul(BASIS_POINTS_DIVISOR)
.div(leverageMultiplier);
let fees = toUsdMax
.mul(MARGIN_FEE_BASIS_POINTS)
.div(BASIS_POINTS_DIVISOR);
const { feeBasisPoints } = getNextToAmount(
chainId,
fromAmount,
fromTokenAddress,
collateralTokenAddress,
infoTokens,
undefined,
undefined,
usdgSupply,
totalTokenWeights
);
if (feeBasisPoints) {
const swapFees = baseFromAmountUsd
.mul(feeBasisPoints)
.div(BASIS_POINTS_DIVISOR);
fees = fees.add(swapFees);
}
const nextFromUsd = baseFromAmountUsd.add(fees);
const nextFromAmount = nextFromUsd
.mul(expandDecimals(1, fromToken.decimals))
.div(fromTokenInfo.minPrice);
const nextFromValue = formatAmountFree(
nextFromAmount,
fromToken.decimals,
fromToken.decimals
);
setFromValue(nextFromValue);
}
};
if (isLong || isShort) {
updateLeverageAmounts();
}
}, [
mode,
type,
anchorOnFromAmount,
fromAmount,
toAmount,
fromToken,
toToken,
fromTokenAddress,
toTokenAddress,
infoTokens,
leverageOption,
fromUsdMin,
toUsdMax,
triggerPriceUsd,
triggerRatio,
hasLeverageOption,
usdgSupply,
totalTokenWeights,
chainId,
collateralTokenAddress,
indexTokenAddress
]);
let entryMarkPrice;
let exitMarkPrice;
if (toTokenInfo) {
entryMarkPrice =
isLong ? toTokenInfo.maxPrice : toTokenInfo.minPrice;
exitMarkPrice =
isLong ? toTokenInfo.minPrice : toTokenInfo.maxPrice;
}
let leverage = bigNumberify(0);
if (fromUsdMin && toUsdMax && fromUsdMin.gt(0)) {
const fees = toUsdMax.mul(MARGIN_FEE_BASIS_POINTS).div(BASIS_POINTS_DIVISOR);
if (fromUsdMin.sub(fees).gt(0)) {
leverage = toUsdMax.mul(BASIS_POINTS_DIVISOR).div(fromUsdMin.sub(fees));
}
}
let nextAveragePrice = type === MARKET ? entryMarkPrice : triggerPriceUsd;
if (hasExistingPosition) {
let nextDelta
let nextHasProfit
if (type === MARKET) {
nextDelta = existingPosition.delta;
nextHasProfit = existingPosition.hasProfit;
} else {
const data = calculatePositionDelta(
triggerPriceUsd || bigNumberify(0),
existingPosition
);
nextDelta = data.delta;
nextHasProfit = data.hasProfit;
}
nextAveragePrice = getNextAveragePrice({
size: existingPosition.size,
sizeDelta: toUsdMax,
hasProfit: nextHasProfit,
delta: nextDelta,
nextPrice: type === MARKET ? entryMarkPrice : triggerPriceUsd,
isLong: mode === LONG
});
}
let positionKey;
if (isLong) {
positionKey = getPositionKey(
toTokenAddress,
toTokenAddress,
true,
nativeTokenAddress
);
}
if (isShort) {
positionKey = getPositionKey(
shortCollateralAddress,
toTokenAddress,
false,
nativeTokenAddress
);
}
const existingPosition = positionKey ? positionsMap[positionKey] : undefined;
const hasExistingPosition = existingPosition && existingPosition.size && existingPosition.size.gt(0);
const liquidationPrice = getLiquidationPrice({
isLong: mode === LONG,
size: hasExistingPosition ? existingPosition.size : bigNumberify(0),
collateral: hasExistingPosition
? existingPosition.collateral
: bigNumberify(0),
averagePrice: nextAveragePrice,
entryFundingRate: hasExistingPosition
? existingPosition.entryFundingRate
: bigNumberify(0),
cumulativeFundingRate: hasExistingPosition
? existingPosition.cumulativeFundingRate
: bigNumberify(0),
sizeDelta: toUsdMax,
collateralDelta: fromUsdMin,
increaseCollateral: true,
increaseSize: true
});
const existingLiquidationPrice = existingPosition
? getLiquidationPrice(existingPosition)
: undefined;
let displayLiquidationPrice = liquidationPrice
? liquidationPrice
: existingLiquidationPrice;
if (hasExistingPosition) {
const collateralDelta = fromUsdMin ? fromUsdMin : bigNumberify(0);
const sizeDelta = toUsdMax ? toUsdMax : bigNumberify(0);
leverage = getLeverage({
size: existingPosition.size,
sizeDelta,
collateral: existingPosition.collateral,
collateralDelta,
increaseCollateral: true,
entryFundingRate: existingPosition.entryFundingRate,
cumulativeFundingRate: existingPosition.cumulativeFundingRate,
increaseSize: true,
hasProfit: existingPosition.hasProfit,
delta: existingPosition.delta,
includeDelta: savedIsPnlInLeverage
});
} else if (hasLeverageOption) {
leverage = bigNumberify(parseInt(leverageOption * BASIS_POINTS_DIVISOR));
}
const selectFromToken = symbol => {
const token = getTokenfromSymbol(tokens, symbol)
setFromTokenAddress(mode, token.address);
console.log("update from token: ", symbol, token, mode);
setActiveToken0((tokens.filter(ele => ele.symbol === symbol))[0]);
setIsWaitingForApproval(false);
if (isShort) {
console.log("is short and changed short collateral token to ", token.address)
setShortCollateralAddress(token.address);
}
};
const getToUsdAmount = () => {
}
useEffect(() => {
console.log("update from token 1: ", fromTokenAddress)
}, [fromTokenAddress])
useEffect(() => {
const fromToken = getTokenfromSymbol(tokens, activeToken0.symbol)
const toToken = getTokenfromSymbol(tokens, activeToken1.symbol)
setFromTokenAddress(mode, fromToken.address);
setToTokenAddress(mode, toToken.address);
}, [activeToken0, activeToken1])
console.log("show this")
const selectToToken = symbol => {
const token = getTokenfromSymbol(tokens, symbol)
console.log("selectToToken symbol and address", symbol, token.address)
setToTokenAddress(mode, token.address);
setActiveToken1((tokens.filter(ele => ele.symbol === symbol))[0]);
};
const onFromValueChange = e => {
setAnchorOnFromAmount(true);
setFromValue(e.target.value);
};
const onToValueChange = e => {
setAnchorOnFromAmount(false);
setToValue(e.target.value);
};
const createIncreaseOrder = () => {
console.log("inside createIncreaseOrder")
let path = [fromTokenAddress];
if (path[0] === USDG_ADDRESS) {
if (isLong) {
const stableToken = getMostAbundantStableToken(chainId, infoTokens);
path.push(stableToken.address);
} else {
path.push(shortCollateralAddress);
}
}
const minOut = 0;
const indexToken = perpetuals.getToken(indexTokenAddress);
const successMsg = `
Created limit order for ${indexToken.symbol} ${isLong ? "Long" : "Short"}: ${formatAmount(toUsdMax, USD_DECIMALS, 2)} USD!`;
return Api.createIncreaseOrder(
chainId,
library,
nativeTokenAddress,
path,
fromAmount,
indexTokenAddress,
minOut,
toUsdMax,
collateralTokenAddress,
isLong,
triggerPriceUsd,
{
pendingTxns,
setPendingTxns,
sentMsg: "Limit order submitted!",
successMsg,
failMsg: "Limit order creation failed.",
}
)
.then(() => {
setIsConfirming(false);
})
.finally(() => {
setIsSubmitting(false);
setIsPendingConfirmation(false);
});
};
// refers to gmx 9c6b4a8 commit
const increasePosition = async () => {
console.log("try to increasePosition");
setIsSubmitting(true);
const tokenAddress0 = fromTokenAddress === AddressZero ? nativeTokenAddress : fromTokenAddress;
const indexTokenAddress = toTokenAddress === AddressZero ? nativeTokenAddress : toTokenAddress;
let path = [indexTokenAddress]; // assume long
if (toTokenAddress !== fromTokenAddress) {
path = [tokenAddress0];
}
if (fromTokenAddress === AddressZero && toTokenAddress === nativeTokenAddress) {
path = [nativeTokenAddress];
}
if (fromTokenAddress === nativeTokenAddress && toTokenAddress === AddressZero) {
path = [nativeTokenAddress];
}
if (isShort) {
path = [shortCollateralAddress];
if (tokenAddress0 !== shortCollateralAddress) {
path = [tokenAddress0, shortCollateralAddress];
}
}
const refPrice = isLong ? toTokenInfo.maxPrice : toTokenInfo.minPrice;
const priceBasisPoints = isLong ? BASIS_POINTS_DIVISOR + allowedSlippage : BASIS_POINTS_DIVISOR - allowedSlippage;
const priceLimit = refPrice.mul(priceBasisPoints).div(BASIS_POINTS_DIVISOR);
const boundedFromAmount = fromAmount ? fromAmount : bigNumberify(0);
if (fromAmount && fromAmount.gt(0) && fromTokenAddress === USDG_ADDRESS && isLong) {
const { amount: nextToAmount, path: multiPath } = getNextToAmount(
chainId,
fromAmount,
fromTokenAddress,
indexTokenAddress,
infoTokens,
undefined,
undefined,
usdgSupply,
totalTokenWeights
);
if (nextToAmount.eq(0)) {
helperToast.error("Insufficient liquidity");
return;
}
if (multiPath) {
path = replaceNativeTokenAddress(multiPath);
}
}
let params = [
path, // _path
indexTokenAddress, // _indexToken
boundedFromAmount, // _amountIn
0, // _minOut
toUsdMax, // _sizeDelta
isLong, // _isLong
priceLimit, // _acceptablePrice
];
let method = "increasePosition";
let value = bigNumberify(0);
if (fromTokenAddress === AddressZero) {
method = "increasePositionETH";
value = boundedFromAmount;
params = [path, indexTokenAddress, 0, toUsdMax, isLong, priceLimit];
}
if (shouldRaiseGasError(getTokenInfo(infoTokens, fromTokenAddress), fromAmount)) {
setIsSubmitting(false);
setIsPendingConfirmation(false);
helperToast.error(
`Leave at least ${formatAmount(DUST_BNB, 18, 3)} ${getConstant(chainId, "nativeTokenSymbol")} for gas`
);
return;
}
console.log("increasePosition 2: ", params);
const contract = new ethers.Contract(routerAddress, Router.abi, library.getSigner());
const indexToken = getTokenInfo(infoTokens, indexTokenAddress);
const tokenSymbol = indexToken.isWrapped ? getConstant(chainId, "nativeTokenSymbol") : indexToken.symbol;
const successMsg = `Requested increase of ${tokenSymbol} ${isLong ? "Long" : "Short"} by ${formatAmount(
toUsdMax,
USD_DECIMALS,
2
)} USD.`;
Api.callContract(chainId, contract, method, params, {
value,
setPendingTxns,
sentMsg: `${isLong ? "Long" : "Short"} submitted.`,
failMsg: `${isLong ? "Long" : "Short"} failed.`,
successMsg,
})
.then(async () => {
setIsConfirming(false);
})
.finally(() => {
setIsConfirming(false);
setIsSubmitting(false);
setIsPendingConfirmation(false);
});
};
const onConfirmationClick = () => {
if (!account) {
connectWalletByLocalStorage()
return;
}
if (needOrderBookApproval) {
approveOrderBook();
// return;
}
setIsPendingConfirmation(true);
if (type === LIMIT) {
createIncreaseOrder();
return;
}
increasePosition();
};
const perpetualMode = [LONG, SHORT, POOL];
const perpetualType = [MARKET, LIMIT]
// LONG or SHORT or POOL
const modeSelect = (input) => {
setMode(input);
onChangeMode(input);
}
// MARKET or LIMIT
const typeSelect = input => {
setType(input);
}
const switchTokens = () => {
if (fromAmount && toAmount) {
if (anchorOnFromAmount) {
setToValue(formatAmountFree(fromAmount, fromToken.decimals, 8));
} else {
setFromValue(formatAmountFree(toAmount, toToken.decimals, 8));
}
setAnchorOnFromAmount(!anchorOnFromAmount);
}
setIsWaitingForApproval(false);
setFromTokenAddress(mode, toTokenAddress)
setToTokenAddress(mode, fromTokenAddress)
};
const getLeverageError = useCallback(() => {
if (!toAmount || toAmount.eq(0)) {
return ["Enter an amount"];
}
let toTokenInfo = getTokenInfo(infoTokens, toTokenAddress);
if (toTokenInfo && toTokenInfo.isStable) {
return [
`${isLong ? "Longing" : "Shorting"} ${toTokenInfo.symbol
} not supported`
];
}
const fromTokenInfo = getTokenInfo(infoTokens, fromTokenAddress);
if (
fromTokenInfo &&
fromTokenInfo.balance &&
fromAmount &&
fromAmount.gt(fromTokenInfo.balance)
) {
return [`Insufficient ${fromTokenInfo.symbol} balance`];
}
if (leverage && leverage.eq(0)) {
return ["Enter an amount"];
}
if (type !== MARKET && (!triggerPriceValue || triggerPriceUsd.eq(0))) {
return ["Enter a price"];
}
if (
!hasExistingPosition &&
fromUsdMin &&
fromUsdMin.lt(expandDecimals(10, USD_DECIMALS))
) {
return ["Min order: 10 USD"];
}
if (leverage && leverage.lt(0.1 * BASIS_POINTS_DIVISOR)) {
return ["Min leverage: 0.1x"];
}
if (leverage && leverage.gt(30.5 * BASIS_POINTS_DIVISOR)) {
return ["Max leverage: 30.5x"];
}
if (type !== MARKET && entryMarkPrice && triggerPriceUsd) {
if (isLong && entryMarkPrice.lt(triggerPriceUsd)) {
return ["Price above Mark Price"];
}
if (mode !== LONG && entryMarkPrice.gt(triggerPriceUsd)) {
return ["Price below Mark Price"];
}
}
if (isLong) {
if (fromTokenAddress !== toTokenAddress) {
const { amount: swapAmount } = getNextToAmount(
chainId,
toAmount,
toTokenAddress,
fromTokenAddress,
infoTokens,
undefined,
undefined,
usdgSupply,
totalTokenWeights
);
// requiredAmount = requiredAmount.add(swapAmount);
let requiredAmount = fromAmount.mul(parseInt(leverageOption*100)).div(100);
if (
toToken &&
toTokenAddress !== USDG_ADDRESS &&
fromTokenInfo.availableAmount &&
requiredAmount.gt(fromTokenInfo.availableAmount)
) {
return ["Insufficient liquidity"];
}
if (
toTokenInfo.poolAmount &&
toTokenInfo.bufferAmount &&
toTokenInfo.bufferAmount.gt(toTokenInfo.poolAmount.sub(swapAmount))
) {
return ["Insufficient liquidity", true, "BUFFER"];
}
if (
fromUsdMin &&
fromTokenInfo.maxUsdgAmount &&
fromTokenInfo.maxUsdgAmount.gt(0) &&
fromTokenInfo.minPrice &&
fromTokenInfo.usdgAmount
) {
const usdgFromAmount = adjustForDecimals(
fromUsdMin,
USD_DECIMALS,
USDG_DECIMALS
);
const nextUsdgAmount = fromTokenInfo.usdgAmount.add(usdgFromAmount);
if (nextUsdgAmount.gt(fromTokenInfo.maxUsdgAmount)) {
return [
`${fromTokenInfo.symbol} pool exceeded, try different token`,
true,
"MAX_USDG"
];
}
}
}
}
if (isShort) {
let stableTokenAmount = bigNumberify(0);
if (
fromTokenAddress !== shortCollateralAddress &&
fromAmount &&
fromAmount.gt(0)
) {
const { amount: nextToAmount } = getNextToAmount(
chainId,
fromAmount,
fromTokenAddress,
shortCollateralAddress,
infoTokens,
undefined,
undefined,
usdgSupply,
totalTokenWeights
);
stableTokenAmount = nextToAmount;
if (stableTokenAmount.gt(shortCollateralToken.availableAmount)) {
return [`Insufficient liquidity, change "Profits In" 1`];
}
if (
shortCollateralToken.bufferAmount &&
shortCollateralToken.poolAmount &&
shortCollateralToken.bufferAmount.gt(
shortCollateralToken.poolAmount.sub(stableTokenAmount)
)
) {
// suggest swapping to collateralToken
return [
`Insufficient liquidity, change "Profits In" 2`,
true,
"BUFFER"
];
}
if (
fromTokenInfo.maxUsdgAmount &&
fromTokenInfo.maxUsdgAmount.gt(0) &&
fromTokenInfo.minPrice &&
fromTokenInfo.usdgAmount
) {
const usdgFromAmount = adjustForDecimals(
fromUsdMin,
USD_DECIMALS,
USDG_DECIMALS
);
const nextUsdgAmount = fromTokenInfo.usdgAmount.add(usdgFromAmount);
if (nextUsdgAmount.gt(fromTokenInfo.maxUsdgAmount)) {
return [
`${fromTokenInfo.symbol} pool exceeded, try different token`,
true,
"MAX_USDG"
];
}
}
}
if (
!shortCollateralToken ||
!fromTokenInfo ||
!toTokenInfo ||
!toTokenInfo.maxPrice ||
!shortCollateralToken.availableAmount
) {
return ["Fetching token info..."];
}
const sizeUsd = toAmount
.mul(toTokenInfo.maxPrice)
.div(expandDecimals(1, toTokenInfo.decimals));
const sizeTokens = sizeUsd
.mul(expandDecimals(1, shortCollateralToken.decimals))
.div(shortCollateralToken.minPrice);
// no more this short limits
// if (toTokenInfo.maxAvailableShort && toTokenInfo.maxAvailableShort.gt(0) && sizeUsd.gt(toTokenInfo.maxAvailableShort)) {
// return [`Max ${toTokenInfo.symbol} short exceeded`]
// }
console.log("DEBUG HERE3:", stableTokenAmount, sizeTokens.toString(), shortCollateralToken)
stableTokenAmount = stableTokenAmount.add(sizeTokens)
if (stableTokenAmount.gt(shortCollateralToken.availableAmount)) {
return [`Insufficient liquidity, change "Profits In" 3`];
}
}
return [false];
}, [
chainId,
fromAmount,
fromTokenAddress,
fromUsdMin,
// hasExistingPosition,
infoTokens,
leverage,
shortCollateralAddress,
shortCollateralToken,
toAmount,
toToken,
toTokenAddress,
totalTokenWeights,
triggerPriceUsd,
triggerPriceValue,
usdgSupply,
entryMarkPrice
]);
const isPrimaryEnabled = () => {
if (!active) { return true }
if (mode !== POOL) {
const [error, modal] = getLeverageError()
if (error && !modal) { return false }
}
if (needOrderBookApproval && isWaitingForPluginApproval) { return false }
if ((needApproval && isWaitingForApproval) || isApproving) { return false }
if (isApproving) { return false }
if (isSubmitting) { return false }
return true;
};
const getPrimaryText = () => {
if (!active) { return "Connect Wallet"; }
if (mode !== POOL) {
const [error, modal] = getLeverageError()
if (error && !modal) { return error }
}
if (needApproval && isWaitingForApproval) {
return "Waiting for Approval";
}
if (isApproving) {
return `Approving ${fromToken.symbol}...`;
}
if (needApproval) {
return `Approve ${fromToken.symbol}`;
}
if (needOrderBookApproval && isWaitingForPluginApproval) {
return "Enabling Orders...";
}
if (isPluginApproving) {
return "Enabling Orders...";
}
if (needOrderBookApproval) {
return "Enable Orders";
}
if (type !== MARKET)
return `Create ${type} Order`;
if (isLong) {
const indexTokenInfo = getTokenInfo(infoTokens, toTokenAddress);
if (indexTokenInfo && indexTokenInfo.minPrice) {
const { amount: nextToAmount } = getNextToAmount(
chainId,
fromAmount,
fromTokenAddress,
indexTokenAddress,
infoTokens,
undefined,
undefined,
usdgSupply,
totalTokenWeights
);
const nextToAmountUsd = nextToAmount
.mul(indexTokenInfo.minPrice)
.div(expandDecimals(1, indexTokenInfo.decimals));
if (
fromTokenAddress === USDG_ADDRESS &&
nextToAmountUsd.lt(fromUsdMin.mul(98).div(100))
) {
return "High USDG Slippage, Long Anyway";
}
}
return `Long ${toToken.symbol}`;
}
return `Short ${toToken.symbol}`;
};
function approveFromToken() {
approveTokens({
setIsApproving,
library,
tokenAddress: fromToken.address,
spender: routerAddress,
chainId,
onApproveSubmitted: () => {
setIsWaitingForApproval(true);
},
infoTokens,
getTokenInfo,
pendingTxns
});
}
const onClickPrimary = () => {
if (!account) {
connectWalletByLocalStorage()
return;
}
// TODO terms and condition pop up, we dont have it now
if (needOrderBookApproval) {
setOrdersToaOpen(true);
// return;
}
if (needApproval) {
approveFromToken();
return;
}
if (mode !== POOL) {
const [, modal, errorCode] = getLeverageError()
if (modal) {
setModalError(errorCode);
return;
}
}
setIsConfirming(true);
};
let hasZeroBorrowFee = false;
let borrowFeeText;
if (isLong && toTokenInfo && toTokenInfo.fundingRate) {
borrowFeeText = formatAmount(toTokenInfo.fundingRate, 4, 4) + "% / 1h";
}
if (isShort && shortCollateralToken && shortCollateralToken.fundingRate) {
borrowFeeText =
formatAmount(shortCollateralToken.fundingRate, 4, 4) + "% / 1h";
}
let fees;
let feesUsd;
let feeBps;
let swapFees;
let positionFee;
if (mode === SWAP) {
if (fromAmount) {
const { feeBasisPoints } = getNextToAmount(
chainId,
fromAmount,
fromTokenAddress,
toTokenAddress,
infoTokens,
undefined,
undefined,
usdgSupply,
totalTokenWeights
);
if (feeBasisPoints !== undefined) {
fees = fromAmount.mul(feeBasisPoints).div(BASIS_POINTS_DIVISOR);
const feeTokenPrice =
fromTokenInfo.address === USDG_ADDRESS
? expandDecimals(1, USD_DECIMALS)
: fromTokenInfo.maxPrice;
feesUsd = fees
.mul(feeTokenPrice)
.div(expandDecimals(1, fromTokenInfo.decimals));
}
feeBps = feeBasisPoints;
}
} else if (toUsdMax) {
positionFee = toUsdMax
.mul(MARGIN_FEE_BASIS_POINTS)
.div(BASIS_POINTS_DIVISOR);
feesUsd = positionFee;
const { feeBasisPoints } = getNextToAmount(
chainId,
fromAmount,
fromTokenAddress,
collateralTokenAddress,
infoTokens,
undefined,
undefined,
usdgSupply,
totalTokenWeights
);
if (feeBasisPoints) {
swapFees = fromUsdMin.mul(feeBasisPoints).div(BASIS_POINTS_DIVISOR);
feesUsd = feesUsd.add(swapFees);
}
feeBps = feeBasisPoints;
}
let payBalance = "$0.00"
let receiveBalance = "$0.00"
if (fromUsdMin) {
payBalance = `$${formatAmount(fromUsdMin, USD_DECIMALS, 2, true, 0)}`
}
if (toUsdMax) {
receiveBalance = `$${formatAmount(toUsdMax, USD_DECIMALS, 2, true)}`
}
// Glp Swap Component
// const tokensForBalanceAndSupplyQuery = [stakedGlpTrackerAddress, usdgAddress]
// const { data: balancesAndSupplies, mutate: updateBalancesAndSupplies } = useSWR([chainId, readerAddress, "getTokenBalancesWithSupplies", account || PLACEHOLDER_ACCOUNT], {
// fetcher: fetcher(library, ReaderV2, [tokensForBalanceAndSupplyQuery]),
// })
// const { data: aums, mutate: updateAums } = useSWR([chainId, glpManagerAddress, "getAums"], {
// fetcher: fetcher(library, GlpManager),
// })
const { data: glpBalance, mutate: updateGlpBalance } = useSWR([chainId, glpAddress, "balanceOf", account || PLACEHOLDER_ACCOUNT], {
fetcher: fetcher(library, Glp),
})
// const { data: glpBalance, mutate: updateGlpBalance } = useSWR([chainId, feeGlpTrackerAddress, "stakedAmounts", account || PLACEHOLDER_ACCOUNT], {
// fetcher: fetcher(library, RewardTracker),
// })
// const { data: reservedAmount, mutate: updateReservedAmount } = useSWR([chainId, glpVesterAddress, "pairAmounts", account || PLACEHOLDER_ACCOUNT], {
// fetcher: fetcher(library, Vester),
// })
// const { gmxPrice, mutate: updateGmxPrice } = useGmxPrice(chainId, { arbitrum: library }, active)
// const rewardTrackersForStakingInfo = [ stakedGlpTrackerAddress, feeGlpTrackerAddress ]
// const { data: stakingInfo, mutate: updateStakingInfo } = useSWR([chainId, rewardReaderAddress, "getStakingInfo", account || PLACEHOLDER_ACCOUNT], {
// fetcher: fetcher(library, RewardReader, [rewardTrackersForStakingInfo]),
// })
const { data: glpSupply, mutate: updateGlpSupply } = useSWR([chainId, glpAddress, "totalSupply"], {
fetcher: fetcher(library, Glp),
})
// const glpSupply = balancesAndSupplies ? balancesAndSupplies[1] : bigNumberify(0)
// const glp_usdgSupply = balancesAndSupplies ? balancesAndSupplies[3] : bigNumberify(0)
// let aum
// if (aums && aums.length > 0) {
// aum = isBuying ? aums[0] : aums[1]
// }
const { data: aumInUsdg, mutate: updateAumInUsdg } = useSWR([chainId, glpManagerAddress, "getAumInUsda", true], {
fetcher: fetcher(library, GlpManager),
})
const glpPrice = (aumInUsdg && aumInUsdg.gt(0) && glpSupply && glpSupply.gt(0) ) ? aumInUsdg.mul(expandDecimals(1, GLP_DECIMALS)).div(glpSupply) : expandDecimals(1, USD_DECIMALS)
// const glpPrice = (aum && aum.gt(0) && glpSupply.gt(0)) ? aum.mul(expandDecimals(1, GLP_DECIMALS)).div(glpSupply) : expandDecimals(1, USD_DECIMALS)
let glpBalanceUsd
if (glpBalance) {
glpBalanceUsd = glpBalance.mul(glpPrice).div(expandDecimals(1, GLP_DECIMALS))
}
const glpSupplyUsd = glpSupply ? glpSupply.mul(glpPrice).div(expandDecimals(1, GLP_DECIMALS)) : bigNumberify(0)
const glp_infoTokens = getInfoTokens(tokens, tokenBalances, whitelistedTokens, vaultTokenInfo, undefined)
return (
<div className={styles.mainContent}>
<AcyPerpetualCard style={{ backgroundColor: 'transparent' }}>
<div className={styles.modeSelector}>
<PerpetualTabs
option={mode}
options={perpetualMode}
onChange={modeSelect}
/>
</div>
{mode !== POOL ?
<>
<div className={styles.typeSelector}>
<PerpetualTabs
option={type}
options={perpetualType}
type="inline"
onChange={typeSelect}
style={{height:'30px'}}
/>
</div>
<BuyInputSection
token={fromToken}
tokenlist={tokens.filter(token => !token.isWrapped)}
topLeftLabel="Pay"
balance={payBalance}
topRightLabel='Balance: '
tokenBalance={formatAmount(fromBalance, fromToken.decimals, 4, true)}
inputValue={fromValue}
onInputValueChange={onFromValueChange}
onSelectToken={selectFromToken}
/>
{/* <div className={styles.arrow} onClick={switchTokens}>
<Icon style={{ fontSize: '16px' }} type="arrow-down" />
</div> */}
<BuyInputSection
token={toToken}
tokenlist={toTokens}
topLeftLabel={getTokenLabel()}
balance={receiveBalance}
// topRightLabel={leverageLabel}
// tokenBalance={leverageValue}
inputValue={toValue}
onInputValueChange={onToValueChange}
onSelectToken={selectToToken}
/>
{type === LIMIT &&
<div className={styles.priceBox}>
<PriceBox
priceValue={triggerPriceValue}
onChange={onTriggerPriceChange}
markOnClick={() => {
setTriggerPriceValue(
formatAmountFree(entryMarkPrice, USD_DECIMALS, 2)
);
}}
mark={formatAmount(entryMarkPrice, USD_DECIMALS, 2, true)}
/>
</div>
}
{/* Leverage Slider */}
{(isLong || isShort) &&
<AcyDescriptions>
<div className={styles.leverageContainer}>
<div className={styles.slippageContainer}>
<div className={styles.leverageLabel}>
<span>Leverage</span>
{isLeverageSliderEnabled &&
<div className={styles.leverageInputContainer}>
<button
className={styles.leverageButton}
onClick={() => {
if (leverageOption > 0.1) {
setLeverageOption((parseFloat(leverageOption) - 0.1).toFixed(1))
}
}}
>
<span> - </span>
</button>
<input
type="number"
min={0.1}
max={30.5}
value={leverageOption}
onChange={e => {
let val = parseFloat(e.target.value.replace(/^(-)*(\d+)\.(\d).*$/, '$1$2.$3')).toFixed(1)
if (val >= 0.1 && val <= 30.5) {
setLeverageOption(val)
}
}}
className={styles.leverageInput}
/>
<button
className={styles.leverageButton}
onClick={() => {
if (leverageOption < 30.5) {
setLeverageOption((parseFloat(leverageOption) + 0.1).toFixed(1))
}
}}
>
<span> + </span>
</button>
</div>
}
</div>
{/* <div className={styles.checkbox}>
<StyledCheckbox
checked={isLeverageSliderEnabled}
onChange={() => {
setIsLeverageSliderEnabled(!isLeverageSliderEnabled)
}}
/>
</div> */}
</div>
{isLeverageSliderEnabled &&
<span className={styles.leverageSlider}>
<StyledSlider
min={0.1}
max={30.5}
step={0.1}
marks={leverageMarks}
value={leverageOption}
onChange={value => setLeverageOption(value)}
defaultValue={leverageOption}
style={{ color: 'red' }}
/>
</span>
}
</div>
</AcyDescriptions>
}
<div className={styles.centerButton}>
<AcyPerpetualButton
// <AcyButton
style={{ marginTop: '25px' }}
onClick={onClickPrimary}
disabled={!isPrimaryEnabled()}
>
{getPrimaryText()}
</AcyPerpetualButton>
{/* </AcyButton> */}
</div>
</> :
<>
<GlpSwapBox
isBuying={isBuying}
setIsBuying={setIsBuying}
swapTokenAddress={swapTokenAddress}
setSwapTokenAddress={setSwapTokenAddress}
isWaitingForApproval={glp_isWaitingForApproval}
setIsWaitingForApproval={glp_setIsWaitingForApproval}
setPendingTxns={setPendingTxns}
/>
</>
}
</AcyPerpetualCard>
{/* Long/Short Detail card */}
{(isLong || isShort) &&
<>
<AcyPerpetualCard style={{ backgroundColor: 'transparent', padding: '10px' }}>
{/* Profits In */}
{isLong && (
<div className={styles.detailCard}>
<div className={styles.label}>Profits In</div>
<div className={styles.value}>{fromToken.symbol}</div>
</div>
)}
{isShort && (
<div className={styles.detailCard}>
<div className={styles.label}>Profits In</div>
<div className={styles.TooltipHandle}>
<span>{shortCollateralToken.symbol}</span>
</div>
</div>
)}
{/* Leverage */}
<div className={styles.detailCard}>
<div className={styles.label}>Leverage</div>
<div className={styles.value}>
{hasExistingPosition &&
toAmount &&
toAmount.gt(0) &&
`${formatAmount(existingPosition.leverage, 4, 2)}x →`
}
{toAmount &&
leverage &&
leverage.gt(0) &&
`${formatAmount(leverage, 4, 2)}x`}
{!toAmount && leverage && leverage.gt(0) && `-`}
{leverage && leverage.eq(0) && `-`}
</div>
</div>
{/* Entry Price */}
<div className={styles.detailCard}>
<div className={styles.label}>Entry Price</div>
<div className={styles.value}>
{hasExistingPosition &&
toAmount &&
toAmount.gt(0) &&
`$${formatAmount(existingPosition.averagePrice, USD_DECIMALS, 2, true)} →`
}
{nextAveragePrice &&
`$${formatAmount(nextAveragePrice, USD_DECIMALS, 2, true)}`}
{!nextAveragePrice && `-`}
</div>
</div>
{/* Liq. Price */}
<div className={styles.detailCard}>
<div className={styles.label}>Liq. Price</div>
<div className={styles.value}>
{hasExistingPosition &&
toAmount &&
toAmount.gt(0) &&
`$${formatAmount(existingLiquidationPrice, USD_DECIMALS, 2, true)} →`
}
{toAmount && displayLiquidationPrice &&
`$${formatAmount(displayLiquidationPrice, USD_DECIMALS, 2, true)}`
}
{!toAmount && displayLiquidationPrice && `-`}
{!displayLiquidationPrice && `-`}
</div>
</div>
{/* Fees */}
<div className={styles.detailCard}>
<div className={styles.label}>Fees</div>
<div className={styles.value}>
{!feesUsd && "-"}
{feesUsd &&
<Tooltip
placement='bottomLeft'
color='#b5b5b6'
mouseEnterDelay={0.5}
title={() => {
return (
<>
{swapFees && (
<div>
{collateralToken.symbol} is required for
collateral.
<br /><br />
Swap {fromToken.symbol} to{" "}
{collateralToken.symbol} Fee: $
{formatAmount(swapFees, USD_DECIMALS, 2, true)}
<br /><br />
</div>
)}
<div>
Position Fee (0.08% of position size): $
{formatAmount(positionFee, USD_DECIMALS, 2, true)}
</div>
</>
)
}}
>
<div className={styles.TooltipHandle}>
${formatAmount(feesUsd, USD_DECIMALS, 2, true)}
</div>
</Tooltip>
}
</div>
</div>
{/* Entry Price */}
<div className={styles.detailCard}>
<div className={styles.label}>Entry Price</div>
<Tooltip
placement='bottomLeft'
color='#b5b5b6'
mouseEnterDelay={0.5}
title={() => {
return (
<>
The position will be opened at{" "}
{formatAmount(entryMarkPrice, USD_DECIMALS, 2, true)} USD
with a max slippage of{" "}
{parseFloat(savedSlippageAmount / 100.0).toFixed(2)}%.
<br /><br />
The slippage amount can be configured under Settings,
found by clicking on your address at the top right of the
page after connecting your wallet.
<br /><br />
<a href="https://gmxio.gitbook.io/gmx/trading#opening-a-position" target="_blank" rel="noopener noreferrer">
More Info
</a>
</>
)
}}
>
<div className={styles.TooltipHandle}>
{`${formatAmount(entryMarkPrice, USD_DECIMALS, 2, true)} USD`}
</div>
</Tooltip>
</div>
{/* Exit Price */}
<div className={styles.detailCard}>
<div className={styles.label}>Exit Price</div>
<Tooltip
placement='bottomLeft'
color='#b5b5b6'
mouseEnterDelay={0.5}
title={() => {
return (
<>
If you have an existing position, the position will be
closed at{" "}
{formatAmount(entryMarkPrice, USD_DECIMALS, 2, true)} USD.
<br /><br />
This exit price will change with the price of the asset.
<br /><br />
<a href="https://gmxio.gitbook.io/gmx/trading#opening-a-position" target="_blank" rel="noopener noreferrer">
More Info
</a>
</>
)
}}
>
<div className={styles.TooltipHandle}>
{`${formatAmount(exitMarkPrice, USD_DECIMALS, 2, true)} USD`}
</div>
</Tooltip>
</div>
{/* Borrow Fee */}
<div className={styles.detailCard}>
<div className={styles.label}>Borrow Fee</div>
<Tooltip
placement='bottomLeft'
color='#b5b5b6'
mouseEnterDelay={0.5}
title={() => {
return (
<>
{hasZeroBorrowFee && (
<div>
{isLong &&
"There are more shorts than longs, borrow fees for longing is currently zero"}
{isShort &&
"There are more longs than shorts, borrow fees for shorting is currently zero"}
</div>
)}
{!hasZeroBorrowFee && (
<div>
The borrow fee is calculated as (assets borrowed) /
(total assets in pool) * 0.01% per hour.
<br /><br />
{isShort &&
`You can change the "Profits In" token above to find lower fees`}
</div>
)}
<br />
<a href="https://gmxio.gitbook.io/gmx/trading#opening-a-position" target="_blank" rel="noopener noreferrer">
More Info
</a>
</>
)
}}
>
<div className={styles.TooltipHandle}>
{borrowFeeText}
</div>
</Tooltip>
</div>
{/* Available Liquidity */}
{isShort && toTokenInfo.maxAvailableShort && toTokenInfo.maxAvailableShort.gt(0) &&
<div className={styles.detailCard}>
<div className={styles.label}>Available Liquidity</div>
<Tooltip
placement='bottomLeft'
color='#b5b5b6'
mouseEnterDelay={0.5}
title={() => {
return (
<>
Max {toTokenInfo.symbol} short capacity: ${formatAmount(toTokenInfo.maxGlobalShortSize, USD_DECIMALS, 2, true)}
<br /><br />
Current {toTokenInfo.symbol} shorts: ${formatAmount(toTokenInfo.globalShortSize, USD_DECIMALS, 2, true)}
<br />
</>
)
}}
>
<div className={styles.TooltipHandle}>
{formatAmount(toTokenInfo.maxAvailableShort, USD_DECIMALS, 2, true)}
</div>
</Tooltip>
</div>
}
</AcyPerpetualCard>
</>
}
{/* Swap detail box */}
{mode === POOL &&
<>
<GlpSwapDetailBox
isBuying={isBuying}
setIsBuying={setIsBuying}
tokens={tokens}
infoTokens={glp_infoTokens}
glpPrice={glpPrice}
glpBalance={glpBalance}
glpBalanceUsd={glpBalanceUsd}
// reservedAmount={reservedAmount}
// reserveAmountUsd={reserveAmountUsd}
// stakingInfo={stakingInfo}
glpSupply={glpSupply}
glpSupplyUsd={glpSupplyUsd}
// gmxPrice={gmxPrice}
/>
</>
}
{isConfirming && (
<ConfirmationBox
fromToken={fromToken}
fromTokenInfo={fromTokenInfo}
toToken={toToken}
toTokenInfo={toTokenInfo}
isLong={isLong}
isMarketOrder={type === MARKET}
type={type}
isHigherSlippageAllowed={isHigherSlippageAllowed}
setIsHigherSlippageAllowed={setIsHigherSlippageAllowed}
isShort={isShort}
toAmount={toAmount}
fromAmount={fromAmount}
onConfirmationClick={onConfirmationClick}
setIsConfirming={setIsConfirming}
shortCollateralAddress={shortCollateralAddress}
hasExistingPosition={hasExistingPosition}
leverage={leverage}
existingPosition={existingPosition}
existingLiquidationPrice={existingLiquidationPrice}
displayLiquidationPrice={displayLiquidationPrice}
shortCollateralToken={shortCollateralToken}
isPendingConfirmation={isPendingConfirmation}
triggerPriceUsd={triggerPriceUsd}
triggerRatio={triggerRatio}
fees={fees}
feesUsd={feesUsd}
isSubmitting={isSubmitting}
fromUsdMin={fromUsdMin}
toUsdMax={toUsdMax}
nextAveragePrice={nextAveragePrice}
collateralTokenAddress={collateralTokenAddress}
feeBps={feeBps}
chainId={chainId}
orders={orders}
/>
)}
</div>
);
}
Example #6
Source File: Farms.js From acy-dex-interface with MIT License | 4 votes |
Farms = (props) => {
// useWeb3React hook will listen to wallet connection.
// if wallet is connected, account, chainId, library, and activate will not be not be undefined.
// const { account, chainId, library, activate, active } = useWeb3React();
const {account, library, chainId, tokenList: supportedTokens} = useConstantLoader();
const { activate } = useWeb3React();
// const [account, setAccount] = useState();
const INITIAL_ROW_NUMBER = 20;
const [farmsContent, setFarmsContent] = useState([]);
const [currentBlock, setCurrentBlock] = useState(0);
const [currentTableRow, setCurrentTableRow] = useState([]);
const [tableRow, setTableRow] = useState([]);
const [selectedTable, setSelectedTable] = useState(0);
const [searchInput, setSearchInput] = useState('');
const [tableTitle, setTableTitle] = useState('All Farms');
const [tableSubtitle, setTableSubtitle] = useState('Stake your LP tokens and earn token rewards');
const [rowNumber, setRowNumber] = useState(INITIAL_ROW_NUMBER);
const [hideDao, setHideDao] = useState(true);
const [tokenFilter, setTokenFilter] = useState(false);
const [daoDataSource, setDaoDataSource] = useState(SampleStakeHistoryData);
const [walletConnected, setWalletConnected] = useState();
const [isMyFarms, setIsMyFarms] = useState(false);
const [harvestAcy, setHarvestAcy] = useState();
const [balanceAcy, setBalanceAcy] = useState();
const [stakeACY, setStakeACY] = useState();
const [isLoadingPool, setIsLoadingPool] = useState(true);
const [isLoadingHarvest, setIsLoadingHarvest] = useState(true);
const [isLoadingBalance, setIsLoadingBalance] = useState(true);
const [isConnected, setIsConnected] = useState(false); // set this after run activate
const [activeEnded, setActiveEnded] = useState(true);
const [notLogginFarmContent, setNotLogginFarmContent] = useState();
// method to activate metamask wallet.
// calling this method for the first time will cause metamask to pop up,
// and require user to approve this connection.
const connectWalletByLocalStorage = useConnectWallet();
const connectWallet = async () => {
connectWalletByLocalStorage();
};
//function to get logo URI
function getLogoURIWithSymbol(symbol) {
for (let j = 0; j < supportedTokens.length; j++) {
if (symbol === supportedTokens[j].symbol) {
return supportedTokens[j].logoURI;
}
}
return null;
}
function getTokenDetail(symbol) {
for (let j = 0; j < supportedTokens.length; j++) {
if (symbol === supportedTokens[j].symbol) {
return supportedTokens[j];
}
}
return {
name: symbol,
symbol: symbol,
address: '0x0000000000000000000000000000000000000000',
addressOnEth: '0x0000000000000000000000000000000000000000',
decimals: 18,
logoURI: 'https://storageapi2.fleek.co/chwizdo-team-bucket/token image/ethereum-eth-logo.svg'
};
}
const onLogInChanged = (account) => {
if (!account)
setWalletConnected(false);
else
setWalletConnected(true);
};
const getDateYDM = (date) => {
return date.getFullYear(date) + "-" + ("0"+(date.getMonth(date)+1)).slice(-2) + "-" + ("0" + date.getDate(date)).slice(-2)
}
const getDHM = (sec) => {
if(sec<0) return '00d:00h:00m';
var diff = sec;
var days = 0, hrs = 0, min = 0, leftSec = 0;
diff = Math.floor(diff);
days = Math.floor(diff/(24*60*60));
leftSec = diff - days * 24*60*60;
hrs = Math.floor(leftSec/(60*60));
leftSec = leftSec - hrs * 60*60;
min = Math.floor(leftSec/(60));
return days.toString() + 'd:' + hrs.toString() + 'h:' + min.toString() +'m';
}
const getPools = async (library, account, chainId) => {
setIsLoadingPool(true);
const block = await library.getBlockNumber();
var pools;
try {
pools = await newGetAllPools(library, account, chainId);
} catch(e) {
console.log("getPools error: ",account,chainId,library,pools);
return;
}
// const pools = await newGetAllPools(library, account, chainId);
const newFarmsContents = [];
let ismyfarm = false;
pools&&pools.forEach((pool,idx) => {
const newFarmsContent = {
index: idx,
poolId: pool.poolId,
lpTokens: pool.lpTokenAddress,
token1: pool.token0Symbol,
token1Logo: getLogoURIWithSymbol(pool.token0Symbol),
token2: pool.token1Symbol,
token2Logo: getLogoURIWithSymbol(pool.token1Symbol),
pendingReward: pool.rewardTokensSymbols.map((token, index) => ({
token,
amount: pool.rewardTokensAmount[index] == 0?0 : pool.rewardTokensAmount[index],
})),
totalApr: pool.apr.toFixed(2),
tvl: pool.tvl,
hasUserPosition: pool.hasUserPosition,
hidden: true,
stakeData: pool.stakeData,
poolLpScore: pool.lpScore,
poolLpBalance: pool.lpBalance,
endsIn: getDHM((pool.endBlock - block) * BLOCK_TIME()),
status: pool.endBlock - block > 0,
ratio: pool.ratio,
endAfter: (pool.endBlock - block) * BLOCK_TIME(),
token1Ratio: pool.token1Ratio,
token2Ratio: pool.token2Ratio,
poolRewardPerYear: pool.poolRewardPerYear, // usd price
tokensRewardPerBlock: pool.tokensRewardPerBlock
};
if(newFarmsContent.poolId == 0) {
// const total = rewards[j].reduce((total, currentAmount) => total.add(parseInt(currentAmount)));
// if(newFarmsContent.stakeData){
// const myStakeAcy = newFarmsContent.stakeData.reduce((total, currentAmount) => total + parseFloat(currentAmount.lpAmount), 0);
// setStakeACY({
// myAcy: myStakeAcy,
// totalAcy: newFarmsContent.poolLpBalance
// });
// } else {
// setStakeACY({
// myAcy: 0,
// totalAcy: newFarmsContent.poolLpBalance
// });
// }
}
//if user has farm, direct to myfarm
if(newFarmsContent.hasUserPosition && account) {
setIsMyFarms(true);
ismyfarm = true;
}
newFarmsContents.push(newFarmsContent);
});
if(account != "0x0000000000000000000000000000000000000000") {
console.log("TEST newFarmsContents 0:",account,farmsContent,walletConnected)
setFarmsContent(newFarmsContents);
console.log("TEST newFarmsContents 1:",newFarmsContents);
} else {
console.log("TEST newFarmsContents 2:",account,farmsContent,walletConnected)
setNotLogginFarmContent(newFarmsContents);
console.log("TEST newFarmsContents 2:",newFarmsContents);
}
setIsLoadingPool(false);
console.log("end getPools");
};
useEffect(
() => {
console.log("HERE TEST:",account);
if(!account){
connectWallet();
}
setIsMyFarms(false);
if (account) {
setWalletConnected(true);
const provider = new JsonRpcProvider(RPC_URL(), chainId);
console.log("start getPools",library,chainId);
getPools(provider, account, chainId);
} else {
const provider = new JsonRpcProvider(RPC_URL(), chainId);
const account = "0x0000000000000000000000000000000000000000";
setWalletConnected(false);
getPools(provider, account, chainId);
}
},
[account, chainId]
);
const onAllToggleButtonClick = () => {
setSelectedTable(0);
setTableTitle('All Farms');
setTableSubtitle('Stake your LP tokens and earn token rewards');
setRowNumber(INITIAL_ROW_NUMBER);
setHideDao(true);
setIsMyFarms(false);
};
const onAcyToggleButtonClick = () => {
setSelectedTable(1);
setTableTitle('ACY Farms');
setTableSubtitle('Stake your LP tokens and earn ACY token rewards');
setRowNumber(INITIAL_ROW_NUMBER);
setHideDao(true);
};
const onDaoToggleButtonClick = () => {
setSelectedTable(3);
setHideDao(false);
setTableTitle('DAO Farms');
setTableSubtitle('Stake your ACY tokens and earn ACY token rewards');
};
const onPremierToggleButtonClick = () => {
setSelectedTable(2);
setTableTitle('Premier Farms');
setTableSubtitle('Stake your LP tokens and earn project/mainstream token rewards');
setRowNumber(INITIAL_ROW_NUMBER);
setHideDao(true);
};
const onMyFarmsButtonClick = () => {
setSelectedTable(4);
};
useEffect(
() => {
if (selectedTable === 4) {
const currentTableData = SampleStakeHistoryData.filter(tableData => {
const [token1, token2] = tableData.tokens.split('-');
if (
token1.toLowerCase().includes(searchInput.toLowerCase()) ||
token2.toLowerCase().includes(searchInput.toLowerCase())
)
return true;
});
setDaoDataSource(currentTableData);
} else {
const currentTableRowCopy = currentTableRow.filter(
tableData =>{
if( tableData.token1.toLowerCase().includes(searchInput.toLowerCase()) ||
tableData.token2.toLowerCase().includes(searchInput.toLowerCase())
) {
return true;
}
}
);
if (isMyFarms){
setTableTitle('My Farms');
// setTableRow(currentTableRowCopy.filter(tableData => tableData.hasUserPosition));
// setTableRow(currentTableRowCopy.filter(tableData => tableData.hasUserPosition));
console.log('My Farms');
}
else if (selectedTable === 0){
setTableTitle('All Farms');
console.log('All Farms');
}
else if (selectedTable === 1){
setTableTitle('Standard Farms');
console.log('Standard Farms');
}
else if (selectedTable === 2){
setTableTitle('Premier Farms');
console.log('Premier Farms');
}
else{
setTableTitle('DAO Farms');
console.log('DAO Farms');
}
}
},
[searchInput, selectedTable, isMyFarms]
);
return (
<PageHeaderWrapper>
{ isLoadingPool? (
<div>
<PageLoading/>
{/* Farm is not available not! */}
</div>
) : (
<div className={styles.farmsContainer}>
<div className={styles.tableControlButtonContainer}>
<ToggleButtonGroup
selectedTable={selectedTable}
onAllToggleButtonClick={onAllToggleButtonClick}
onAcyToggleButtonClick={onAcyToggleButtonClick}
onPremierToggleButtonClick={onPremierToggleButtonClick}
onDaoToggleButtonClick={onDaoToggleButtonClick}
onMyFarmsToggleButtonClick={onMyFarmsButtonClick}
isMyFarms={isMyFarms}
/>
<TableControl
searchInput={searchInput}
setSearchInput={setSearchInput}
isMyFarms={isMyFarms}
setIsMyFarms={setIsMyFarms}
walletConnected={walletConnected}
activeEnded={activeEnded}
setActiveEnded={setActiveEnded}
/>
</div>
{selectedTable !== 4 && (
<FarmsTable
tableRow={walletConnected?farmsContent:notLogginFarmContent}
tableTitle={tableTitle}
tableSubtitle={tableSubtitle}
rowNumber={rowNumber}
setRowNumber={setRowNumber}
hideDao={hideDao}
selectedTable={selectedTable}
tokenFilter={tokenFilter}
setTokenFilter={setTokenFilter}
walletConnected={walletConnected}
connectWallet={connectWallet}
account={account}
library={library}
chainId={chainId}
isMyFarms={isMyFarms}
harvestAcy={harvestAcy}
balanceAcy={balanceAcy}
searchInput={searchInput}
selectedTable={selectedTable}
isLoading={isLoadingPool || isLoadingBalance || isLoadingHarvest}
activeEnded={activeEnded}
setWalletConnected={setWalletConnected}
// refreshPool={refreshPool}
/>
)}
{selectedTable === 4 && <DaoTable dataSource={daoDataSource} />}
</div>
)}
</PageHeaderWrapper>
);
}
Example #7
Source File: FarmsTableRow.js From acy-dex-interface with MIT License | 4 votes |
FarmsTableRow = props => {
const {
index,
lpTokens,
rowClickHandler,
walletConnected,
connectWallet,
hideArrow = false,
chainId,
account,
library,
isMyFarms,
dispatch,
content,
poolId,
stakedTokenAddr,
token1,
token1Logo,
token2,
token2Logo,
totalApr,
tvl,
pendingReward,
stakeData,
hasUserPosition,
searchInput,
selectedTable,
tokenFilter,
dao,
isLoading,
activeEnded,
setWalletConnected
} = props;
const [poolInfo, setPoolInfo] = useState(content);
const [hidden, setHidden] = useState(true);
const [balance, setBalance] = useState(12345);
const [isHarvestDisabled, setIsHarvestDisabled] = useState(false);
const [remainingDays, setRemainingDays] = useState(120)
const [date, setDate] = useState("10/12/2021")
const [isModalVisible, setIsModalVisible] = useState(false);
const hideModal = () => setIsModalVisible(false);
const showModal = () => setIsModalVisible(true);
const [withdrawModal,setWithdrawModal] = useState(false);
const hideWithdrawModal = () => setWithdrawModal(false);
const showWithdrawModal = () => setWithdrawModal(true);
const [selectedRowData, setSelectedRowData] = useState(null);
const [harvestModal,setHarvestModal] = useState(false);
const [harvestButtonText, setHarvestButtonText] = useState('Harvest');
const [harvestButtonStatus,setHarvestButtonStatus] = useState(true);
const hideHarvestModal = () => setHarvestModal(false);
const showHarvestModal = () => setHarvestModal(true);
const [showAddLiquidity,setShowAddLiquidity] = useState(false);
const [errorMessages,setErrorMessages] = useState('');
const [loggedIn, setLoggedIn] = useState(false);
const [withdrawButtonText,setWithdrawButtonText] = useState('Withdraw');
const [withdrawButtonStatus,setWithdrawButtonStatus] = useState(true);
const [percent,setPercent] = useState(50);
const [withdrawAmount, setWithdrawAmount] = useState(0);
const ACY_LOGO = "https://acy.finance/static/media/logo.78c0179c.svg";
//function to get logo URI
function getLogoURIWithSymbol(symbol) {
const supportedTokens = TOKENLIST();
for (let j = 0; j < supportedTokens.length; j++) {
if (symbol === supportedTokens[j].symbol) {
return supportedTokens[j].logoURI;
}
}
return null;
}
useEffect(
() => {
setPoolInfo(content);
},
[isLoading]
);
useEffect(
() => {
if (!poolInfo.lpTokens || !chainId || !account || !library) return;
async function getFarmTokenUserBalance() {
const bal = await getUserTokenBalanceWithAddress(
poolInfo.lpTokens,
chainId,
account,
library
);
setBalance(bal);
}
getFarmTokenUserBalance();
},
[poolInfo,isModalVisible]
);
useEffect(
() => {
setErrorMessages('');
setWithdrawButtonText('Withdraw');
setHarvestButtonStatus(true);
},[withdrawModal]
);
useEffect(
() => {
setErrorMessages('');
setHarvestButtonText('Harvest');
setHarvestButtonStatus(true);
},[harvestModal]
);
let history = useHistory();
const getDHM = (sec) => {
if(sec<0) return '00d:00h:00m';
var diff = sec;
var days = 0, hrs = 0, min = 0, leftSec = 0;
diff = Math.floor(diff);
days = Math.floor(diff/(24*60*60));
leftSec = diff - days * 24*60*60;
hrs = Math.floor(leftSec/(60*60));
leftSec = leftSec - hrs * 60*60;
min = Math.floor(leftSec/(60));
return days.toString() + 'd:' + hrs.toString() + 'h:' + min.toString() +'m';
}
const refreshPoolInfo = async () => {
const provider = new JsonRpcProvider(RPC_URL(), CHAINID());
const pool = await newGetPool(poolInfo.poolId, provider, account, chainId);
const block = await provider.getBlockNumber();
const newFarmsContent = {
index: pool.poolId,
poolId: pool.poolId,
lpTokens: pool.lpTokenAddress,
token1: pool.token0Symbol,
token1Logo: getLogoURIWithSymbol(pool.token0Symbol),
token2: pool.token1Symbol,
token2Logo: getLogoURIWithSymbol(pool.token1Symbol),
pendingReward: pool.rewardTokensSymbols.map((token, index) => ({
token,
amount: pool.rewardTokensAmount[index] == 0?0 : pool.rewardTokensAmount[index],
})),
totalApr: pool.apr.toFixed(2),
tvl: pool.tvl,
hasUserPosition: pool.hasUserPosition,
hidden: true,
stakeData: pool.stakeData,
poolLpScore: pool.lpScore,
poolLpBalance: pool.lpBalance,
endsIn: getDHM((pool.endBlock - block) * BLOCK_TIME()),
status: pool.endBlock - block > 0,
ratio: pool.ratio,
endAfter: (pool.endBlock - block) * BLOCK_TIME(),
token1Ratio: pool.token1Ratio,
token2Ratio: pool.token2Ratio,
poolRewardPerYear: pool.poolRewardPerYear,
tokensRewardPerBlock: pool.tokensRewardPerBlock
};
setPoolInfo(newFarmsContent);
};
const redirectLiquidity = () => {
history.push({
pathname: '/liquidity',
// search: '?update=true', // query string
state: { // location state
token1 : token1,
token2 : token2,
},
});
};
const withdrawClicked = () => {
if(false) {
setErrorMessages("- You can't withdraw now");
} else {
setWithdrawButtonStatus(false);
setWithdrawButtonText(<>Processing <Icon type="loading" /></>);
withdraw(poolId, selectedRowData.positionId, (selectedRowData.lpAmount * percent / 100).toString(), setWithdrawButtonText, setWithdrawButtonStatus, withdrawCallback, library, account);
}
};
const formatString = (value) => {
let formattedStr;
if (value >= 1000000000) {
formattedStr = `$ ${(value / 1000000000).toFixed(2)}b`;
}else if (value >= 1000000) {
formattedStr = `$ ${(value / 1000000).toFixed(2)}m`;
} else if (value >= 1000) {
formattedStr = `$ ${(value / 1000).toFixed(2)}k`;
} else {
formattedStr = `$ ${(value).toFixed(2)}`;
}
return formattedStr;
}
const harvestCallback = status => {
// const {
// transaction: { transactions },
// } = props;
// // 检查是否已经包含此交易
// const transLength = transactions.filter(item => item.hash == status.hash).length;
// if (transLength == 0) {
// dispatch({
// type: 'transaction/addTransaction',
// payload: {
// transactions: [...transactions, status.hash],
// },
// });
// }
const sti = async (hash) => {
library.getTransactionReceipt(hash).then(async receipt => {
// receipt is not null when transaction is done
if (!receipt)
setTimeout(sti(hash), 500);
else {
// const newData = transactions.filter(item => item.hash != hash);
// props.onGetReceipt(receipt.transactionHash, library, account);
// dispatch({
// type: 'transaction/addTransaction',
// payload: {
// transactions: newData
// },
// });
// await axios.get(
// // fetch valid pool list from remote
// `${API_URL}/farm/updatePool?poolId=${poolInfo.poolId}`
// //change to to production
// //`http://api.acy.finance/api/updatePool?poolId=${poolId}`
// ).then( async (res) => {
// }).catch(e => console.log("error: ", e));
// set button to done and disabled on default
await refreshPoolInfo();
setHarvestButtonText("Done");
hideHarvestModal();
}
});
}
sti(status.hash);
}
const withdrawCallback = status => {
// const {
// transaction: { transactions },
// } = props;
// // 检查是否已经包含此交易
// const transLength = transactions.filter(item => item.hash == status.hash).length;
// if (transLength == 0) {
// dispatch({
// type: 'transaction/addTransaction',
// payload: {
// transactions: [...transactions, status.hash],
// },
// });
// }
const sti = async (hash) => {
library.getTransactionReceipt(hash).then(async receipt => {
// console.log(`receiptreceipt for ${hash}: `, receipt);
// receipt is not null when transaction is done
if (!receipt)
setTimeout(sti(hash), 500);
else {
// const newData = transactions.filter(item => item.hash != hash);
// props.onGetReceipt(receipt.transactionHash, library, account);
// dispatch({
// type: 'transaction/addTransaction',
// payload: {
// transactions: newData
// },
// });
// await refreshPoolInfo();
// await axios.get(
// // fetch valid pool list from remote
// `${API_URL}/farm/updatePool?poolId=${poolInfo.poolId}`
// //change to to production
// //`http://api.acy.finance/api/updatePool?poolId=${poolId}`
// ).then(async (res) => {
// await refreshPoolInfo();
// setWithdrawButtonText("Done");
// hideWithdrawModal();
// }).catch(e => console.log("error: ", e));
// set button to done and disabled on default
await refreshPoolInfo();
setWithdrawButtonText("Done");
hideWithdrawModal();
}
});
}
sti(status.hash);
};
const searchFilter = () => {
if(token1.toLowerCase().includes(searchInput.toLowerCase()) || token2.toLowerCase().includes(searchInput.toLowerCase())) {
return true;
} else {
return false;
}
};
const tableFilter = () => {
if(dao) {
return true;
}
if(selectedTable === 0) {
return true;
} else if(selectedTable === 1) {
return (poolInfo.pendingReward.length === 1 && poolInfo.pendingReward[0].token) === "ACY" && !(poolInfo.token1 && !poolInfo.token2);
} else if(selectedTable === 2) {
const table4 = poolInfo.pendingReward.length !== 1 ||
(poolInfo.pendingReward.length === 1 && poolInfo.pendingReward[0].token) !== "ACY"
if(tokenFilter) {
let isBtcEth = false;
poolInfo.pendingReward.forEach(({ token }) => {
if (token === 'BTC' || token === 'ETH' || token === 'USDC' || token === 'USDT') {
isBtcEth = true;
}
});
return isBtcEth && table4;
}
return table4;
}
}
const getFilter = () =>{
return !tableFilter() || !searchFilter() || !daoFilter() || activeEndedFilter();
}
const daoFilter = () => {
return !dao || (poolInfo.token1 && !poolInfo.token2);
}
const activeEndedFilter = () => {
return poolInfo.status != activeEnded;
}
return ( poolInfo && (!isMyFarms || poolInfo.hasUserPosition) && (
<div className={styles.tableBodyRowContainer} hidden={getFilter()}>
{/* Table Content */}
<div className={styles.tableBodyRowContentContainer}
onClick={()=> {
// if(poolInfo.status)
setHidden(prevState => !prevState)
}
}
>
{/* Token Title Row */}
<div className={styles.tableBodyTitleColContainer}>
{poolInfo.token1Logo && (
<div className={styles.token1LogoContainer}>
<img src={poolInfo.token1Logo} alt={poolInfo.token1} />
</div>
)}
{/* conditionally hide and show token 2 logo. */}
{/* if token 2 is undefined or null, hide token 2 logo. */}
{poolInfo.token2Logo && (
<div className={styles.token2LogoContainer}>
<img src={poolInfo.token2Logo} alt={poolInfo.token2} />
</div>
)}
{/* conditionally hide and show token 2 symbol */}
{/* only display token 1 symbol if token 2 is undefined or null. */}
<div className={styles.tokenTitleContainer}>
{poolInfo.token1 && poolInfo.token2 && `${poolInfo.token1}-${poolInfo.token2}`}
{poolInfo.token1 && !poolInfo.token2 && `${poolInfo.token1}`}
{poolInfo.token2 && !poolInfo.token1 && `${poolInfo.token2}`}
{!isMobile ? poolInfo.token1 && poolInfo.token2 && <span style={{ opacity: '0.5' }}> LP</span> : ''}
</div>
</div>
{/* Pending Reward Column */}
<div className={styles.tableBodyRewardColContainer}>
<div className={styles.pendingRewardTitleContainer}>
{(isMyFarms && !isMobile ) ? 'Accumulated Reward' : ''}
{(!isMyFarms && !isMobile ) ? 'Accumulated Reward' : ''}
{(isMobile) ? 'Reward' : ''}
{isMobile}
</div>
{poolInfo.pendingReward && poolInfo.pendingReward.map((reward,idx) => (
<div className={styles.pendingReward1ContentContainer}>
{`${reward.amount.toFixed(2)} ${reward.token}`}
</div>
))}
</div>
{/* Total APR Column */}
<div className={styles.tableBodyAprColContainer}>
<div className={styles.totalAprTitleContainer}>APR</div>
<div className={styles.totalAprContentContainer}>{totalApr}%</div>
</div>
{/* TVL Column */}
{!isMobile && (
<div className={styles.tableBodyTvlColContainer}>
<div className={styles.tvlTitleContainer}>TVL</div>
<div className={styles.tvlContentContainer}>{formatString(poolInfo.tvl)}</div>
</div>
)}
{!isMobile && (
<div className={styles.tableBodyTvlColContainer}>
<div className={styles.tvlTitleContainer}>End</div>
<div className={styles.tvlContentContainer}>{poolInfo.endsIn}</div>
</div>
)}
{/* Arrow Icon Column */}
{!hideArrow && !dao && (
<div className={styles.tableBodyArrowColContainer}>
<svg
xmlns="http://www.w3.org/2000/svg"
className={styles.arrowIcon}
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</div>
)}
</div>
{/* Table Drawer */}
{!isMyFarms && (
<div className={styles.tableBodyDrawerContainer} hidden={hidden && !dao}>
{/* Staking Propotion */}
{!isMyFarms && (
<div className={styles.index0tableBodyDrawerFarmContainer}>
<div className={styles.tableBodyDrawerStakingPropotionTitle}>
{/* *20% */}
</div>
{/* <div className={styles.tableBodyDrawerStakingPropotionEquation}> {token1}-{token2} LP </div> */}
</div>
)}
{/* Add Liquidity */}
{!isMyFarms && poolInfo.token1 && !poolInfo.token2 ?(
<div className={styles.tableBodyDrawerAddLiquidityContainer}>
<div className={styles.tableBodyDrawerAddLiquidityTitle}>Buy ACY</div>
<button
type="button"
className={styles.tableBodyDrawerAddLiquidityButton}
onClick={()=> setShowAddLiquidity(true)}
>
Buy
</button>
</div>
) : (
<div className={styles.tableBodyDrawerAddLiquidityContainer}>
<div className={styles.tableBodyDrawerAddLiquidityTitle}>Add Liquidity</div>
<button
type="button"
className={styles.tableBodyDrawerAddLiquidityButton}
onClick={()=> setShowAddLiquidity(true)}
>
Add
</button>
</div>
)
}
{/* Farm Column */}
<div className={styles.tableBodyDrawerFarmContainer}>
<div className={styles.tableBodyDrawerWalletTitle}>Start Farming</div>
<div>
{walletConnected ? (
<button
type="button"
className={styles.tableBodyDrawerWalletButton}
onClick={showModal}
>
Stake LP
</button>
) : (
<button
type="button"
className={styles.tableBodyDrawerWalletButton}
onClick={connectWallet}
>
Connect Wallet
</button>
)}
</div>
</div>
</div>
)}
{ poolInfo.stakeData && poolInfo.stakeData.map((data,id) => {
return (
<div hidden={hidden||!isMyFarms}>
{/* Farm Column */}
<StakeRow
data={data}
library={library}
account={account}
poolId={poolId}
token1={poolInfo.token1}
token1Logo={poolInfo.token1Logo}
token2={poolInfo.token2}
token2Logo={poolInfo.token2Logo}
refreshPoolInfo={refreshPoolInfo}
ratio={poolInfo.ratio}
token1Ratio={poolInfo.token1Ratio}
token2Ratio={poolInfo.token2Ratio}
>
{ (id == Math.ceil(poolInfo.stakeData.length/2) - 1 && !isMobile) ||
(id == 0 && isMobile) ? (
<div className={styles.tableBodyDrawerFarmContainer}>
<div>
<div className={styles.tableBodyDrawerWalletTitle}>Start Farming</div>
<div>
{walletConnected ? (
<button
type="button"
className={styles.tableBodyDrawerWalletButton}
onClick={showModal}
>
Stake LP
</button>
) : (
<button
type="button"
className={styles.tableBodyDrawerWalletButton}
onClick={connectWallet}
>
Connect Wallet
</button>
)}
</div>
</div>
</div>
) : (
<div className={styles.index0tableBodyDrawerFarmContainer}>
{/* lp Amount {stakeData[id].lpAmount} */}
</div>
)}
</StakeRow>
</div>
);
})}
<AcyModal
visible={showAddLiquidity}
onCancel={()=> setShowAddLiquidity(false)}
width={400}
bodyStyle={{
padding: '0px',
margin: '0px',
background: '#FFFFFF',
borderRadius: '1.5rem',
}}
>
<div>{ poolInfo.token1 && !poolInfo.token2 ? (
<AcyCard style={{ backgroundColor: '#0e0304', padding: '10px' }}>
<div className={styles.trade}>
<SwapComponent
onSelectToken0={token => {
// setActiveToken0(token);
}}
onSelectToken1={token => {
// setActiveToken1(token);
}}
onGetReceipt={null}
token={{
token0: TOKENLIST().find(token => token.symbol == "USDT"),
token1: TOKENLIST().find(token => token.symbol == poolInfo.token1)
}}
isLockedToken1={true}
/>
</div>
</AcyCard>
) : (
<AddLiquidityComponent
onLoggedIn={()=>setLoggedIn(true)}
isFarm={true}
token={{
token1: poolInfo.token1,
token2: poolInfo.token2
}}
onLogInChanged={setWalletConnected}
/>
)}
</div>
</AcyModal>
<StakeModal
onCancel={hideModal}
isModalVisible={isModalVisible}
token1={poolInfo.token1}
token2={poolInfo.token2}
balance={balance}
poolId={poolInfo.poolId}
stakedTokenAddr={poolInfo.lpTokens}
refreshPoolInfo={refreshPoolInfo}
account={account}
library={library}
chainId={chainId}
poolLpScore={poolInfo.poolLpScore}
endAfter={poolInfo.endAfter}
ratio={poolInfo.ratio}
token1Logo={poolInfo.token1Logo}
token2Logo={poolInfo.token2Logo}
token1Ratio={poolInfo.token1Ratio}
token2Ratio={poolInfo.token2Ratio}
poolRewardPerYear={poolInfo.poolRewardPerYear}
tokensRewardPerBlock={poolInfo.tokensRewardPerBlock}
/>
</div>
)
);
}
Example #8
Source File: LaunchpadProject.js From acy-dex-interface with MIT License | 4 votes |
LaunchpadProject = () => {
// STATES
const { account, chainId, library, activate, active } = useWeb3React();
const { projectId } = useParams();
const [receivedData, setReceivedData] = useState({});
const [mainCoinLogoURI, setMainCoinLogoURI] = useState(null);
const [poolID, setPoolID] = useState(null);
const [poolBaseData, setPoolBaseData] = useState(null);
const [poolDistributionDate, setDistributionDate] = useState([]);
const [poolDistributionStage, setpoolDistributionStage] = useState([]);
const [poolStatus, setPoolStatus] = useState(0);
const [poolTokenDecimals, setPoolTokenDecimals] = useState(0);
const [poolMainCoinDecimals, setPoolMainCoinDecimals] = useState(0); // Gary: decimal initialize to 0
const [poolMainCoinAddress, setPoolMainCoinAddress] = useState(""); // e.g., USDT
const [poolTokenAddress, setPoolTokenAddress] = useState("");
const [poolMainCoinLogoURL, setPoolMainCoinLogoURL] = useState(null);
const [poolMainCoinName, setPoolMainCoinName] = useState(null);
const [compareAlloDate, setCompareAlloDate] = useState(false);
const [comparesaleDate, setComparesaleDate] = useState(false);
const [comparevestDate, setComparevestDate] = useState(false);
// const [investorNum,setinvestorNum] = useState(0);
// const [isInvesting, setIsInvesting] = useState(false);
// CONSTANTS
// FUNCTIONS
const convertUnixTime = unixTime => {
const data = new Date((Number(unixTime)) * 1000)
const res = data.toLocaleString()
return res
}
const connectWalletByLocalStorage = useConnectWallet();
useEffect(() => {
if (!account) {
connectWalletByLocalStorage();
}
}, [account]);
// contract function
const getPoolData = async (lib, acc) => {
const poolContract = getContract(LAUNCHPAD_ADDRESS(), POOLABI, lib, acc);
const pool = []
const distributionRes = []
const distributionStage = []
// 合约函数调用
const baseData = await poolContract.GetPoolBaseData(poolID)
const distributionData = await poolContract.GetPoolDistributionData(poolID)
const status = await poolContract.GetPoolStatus(poolID)
console.log('Base Data', baseData);
console.log('Pool Status', status);
console.log('Distribution Data', distributionData);
// getpoolbasedata 数据解析
const token2Address = baseData[1]
const tokenList = TOKEN_LIST()
const token2Info = tokenList.find(item => item.address == token2Address)
const token1contract = getContract(baseData[0], ERC20ABI, lib, acc)
const token2contract = getContract(token2Address, ERC20ABI, lib, acc)
const token1decimal = await token1contract.decimals()
const token2decimal = await token2contract.decimals()
// 不解析时间戳
const res1 = BigNumber.from(baseData[2]).toBigInt().toString().slice(0, -(token1decimal)) // 获取销售的token的总数
const res2 = BigNumber.from(baseData[3]).toBigInt().toString().slice(0, -(token1decimal)) // 已销售的token的数量
const res3 = BigNumber.from(baseData[4]).toBigInt()
const res4 = BigNumber.from(baseData[5]).toBigInt()
console.log('End time', res4);
// 获取当前阶段
const d = Math.round(new Date().getTime() / 1000)
if (d > res3) setComparesaleDate(true)
if (d > res4) setComparevestDate(true)
const saleStartDate = convertUnixTime(res3)
const saleEndDate = convertUnixTime(res4)
// 存放数据
pool.push(res1, res2, saleStartDate, saleEndDate)
// getpooldistributiondata 数据解析以及存放
distributionData[1].map(uTime => distributionRes.push(convertUnixTime(uTime)))
distributionData[2].map(vestingRate => distributionStage.push(BigNumber.from(vestingRate).toBigInt().toString()))
// 判断当前是否是vesting阶段
const curPoolStatus = Number(BigNumber.from(status).toBigInt())
// set数据
setPoolBaseData(pool)
setPoolStatus(curPoolStatus)
setPoolStatus(Number(BigNumber.from(status).toBigInt()))
setPoolMainCoinAddress(token2Address)
setPoolTokenAddress(baseData[0])
setPoolTokenDecimals(token1decimal)
setPoolMainCoinDecimals(token2decimal)
}
const updatePoolData = async () => {
// project must have poolID
if (poolID === null) return;
const now_moment_utc = moment.utc();
const end_moment_utc = moment.utc(receivedData.saleEnd);
const start_moment_utc = moment.utc(receivedData.saleStart);
if (now_moment_utc > end_moment_utc || now_moment_utc < start_moment_utc) return;
try {
if (account && library) {
await getPoolData(library, account);
} else {
const provider = new JsonRpcProvider(LAUNCH_RPC_URL(), CHAINID()); // different RPC for mainnet
const accnt = "0x0000000000000000000000000000000000000000";
await getPoolData(provider, accnt);
};
} catch (error) {
console.log('Invalid Pool ID.')
}
}
// HOOKS
// Retrieve project data from db
useEffect(() => {
getProjectInfo(API_URL(), projectId)
.then(res => {
if (res) {
// extract data from string
console.log("fecthing project info ------------111", res.contextData)
const contextData = JSON.parse(res.contextData);
res['tokenLabels'] = contextData['tokenLabels'];
res['projectDescription'] = contextData['projectDescription'];
res['alreadySale'] = contextData['alreadySale'];
res['salePercentage'] = contextData['salePercentage'];
res['posterUrl'] = contextData['posterUrl'];
res['bulletin'] = contextData['bulletin'];
res['tokenLogoUrl'] = res.basicInfo.projectTokenUrl;
res['minInvest'] = res.allocationInfo.parameters.minInvest;
res['regStart'] = res.scheduleInfo.regStart;
res['regEnd'] = res.scheduleInfo.regEnd;
res['saleStart'] = res.scheduleInfo.saleStart;
res['saleEnd'] = res.scheduleInfo.saleEnd;
if (res.scheduleInfo.distributionData) {
const distributionData = res.scheduleInfo.distributionData;
const distributionRes = [];
const distributionStage = [];
distributionData[2].map(vestingRate => distributionStage.push(BigNumber.from(vestingRate).toBigInt().toString()))
setDistributionDate([...distributionData[1]]);
setpoolDistributionStage(distributionStage);
}
res['tokenPrice'] = res.saleInfo.tokenPrice;
res['totalSale'] = res.saleInfo.totalSale;
res['totalRaise'] = res.saleInfo.totalRaise;
res['distributionType'] = res.basicInfo.distributionType || "contract";
res['distributionLink'] = res.basicInfo.distributionLink || "";
res['projectName'] = res.basicInfo.projectName;
res['projectToken'] = res.basicInfo.projectToken;
res['mainCoin'] = res.basicInfo.mainCoin;
res['actualChain'] = res.basicInfo.actualChain;
// get state to hide graph and table
const curT = new Date()
if (curT < res.scheduleInfo.saleStart) setCompareAlloDate(true)
const tokenList = ConstantLoader()['tokenList'];
console.log(tokenList);
const mainCoinInfo = tokenList.find(item => item.symbol == res.basicInfo.mainCoin)
// const mainCoinInfo = TOKEN_LIST().find(item => item.symbol == res.basicInfo.mainCoin)
setMainCoinLogoURI(mainCoinInfo.logoURI);
setPoolID(res.basicInfo.poolID);
console.log('res', res);
setReceivedData(res);
} else {
console.log('redirect to list page');
// history.push('/launchpad');
}
})
.catch(e => {
console.log("Project Detail check errrrrrrrrrrr", e);
// console.error(e);
// history.push('/launchpad');
});
}, [library, account]);
// fetching data from Smart Contract
useEffect(() => {
updatePoolData();
}, [library, account, poolID])
// COMPONENTS
return (
<div>
{!receivedData.posterUrl ? (
<div>
<PageLoading />
</div>
) : (
<div className="mainContainer">
<Timer callBack={updatePoolData} ms={30000} />
<TokenBanner posterUrl={receivedData.posterUrl} />
<TokenLogoLabel
projectName={receivedData.projectName}
tokenLogo={receivedData.tokenLogoUrl}
receivedData={receivedData}
/>
<CardArea
poolBaseData={poolBaseData}
receivedData={receivedData}
account={account}
library={library}
mainCoinLogoURI={mainCoinLogoURI}
poolDistributionStage={poolDistributionStage}
poolDistributionDate={poolDistributionDate}
comparesaleDate={comparesaleDate}
comparevestDate={comparevestDate}
poolID={poolID}
poolStatus={poolStatus}
poolMainCoinDecimals={poolMainCoinDecimals}
poolMainCoinAddress={poolMainCoinAddress}
poolTokenAddress={poolTokenAddress}
poolTokenDecimals={poolTokenDecimals}
/>
</div>
)}
</div>
);
}