Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tokens state refactor #300

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open

Tokens state refactor #300

wants to merge 11 commits into from

Conversation

r-czajkowski
Copy link
Collaborator

@r-czajkowski r-czajkowski commented Nov 9, 2022

Depends on: #299

This PR moves the contract integration part from hooks to the Threshold-ts library. Thanks to this layer we can separate work between UI and contract integration. Also, it helps to unit test created services and move the "business logic" from the React hooks.

Main changes

Tokens in Threshold-ts lib

Create an interface and implementation of the ERC20 token and a Tokens class "consumer" that creates all tokens used in T dapp to fetch necessary data.

React

  1. Move fetching token balances to the listener middleware as a one-shot listener and effect callback will be run on walletConnected action.
  2. Clean up tokens redux state- remove the unnecessary conversionRate from a token state, only KEEP and NU has conversion rate to T but the store for tokens must be generic so it's unnecessary to define conversionRate for each token. We have a nice solution for storing the vending machine ratio in local storage.
  3. Refactor the useERC20 hook- use the ERC20 wrapper from the threshold ts lib.
  4. Get rid of the TokenContextProvider- this context provider is now unnecessary. We moved fetching token balances to redux listener middleware and we can get the token state from redux so there is no need for an additional context provider.

Create a wrapper for erc20 token. Also create a `Tokens` class- a wrapper for
all tokens related to the threshold network.
The main change are:
- remove the unnecessary `conversionRate` from a token state, only keep
and nu has conversion rate to T but the store for tokens must be
generic so it's unnecessary to define `conversionRate` for each token.
We have nice solution for storing the vending machine ratio in local
storage.
- clean up the token context- fetching the token balances using the
threshold-ts lib using listener middleware. It's a one-shot listener and
effect callback will be run on `walletConnected` action.  We will
probably get rid of the `TokenContext` in a follow-up work.
Use the ERC20 wrapper from the threshold ts lib.
This context provider is now unnecessary. We moved fetching token
balances to redux listener middleware and we can get the token state
from redux so there is no need for additional context provider.
@github-actions
Copy link

github-actions bot commented Nov 9, 2022

@r-czajkowski r-czajkowski marked this pull request as ready for review November 18, 2022 08:54
Base automatically changed from threshold-lib-updates to main November 18, 2022 12:46
Copy link
Contributor

@michalsmiarowski michalsmiarowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some small comments below

Comment on lines 31 to 32
}
balanceOf = (account: string): Promise<BigNumber> => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add new line here (after 31st line)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 44 to 46
approve = (spender: string, amount: string): Promise<ContractTransaction> => {
return this._contract.approve(spender, amount)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need async/await here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -9,13 +10,15 @@ export class Threshold {
staking!: IStaking
multiAppStaking!: MultiAppStaking
vendingMachines!: IVendingMachines
tokens!: ITokens
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to keep it as singular instead of plurar so we can call specific token as:

threshold.token.tbtc instead of threshold.tokens.tbtc.

What do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbtc: IERC20WithApproveAndCall
}

export class Tokens implements ITokens {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you agree with above then maybe we could also rename those to Token and IToken?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I agree with the above but imo it doesn't fit here because Token sounds like an abstract interface for all tokens eg erc20 or erc721. Maybe TokensWrapper here? I would like to point out here that it's a wrapper for all tokens that we use/are important in Threshold network.

Comment on lines 27 to 28
{ token: tbtcv1, name: Token.TBTC },
{ token: tbtc, name: Token.TBTCV2 },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change the names in Token enum?

Token.TBTC -> Token.TBTCV1
Token.TBTCV2 -> Token.TBTC

I think that we had a discussion about this and we decided to name tbtc-v2 occurences in dApp as tbtc and old tbtc as tbtc-v1

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we had a discussion about this and we decided to name tbtc-v2 occurences in dApp as tbtc and old tbtc as tbtc-v1

yep, comments here: #178 (comment)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 87 to 92
setTokenBalanceError: (
state,
action: PayloadAction<SetTokenConversionRateActionPayload>
action: PayloadAction<SetTokenBalanceErrorActionPayload>
) => {
const { token, conversionRate } = action.payload

const formattedConversionRate = numeral(
+conversionRate / 10 ** 15
).format("0.0000")

state[token].conversionRate = formattedConversionRate
const { token } = action.payload
state[token].loading = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why we need that action? It doesn't set any error in the store so the name of it could be misleading. I think we could refactor the names:

setTokenLoading -> tokenLoading
setTokenBalanceError -> tokenLoaded

if we want to just keep the true/false assignment to loading property in separate actions

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
},
[account, contract]
[token, tokenName, setTokenLoading, setTokenBalanceError]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also add setTokenBalance to the dependency arrray

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@michalsmiarowski michalsmiarowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small issue with tests

contract: Contract | null
}

export const TokenContext = createContext<{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useFetchTvl test fails because it can't find Token Context

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We agree that we prefer to keep it as singular instead of plural so we
can call specific token as: `threshold.token.tbtc` instead of
`threshold.tokens.tbtc`.
`Token.TBTC` -> `Token.TBTCV1`
`Token.TBTCV2` -> `Token.TBTC`

In terms of threshold staking applications, we have only tbtc v2 app so
I think from code's/T dapp's perspective is ok to use tbtc w/o v-2
because it's obvious that only tbtc-v2 works on threshold network. We
only added the tbtc v1 token to get the token price in usd and calculate
tvl.

Ref: #178 (comment)
Trying to treat actions more as "describing events that occurred",
rather than "setters" as recommended in official redux docs.
@github-actions
Copy link

github-actions bot commented Dec 1, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants