From 535fa61f96c67544b491decee2ae2cca33187213 Mon Sep 17 00:00:00 2001 From: antonnell Date: Mon, 2 Aug 2021 15:21:54 +0200 Subject: [PATCH] Stake page functional. Added Staking Overview section with staking relevant info. Integrated deposit/withdraw calls for faucet. Signed-off-by: antonnell --- components/ffMintBurn/ffMintBurn.module.css | 1 + components/ffStake/ffStake.js | 319 ++++++++++++++---- components/ffStake/ffStake.module.css | 59 +++- .../ffStakeDistribution.js | 26 +- components/ffStakeOverview/ffStakeOverview.js | 74 ++++ .../ffStakeOverview.module.css | 57 ++++ components/ffStakeOverview/package.json | 3 + components/ffSwaps/ffSwaps.module.css | 1 + pages/stake/index.js | 4 +- stores/constants/constants.js | 18 +- stores/fixedForexStore.js | 239 +++++++++++-- 11 files changed, 704 insertions(+), 97 deletions(-) create mode 100644 components/ffStakeOverview/ffStakeOverview.js create mode 100644 components/ffStakeOverview/ffStakeOverview.module.css create mode 100644 components/ffStakeOverview/package.json diff --git a/components/ffMintBurn/ffMintBurn.module.css b/components/ffMintBurn/ffMintBurn.module.css index b466e96..44f8635 100644 --- a/components/ffMintBurn/ffMintBurn.module.css +++ b/components/ffMintBurn/ffMintBurn.module.css @@ -17,6 +17,7 @@ grid-template-columns: 1fr; border-left: 1px solid rgba(128, 128, 128, 0.8); padding: 0px 24px; + width: 240px; } .informationContainer { diff --git a/components/ffStake/ffStake.js b/components/ffStake/ffStake.js index ecc71ed..b4cc817 100644 --- a/components/ffStake/ffStake.js +++ b/components/ffStake/ffStake.js @@ -7,106 +7,293 @@ import moment from 'moment'; import { formatCurrency } from '../../utils'; import classes from './ffStake.module.css'; import stores from '../../stores' -import { FIXED_FOREX_UPDATED, IBEUR_ADDRESS } from '../../stores/constants'; +import { + ERROR, + FIXED_FOREX_UPDATED, + MAX_UINT256, + FIXED_FOREX_APPROVE_STAKE_SLP, + FIXED_FOREX_STAKE_SLP_APPROVED, + FIXED_FOREX_STAKE_SLP, + FIXED_FOREX_SLP_STAKED, + FIXED_FOREX_UNSTAKE_SLP, + FIXED_FOREX_SLP_UNSTAKED +} from '../../stores/constants'; import AttachMoneyIcon from '@material-ui/icons/AttachMoney'; export default function ffStake() { + const [ approvalLoading, setApprovalLoading ] = useState(false) + const [ stakeLoading, setStakeLoading ] = useState(false) + const [ ibEURSLP, setIBEURSLP] = useState(null) + const [ rewards, setRewards ] = useState(null) const [ amount, setAmount ] = useState(''); const [ amountError, setAmountError ] = useState(false); + const [ withdrawAmount, setWithdrawAmount ] = useState(''); + const [ withdrawAmountError, setWithdrawAmountError ] = useState(false); + + const [ activeTab, setActiveTab ] = useState('deposit') + useEffect(() => { const forexUpdated = () => { - const asset = stores.fixedForexStore.getAsset(IBEUR_ADDRESS) - setIBEURSLP(asset) + setIBEURSLP(stores.fixedForexStore.getStore('veEURETHSLP')) + setRewards(stores.fixedForexStore.getStore('rewards')) } - const asset = stores.fixedForexStore.getAsset(IBEUR_ADDRESS) - setIBEURSLP(asset) + const approveReturned = () => { + setApprovalLoading(false) + } + + const stakeReturned = () => { + setStakeLoading(false) + } + + const errorReturned = () => { + setStakeLoading(false) + setApprovalLoading(false) + } + + setIBEURSLP(stores.fixedForexStore.getStore('veEURETHSLP')) + setRewards(stores.fixedForexStore.getStore('rewards')) stores.emitter.on(FIXED_FOREX_UPDATED, forexUpdated); + stores.emitter.on(FIXED_FOREX_STAKE_SLP_APPROVED, approveReturned); + stores.emitter.on(FIXED_FOREX_SLP_STAKED, stakeReturned); + stores.emitter.on(FIXED_FOREX_SLP_UNSTAKED, stakeReturned); + stores.emitter.on(ERROR, errorReturned); return () => { stores.emitter.removeListener(FIXED_FOREX_UPDATED, forexUpdated); + stores.emitter.removeListener(FIXED_FOREX_STAKE_SLP_APPROVED, approveReturned); + stores.emitter.removeListener(FIXED_FOREX_SLP_STAKED, stakeReturned); + stores.emitter.removeListener(FIXED_FOREX_SLP_UNSTAKED, stakeReturned); + stores.emitter.removeListener(ERROR, errorReturned); }; }, []); const onAmountChanged = (newVal) => { - setAmount(newVal) + if(activeTab === 'deposit') { + setAmount(newVal) + } else { + setWithdrawAmount(newVal) + } } const setAmountPercent = (percent) => { - setAmount(BigNumber(ibEURSLP.balance).times(percent).div(100).toFixed(ibEURSLP.decimals)); + if(activeTab === 'deposit') { + setAmount(BigNumber(ibEURSLP.balance).times(percent).div(100).toFixed(ibEURSLP.decimals)); + } else { + setWithdrawAmount(BigNumber(rewards.balance).times(percent).div(100).toFixed(ibEURSLP.decimals)); + } + } + + const onApprove = () => { + setApprovalLoading(true) + stores.dispatcher.dispatch({ type: FIXED_FOREX_APPROVE_STAKE_SLP, content: { amount } }) + } + + const onStake = () => { + setStakeLoading(true) + stores.dispatcher.dispatch({ type: FIXED_FOREX_STAKE_SLP, content: { amount } }) + } + + const onUnstake = () => { + setStakeLoading(true) + stores.dispatcher.dispatch({ type: FIXED_FOREX_UNSTAKE_SLP, content: { amount } }) + } + + const toggleDeposit = () => { + setActiveTab('deposit') + } + + const toggleWithdraw = () => { + setActiveTab('withdraw') + } + + const formatApproved = (am) => { + if(BigNumber(am).gte(1000000000000000)) { + return 'Approved Forever' + } + + return `Approved ${formatCurrency(am)}` + } + + let depositApprovalNotRequired = false + if(ibEURSLP) { + depositApprovalNotRequired = BigNumber(ibEURSLP.faucetAllowance).gte(amount) || ((!amount || amount === '') && BigNumber(ibEURSLP.faucetAllowance).gt(0) ) + } + + const calcEstimatedRewards = () => { + let am = 0 + let rew = 0 + if(activeTab === 'deposit') { + am = BigNumber(rewards.balance).plus(amount ? amount : 0) + rew = BigNumber(rewards.faucetSupply).plus(amount ? amount : 0) + } else { + am = BigNumber(rewards.balance).minus(withdrawAmount ? withdrawAmount : 0) + rew = BigNumber(rewards.faucetSupply).minus(withdrawAmount ? withdrawAmount : 0) + } + + let estimatedReward = BigNumber(am).times(rewards.totalRewards).div(rew) + + if(BigNumber(estimatedReward).lte(0)) { + return '0.00' + } else { + return formatCurrency(estimatedReward) + } + } return ( -
- -
-
-
- - Stake Amount: - +
+ + +
+
+
+ { + activeTab === 'deposit' && +
+
+
+ + Stake Amount: + +
+
+ { + setAmountPercent(100); + }} + className={classes.value} + noWrap + > + Balance: {formatCurrency(ibEURSLP ? ibEURSLP.balance : 0)} + +
+
+ { + setAmount(e.target.value); + }} + InputProps={{ + startAdornment: ( + + + + ), + }} + />
-
- { - setAmountPercent(100); + } + { + activeTab === 'withdraw' && +
+
+
+ + Withdraw Amount: + +
+
+ { + setAmountPercent(100); + }} + className={classes.value} + noWrap + > + Balance: {formatCurrency(rewards ? rewards.balance : 0)} + +
+
+ { + setWithdrawAmount(e.target.value); }} - className={classes.value} - noWrap - > - Balance: {formatCurrency(ibEURSLP ? ibEURSLP.balance : 0)} - + InputProps={{ + startAdornment: ( + + + + ), + }} + />
-
- { - setAmount(e.target.value); - }} - InputProps={{ - startAdornment: ( - - - - ), - }} - /> -
-
-
- -
- Estimated Weekly Rewards: - 123.32 ibEUR + } +
+
+ +
+ Estimated Weekly Rewards: + { + rewards && rewards.faucetSupply && rewards.totalRewards && + calcEstimatedRewards() + } ibff +
-
-
- - + { + activeTab === 'deposit' && +
+ + +
+ } + { + activeTab === 'withdraw' && +
+ +
+ }
); diff --git a/components/ffStake/ffStake.module.css b/components/ffStake/ffStake.module.css index 689fdcb..d1d7106 100644 --- a/components/ffStake/ffStake.module.css +++ b/components/ffStake/ffStake.module.css @@ -2,13 +2,22 @@ width: calc(100% - 48px); max-width: 1356px; display: flex; - padding: 24px 0px; border: 1px solid rgba(128, 128, 128, 0.8); position: absolute; top: 240px; left: 0; right: 0; - margin: auto + margin: auto; + min-height: 180px; +} + +.topLeftButton { + border-top-left-radius: 10px !important; + border-bottom: 1px solid rgba(128, 128, 128, 0.25) !important; +} + +.bottomLeftButton { + border-bottom-left-radius: 10px !important; } .inputsContainer { @@ -25,6 +34,20 @@ .textField { flex: 1; + display: flex; + flex-direction: column; + justify-content: center; +} + +.activeIcon { + height: 10px; + width: 10px; + background-color: #0ba360; + border-radius: 50%; + display: inline-block; + position: absolute; + right: 12px; + top: 12px; } .inputTitleContainer { @@ -72,6 +95,7 @@ display: flex; align-items: center; min-width: 300px; + margin-top: 32px; } .infoText { @@ -85,6 +109,7 @@ grid-template-columns: 1fr; border-left: 1px solid rgba(128, 128, 128, 0.8); padding: 0px 24px; + width: 240px; } .actionButtonText { @@ -98,3 +123,33 @@ margin-top: 10px; width: 100%; } + +.reAddPadding { + padding: 24px 0px; + display: flex; + flex: 1; +} + +.loadingCircle { + margin-left: 6px !important; +} + +.toggleButtons { + display: flex; + flex-direction: column; + min-height: 140px; + width: 200px; +} + +.button { + border-radius: 0px !important; + flex: 1; + border-right: 1px solid rgba(128, 128, 128, 0.25) !important; + transition: none !important; + opacity: 0.5; +} + +.buttonActive { + border-radius: 0px !important; + flex: 1; +} diff --git a/components/ffStakeDistribution/ffStakeDistribution.js b/components/ffStakeDistribution/ffStakeDistribution.js index 3601740..bd891ee 100644 --- a/components/ffStakeDistribution/ffStakeDistribution.js +++ b/components/ffStakeDistribution/ffStakeDistribution.js @@ -7,37 +7,53 @@ import moment from 'moment'; import { formatCurrency } from '../../utils'; import classes from './ffStakeDistribution.module.css'; import stores from '../../stores' -import { FIXED_FOREX_UPDATED, IBEUR_ADDRESS } from '../../stores/constants'; +import { FIXED_FOREX_UPDATED, FIXED_FOREX_CLAIM_STAKING_REWARD, FIXED_FOREX_STAKING_REWARD_CLAIMED, ERROR } from '../../stores/constants'; import AttachMoneyIcon from '@material-ui/icons/AttachMoney'; export default function ffStakeDistribution() { const [ rewards, setRewards] = useState(null) + const [ loading, setLoading ] = useState(false) useEffect(() => { const forexUpdated = () => { setRewards(stores.fixedForexStore.getStore('rewards')) } + const errorReturned = () => { + setLoading(false) + } + + const claimReturned = () => { + setLoading(false) + } + setRewards(stores.fixedForexStore.getStore('rewards')) stores.emitter.on(FIXED_FOREX_UPDATED, forexUpdated); + stores.emitter.on(FIXED_FOREX_STAKING_REWARD_CLAIMED, claimReturned); + stores.emitter.on(ERROR, errorReturned); return () => { stores.emitter.removeListener(FIXED_FOREX_UPDATED, forexUpdated); + stores.emitter.removeListener(FIXED_FOREX_STAKING_REWARD_CLAIMED, claimReturned); + stores.emitter.removeListener(ERROR, errorReturned); }; }, []); - const claim = () => { - //do something + const onClaim = () => { + if(loading) { return; } + + setLoading(true) + stores.dispatcher.dispatch({ type: FIXED_FOREX_CLAIM_STAKING_REWARD, content: {} }) } return (
Claimable Rewards -
{ claim() } }> +
{ onClaim() } }>
- Curve Logo + Sushi Logo
Sushiswap LP Staking Rewards diff --git a/components/ffStakeOverview/ffStakeOverview.js b/components/ffStakeOverview/ffStakeOverview.js new file mode 100644 index 0000000..634c8be --- /dev/null +++ b/components/ffStakeOverview/ffStakeOverview.js @@ -0,0 +1,74 @@ +import React, { useState, useEffect } from 'react'; +import { Paper, Typography, Button, TextField, InputAdornment, CircularProgress } from '@material-ui/core'; +import Autocomplete from '@material-ui/lab/Autocomplete'; +import Skeleton from '@material-ui/lab/Skeleton'; +import AccountBalanceWalletIcon from '@material-ui/icons/AccountBalanceWallet'; +import AttachMoneyIcon from '@material-ui/icons/AttachMoney'; +import TimerIcon from '@material-ui/icons/Timer'; + +import { formatCurrency } from '../../utils'; +import classes from './ffStakeOverview.module.css'; + +import stores from '../../stores' +import { FIXED_FOREX_UPDATED } from '../../stores/constants'; + +export default function ffStakeOverview() { + + const [ ibEURSLP, setIBEURSLP] = useState(null) + const [ rewards, setRewards] = useState(null) + + useEffect(() => { + const forexUpdated = () => { + + console.log(stores.fixedForexStore.getStore('veEURETHSLP')) + + setIBEURSLP(stores.fixedForexStore.getStore('veEURETHSLP')) + setRewards(stores.fixedForexStore.getStore('rewards')) + } + + setIBEURSLP(stores.fixedForexStore.getStore('veEURETHSLP')) + setRewards(stores.fixedForexStore.getStore('rewards')) + + stores.emitter.on(FIXED_FOREX_UPDATED, forexUpdated); + return () => { + stores.emitter.removeListener(FIXED_FOREX_UPDATED, forexUpdated); + }; + }, []); + + return ( +
+
+
+ +
+ SLP Balance: +
+ { formatCurrency(ibEURSLP ? ibEURSLP.balance : 0) } + { ibEURSLP ? ibEURSLP.symbol : '' } +
+
+
+
+ +
+ Staked Balance: +
+ { formatCurrency(ibEURSLP ? ibEURSLP.faucetBalance : 0) } + { ibEURSLP ? ibEURSLP.symbol : '' } +
+
+
+
+ +
+ Rewards Available: +
+ { formatCurrency(rewards ? rewards.earned : 0) } + ibff +
+
+
+
+
+ ); +} diff --git a/components/ffStakeOverview/ffStakeOverview.module.css b/components/ffStakeOverview/ffStakeOverview.module.css new file mode 100644 index 0000000..830dde9 --- /dev/null +++ b/components/ffStakeOverview/ffStakeOverview.module.css @@ -0,0 +1,57 @@ +.container { + width: 100%; + background-image: linear-gradient(0deg ,#1c46f5 0,#0005d3); + margin-bottom: 120px; + padding: 0px 24px; +} + +.fieldsContainer { + max-width: 1356px; + display: flex; + margin: 0 auto; + padding: 48px 0px 140px 0px; + align-items: center; + justify-content: space-between; + min-height: 270px; +} + +.field { + display: flex; +} + +.title { + background: rgba(256, 256, 256, 0.3); + border-radius: 30px; + padding: 4px 20px; + width: fit-content; + color: #fff !important; + font-size: 14px !important; +} + +.value { + font-size: 40px !important; + font-weight: bold !important; + color: #fff !important; +} + +.inline { + display: flex; + align-items: flex-end; +} + +.valueSymbol { + font-size: 20px !important; + font-weight: bold !important; + color: #fff !important; + margin-bottom: 4px !important; + margin-left: 3px !important; +} + +.balanceIcon { + color: #fff; + border: 1px solid #fff; + border-radius: 50%; + padding: 16px; + font-size: 70px !important; + margin-right: 24px !important; +} diff --git a/components/ffStakeOverview/package.json b/components/ffStakeOverview/package.json new file mode 100644 index 0000000..ea9c7af --- /dev/null +++ b/components/ffStakeOverview/package.json @@ -0,0 +1,3 @@ +{ + "main": "ffStakeOverview.js" +} diff --git a/components/ffSwaps/ffSwaps.module.css b/components/ffSwaps/ffSwaps.module.css index 5fa000a..7a7f9f5 100644 --- a/components/ffSwaps/ffSwaps.module.css +++ b/components/ffSwaps/ffSwaps.module.css @@ -87,6 +87,7 @@ grid-template-columns: 1fr; border-left: 1px solid rgba(128, 128, 128, 0.8); padding: 0px 24px; + width: 240px; } .actionButtonText { diff --git a/pages/stake/index.js b/pages/stake/index.js index 63cafe7..78d1718 100644 --- a/pages/stake/index.js +++ b/pages/stake/index.js @@ -7,7 +7,7 @@ import Head from 'next/head'; import Layout from '../../components/layout/layout.js'; import StakeSLP from '../../components/ffStake'; import StakeDistribution from '../../components/ffStakeDistribution'; -import Overview from '../../components/ffOverview'; +import StakeOverview from '../../components/ffStakeOverview'; import classes from './stake.module.css'; @@ -23,7 +23,7 @@ function Stake({ changeTheme }) { Fixed Forex
- +
diff --git a/stores/constants/constants.js b/stores/constants/constants.js index 7897fd1..f30b917 100644 --- a/stores/constants/constants.js +++ b/stores/constants/constants.js @@ -41,6 +41,23 @@ export const FIXED_FOREX_CONFIGURED = 'FIXED_FOREX_CONFIGURED'; export const GET_FIXED_FOREX_BALANCES = 'GET_FIXED_FOREX_BALANCES'; export const FIXED_FOREX_BALANCES_RETURNED = 'FIXED_FOREX_BALANCES_RETURNED'; +export const FIXED_FOREX_CLAIM_VESTING_REWARD = 'FIXED_FOREX_CLAIM_VESTING_REWARD'; +export const FIXED_FOREX_VESTING_REWARD_CLAIMED = 'FIXED_FOREX_VESTING_REWARD_CLAIMED'; + +export const FIXED_FOREX_CLAIM_STAKING_REWARD = 'FIXED_FOREX_CLAIM_STAKING_REWARD'; +export const FIXED_FOREX_STAKING_REWARD_CLAIMED = 'FIXED_FOREX_STAKING_REWARD_CLAIMED'; + +export const FIXED_FOREX_APPROVE_STAKE_SLP = 'FIXED_FOREX_APPROVE_STAKE_SLP' +export const FIXED_FOREX_STAKE_SLP_APPROVED = 'FIXED_FOREX_STAKE_SLP_APPROVED' + +export const FIXED_FOREX_STAKE_SLP = 'FIXED_FOREX_STAKE_SLP' +export const FIXED_FOREX_SLP_STAKED = 'FIXED_FOREX_SLP_STAKED' + +export const FIXED_FOREX_UNSTAKE_SLP = 'FIXED_FOREX_UNSTAKE_SLP' +export const FIXED_FOREX_SLP_UNSTAKED = 'FIXED_FOREX_SLP_UNSTAKED' + + + export const APPROVE_FUSD = 'APPROVE_FUSD' export const FUSD_APPROVED = 'FUSD_APPROVED' @@ -50,5 +67,4 @@ export const FUSD_MINTED = 'FUSD_MINTED' export const BURN_FUSD = 'BURN_FUSD' export const FUSD_BURNT = 'FUSD_BURNT' - export const MAX_UINT256 = new BigNumber(2).pow(256).minus(1).toFixed(0); diff --git a/stores/fixedForexStore.js b/stores/fixedForexStore.js index f0c1597..d3eaba8 100644 --- a/stores/fixedForexStore.js +++ b/stores/fixedForexStore.js @@ -16,6 +16,16 @@ import { FIXED_FOREX_CONFIGURED, GET_FIXED_FOREX_BALANCES, FIXED_FOREX_BALANCES_RETURNED, + FIXED_FOREX_CLAIM_VESTING_REWARD, + FIXED_FOREX_VESTING_REWARD_CLAIMED, + FIXED_FOREX_CLAIM_STAKING_REWARD, + FIXED_FOREX_STAKING_REWARD_CLAIMED, + FIXED_FOREX_STAKE_SLP, + FIXED_FOREX_SLP_STAKED, + FIXED_FOREX_APPROVE_STAKE_SLP, + FIXED_FOREX_STAKE_SLP_APPROVED, + FIXED_FOREX_UNSTAKE_SLP, + FIXED_FOREX_SLP_UNSTAKED, } from './constants'; import * as moment from 'moment'; @@ -36,11 +46,13 @@ class Store { assets: [], ibff: null, veIBFF: null, + veEURETHSLP: null, rewards: null }; dispatcher.register( function (payload) { + console.log(payload) switch (payload.type) { case CONFIGURE_FIXED_FOREX: this.configure(payload); @@ -48,6 +60,21 @@ class Store { case GET_FIXED_FOREX_BALANCES: this.getFFBalances(payload); break; + case FIXED_FOREX_CLAIM_VESTING_REWARD: + this.claimVestingReward(payload); + break; + case FIXED_FOREX_CLAIM_STAKING_REWARD: + this.claimStakingReward(payload); + break; + case FIXED_FOREX_STAKE_SLP: + this.stakeSLP(payload); + break; + case FIXED_FOREX_APPROVE_STAKE_SLP: + this.approveStakeSLP(payload); + break; + case FIXED_FOREX_UNSTAKE_SLP: + this.unstakeSLP(payload); + break; default: { } } @@ -188,8 +215,14 @@ class Store { // get veIBFF bal const veIBFF = await this._getAssetInfo(web3, { address: VEIBFF_ADDRESS }, account) + // get veIBFF bal + const veEURETHSLP = await this._getAssetInfo(web3, { address: IBEUR_ETH_ADDRESS }, account) + const faucetContractApprovalAmount = await this._getApprovalAmount(web3, veEURETHSLP, account.address, FF_FAUCET_ADDRESS) + // get rewards - const rewards = await this._getRewards(web3, account, ibff) + const rewards = await this._getFaucetRewards(web3, account, ibff) + veEURETHSLP.faucetAllowance = faucetContractApprovalAmount + veEURETHSLP.faucetBalance = rewards.balance // get asset balances // get asset approvals (swap/stake/vest) @@ -212,6 +245,7 @@ class Store { assets: assets, ibff, veIBFF, + veEURETHSLP, rewards, }) @@ -222,17 +256,20 @@ class Store { } }; - _getRewards = async (web3, account, ibff) => { + _getFaucetRewards = async (web3, account, ibff) => { try { - // const distributionContract = new web3.eth.Contract(abis.distributionABI, FF_DISTRIBUTION_ADDRESS) - // const claimable = await distributionContract.methods.claimable(account.address).call() - const faucetContract = new web3.eth.Contract(abis.faucetABI, FF_FAUCET_ADDRESS) + const earned = await faucetContract.methods.earned(account.address).call() + const totalRewards = await faucetContract.methods.getRewardForDuration().call() + const totalSupply = await faucetContract.methods.totalSupply().call() + const balanceOf = await faucetContract.methods.balanceOf(account.address).call() return { - // distribution: BigNumber(claimable).div(10**ibff.decimals).toFixed(ibff.decimals), - faucet: BigNumber(earned).div(10**ibff.decimals).toFixed(ibff.decimals) + earned: BigNumber(earned).div(10**ibff.decimals).toFixed(ibff.decimals), + faucetSupply: BigNumber(totalSupply).div(10**ibff.decimals).toFixed(ibff.decimals), + totalRewards: BigNumber(totalRewards).div(10**ibff.decimals).toFixed(ibff.decimals), + balance: BigNumber(balanceOf).div(10**ibff.decimals).toFixed(ibff.decimals) } } catch(ex) { console.log(ex) @@ -240,7 +277,21 @@ class Store { } } - approveFUSD = async (payload) => { + _getApprovalAmount = async (web3, asset, owner, spender) => { + const erc20Contract = new web3.eth.Contract(abis.erc20ABI, asset.address) + const allowance = await erc20Contract.methods.allowance(owner, spender).call() + + return BigNumber(allowance).div(10**asset.decimals).toFixed(asset.decimals) + } + + _getFaucetStakedAmount = async (web3, asset, owner) => { + const faucetContract = new web3.eth.Contract(abis.faucetABI, FF_FAUCET_ADDRESS) + const balanceOf = await faucetContract.methods.balanceOf(owner).call() + + return BigNumber(balanceOf).div(10**asset.decimals).toFixed(asset.decimals) + } + + claimVestingReward = async (payload) => { const account = stores.accountStore.getStore('account'); if (!account) { return false; @@ -253,32 +304,178 @@ class Store { //maybe throw an error } - const { asset, amount, gasSpeed } = payload.content; + const { gasSpeed } = payload.content; - this._callApproveFUSD(web3, asset, account, amount, gasSpeed, (err, approveResult) => { + this._callClaimVestingReward(web3, account, gasSpeed, (err, res) => { if (err) { return this.emitter.emit(ERROR, err); } - return this.emitter.emit(FUSD_APPROVED, approveResult); + return this.emitter.emit(FIXED_FOREX_VESTING_REWARD_CLAIMED, res); }); - }; + } + + _callClaimVestingReward = async (web3, account, gasSpeed, callback) => { + try { + const faucetContract = new web3.eth.Contract(abis.faucetABI, FF_FAUCET_ADDRESS) + const gasPrice = await stores.accountStore.getGasPrice(gasSpeed); + + this._callContractWait(web3, faucetContract, 'getReward', [], account, gasPrice, GET_FIXED_FOREX_BALANCES, callback); + } catch (ex) { + console.log(ex); + return this.emitter.emit(ERROR, ex); + } + } - _callApproveFUSD = async (web3, asset, account, amount, gasSpeed, callback) => { - const tokenContract = new web3.eth.Contract(ERC20ABI, asset.tokenMetadata.address); + claimStakingReward = async (payload) => { + const account = stores.accountStore.getStore('account'); + if (!account) { + return false; + //maybe throw an error + } - let amountToSend = '0'; - if (amount === 'max') { - amountToSend = MAX_UINT256; - } else { - amountToSend = BigNumber(amount) - .times(10 ** asset.tokenMetadata.decimals) + const web3 = await stores.accountStore.getWeb3Provider(); + if (!web3) { + return false; + //maybe throw an error + } + + const { gasSpeed } = payload.content; + + this._callClaimStakingReward(web3, account, gasSpeed, (err, res) => { + if (err) { + return this.emitter.emit(ERROR, err); + } + + return this.emitter.emit(FIXED_FOREX_STAKING_REWARD_CLAIMED, res); + }); + } + + _callClaimStakingReward = async (web3, account, gasSpeed, callback) => { + try { + const faucetContract = new web3.eth.Contract(abis.faucetABI, FF_FAUCET_ADDRESS) + const gasPrice = await stores.accountStore.getGasPrice(gasSpeed); + + this._callContractWait(web3, faucetContract, 'getReward', [], account, gasPrice, GET_FIXED_FOREX_BALANCES, callback); + } catch (ex) { + console.log(ex); + return this.emitter.emit(ERROR, ex); + } + } + + stakeSLP = async (payload) => { + const account = stores.accountStore.getStore('account'); + if (!account) { + return false; + //maybe throw an error + } + + const web3 = await stores.accountStore.getWeb3Provider(); + if (!web3) { + return false; + //maybe throw an error + } + + const { amount, gasSpeed } = payload.content; + + this._callDepositFaucet(web3, account, amount, gasSpeed, (err, res) => { + if (err) { + return this.emitter.emit(ERROR, err); + } + + return this.emitter.emit(FIXED_FOREX_SLP_STAKED, res); + }); + + } + + _callDepositFaucet = async (web3, account, amount, gasSpeed, callback) => { + try { + let faucetContract = new web3.eth.Contract(abis.faucetABI, FF_FAUCET_ADDRESS); + + const sendAmount = BigNumber(amount === '' ? 0 : amount) + .times(10 ** 18) .toFixed(0); + + const gasPrice = await stores.accountStore.getGasPrice(gasSpeed); + + this._callContractWait(web3, faucetContract, 'deposit', [sendAmount], account, gasPrice, GET_FIXED_FOREX_BALANCES, callback); + } catch (ex) { + console.log(ex); + return this.emitter.emit(ERROR, ex); } + }; + + + approveStakeSLP = async (payload) => { + const account = stores.accountStore.getStore('account'); + if (!account) { + return false; + //maybe throw an error + } + + const web3 = await stores.accountStore.getWeb3Provider(); + if (!web3) { + return false; + //maybe throw an error + } + + const { gasSpeed } = payload.content; + + this._callApproveStakeSLP(web3, account, gasSpeed, (err, res) => { + if (err) { + return this.emitter.emit(ERROR, err); + } + + return this.emitter.emit(FIXED_FOREX_STAKE_SLP_APPROVED, res); + }); + } + _callApproveStakeSLP = async (web3, account, gasSpeed, callback) => { + const slpContract = new web3.eth.Contract(abis.sushiLPABI, IBEUR_ETH_ADDRESS); const gasPrice = await stores.accountStore.getGasPrice(gasSpeed); + this._callContractWait(web3, slpContract, 'approve', [FF_FAUCET_ADDRESS, MAX_UINT256], account, gasPrice, GET_FIXED_FOREX_BALANCES, callback); + }; + + unstakeSLP = async (payload) => { + const account = stores.accountStore.getStore('account'); + if (!account) { + return false; + //maybe throw an error + } - this._callContractWait(web3, tokenContract, 'approve', ['CDP_VAULT_ADDRESS', amountToSend], account, gasPrice, GET_FUSD_BALANCES, callback); + const web3 = await stores.accountStore.getWeb3Provider(); + if (!web3) { + return false; + //maybe throw an error + } + + const { amount, gasSpeed } = payload.content; + + this._callWithdrawFaucet(web3, account, amount, gasSpeed, (err, res) => { + if (err) { + return this.emitter.emit(ERROR, err); + } + + return this.emitter.emit(FIXED_FOREX_SLP_UNSTAKED, res); + }); + + } + + _callWithdrawFaucet = async (web3, account, amount, gasSpeed, callback) => { + try { + let faucetContract = new web3.eth.Contract(abis.faucetABI, FF_FAUCET_ADDRESS); + + const sendAmount = BigNumber(amount === '' ? 0 : amount) + .times(10 ** 18) + .toFixed(0); + + const gasPrice = await stores.accountStore.getGasPrice(gasSpeed); + + this._callContractWait(web3, faucetContract, 'withdraw', [sendAmount], account, gasPrice, GET_FIXED_FOREX_BALANCES, callback); + } catch (ex) { + console.log(ex); + return this.emitter.emit(ERROR, ex); + } }; mintFUSD = async (payload) => {