Skip to content
This repository has been archived by the owner on Jan 22, 2019. It is now read-only.

implement erc20 reducer, transfers #35

Merged
merged 3 commits into from
Aug 4, 2018

Conversation

nionis
Copy link
Contributor

@nionis nionis commented Jul 24, 2018

This implementation is only for transfers, we need to discuss on what is the best way to handle mints / burns / totalSupply

Copy link
Member

@shrugs shrugs left a comment

Choose a reason for hiding this comment

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

fantastic start! added some nitpicks

"type": "git",
"url": "[email protected]:XLNT/gnarly.git"
},
"author": "Matt Condon <[email protected]>",
Copy link
Member

Choose a reason for hiding this comment

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

please add yourself here!

'erc20_balances',
{
id: { type: DataTypes.STRING, primaryKey: true },
darAddress: { type: DataTypes.STRING },
Copy link
Member

Choose a reason for hiding this comment

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

let's replace this with tokenAddress or similar; a DAR is a NFT-specific thing (distinct asset registry or whatever it was supposed to mean).

id: { type: DataTypes.STRING, primaryKey: true },
darAddress: { type: DataTypes.STRING },
owner: { type: DataTypes.STRING },
balance: { type: DataTypes.STRING },
Copy link
Member

Choose a reason for hiding this comment

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

It may be helpful to have an unsafeBalance column that's a DECIMAL of some arbitrary precision. It's not ideal, since storing 256 bit numbers is not something postgres is designed to do, but I know a lot of people will want to sort by balance and otherwise do numeric queries, so it'd be good to support that at some basic level. You can see something similar in unsafeNumber from the block metadata reducer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. do you know what data type would be the best?
  2. do we actually need it to be a string at all?

Copy link
Member

Choose a reason for hiding this comment

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

well, turns out the DECIMAL type can handle the 78 decimal points required by a 256 bit number as DECIMAL(78, 0) so perhaps it may not be necessary. google was not very helpfulf or best practices. I've asked twitter and will report back lol https://twitter.com/mattgcondon/status/1022645438229307392

Copy link
Member

Choose a reason for hiding this comment

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

@nionis nobody responded on twitter, but looking at various docs, it seems like a decimal is fine. So let's make the primary datatype a DECIMAL(76, 0) and a backup strBalance or balanceStr (your preference) that holds the raw data just in case

debug('transferring %d tokens from %s to %s', value, from, to)

// turn value into BN value
value = new BN(value)
Copy link
Member

Choose a reason for hiding this comment

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

let's use an immutable pattern here to avoid any confusion about the types

transfer: (from: string, to: string, rawTokenValue: string) => {
   const tokenValue = new BN(rawTokenValue)
   ...

@shrugs
Copy link
Member

shrugs commented Jul 24, 2018

For handing mint/burn mechanics, lets implement the minimum viable concept of

  1. If Transfer to 0x0 or Mint, add the value to the addr and emit a ERC20_MINT reason.
  2. If Transfer from 0x0 or Burn, subtract the value from the addr and emit an ERC20_BURN reason.

That should get us 90% of compatibility, I think. Let's use the OpenZeppelin Burn and Mint event abis.

@nionis
Copy link
Contributor Author

nionis commented Jul 25, 2018

@shrugs should we make 0x0 balance to remain 0 when there its Transfer from 0x0 to X address ?

@shrugs
Copy link
Member

shrugs commented Jul 27, 2018

@nionis It seems like an arbitrary thing, but I do prefer the idea of keeping burns literal. That way we should be able to get totalSuppy by doing something like SELECT SUM(balance) as totalSupply where address = '0xabcd'.

@nionis
Copy link
Contributor Author

nionis commented Aug 3, 2018

@shrugs Mint / Burn always emit Transfer function, so there is no need to check for those events unless we want to specifically store the MINT_REASON or BURN_REASON

so I would just look for Transfer event, and then check from / to values, if they are 0x0 then I do MINT_REASON / BURN_REASON

sounds good?

@shrugs
Copy link
Member

shrugs commented Aug 3, 2018 via email

const MINT_REASON = 'ERC20_MINT'
const BURN_REASON = 'ERC20_BURN'

const isZeroAddress = (address: string) => address === '0x0000000000000000000000000000000000000000'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

probably there is a better way to do this, ideas?

Copy link
Member

Choose a reason for hiding this comment

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

I expected there would be an isNullAddress utility in web3, but apparently there isn't. Let's leave this here for now, but I've added issue #39 to track it

Sequelize,
sequelize,
))(
ZRX_ADDRESS,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I hope using 0x token in bin is not an issue, I used that one because it has alot of traffic and its nice for testing


const makeActions = (state: IERC20Tracker, { operation, emit }) => ({
transfer: (from: string, to: string, rawTokenValue: string) => {
debug('transferring %d tokens from %s to %s', rawTokenValue, from, to)
Copy link
Member

Choose a reason for hiding this comment

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

nit: let's make this

debug('transferring %d %s tokens from %s to %s', rawTokenValue, key, from, to)

so the logs mention which reducer is being run

})
}

operation(() => {
Copy link
Member

Choose a reason for hiding this comment

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

nit: this doesn't actually need to be within an operation; it's implied by the because block that this is executed in.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see! functions like because / operation / emit etc, we could make some documentation on them cause I am not sure how they work tbh

Copy link
Member

Choose a reason for hiding this comment

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

you're totally right 😁

I'm not sure if it's worth investing in a docs wiki or anything just yet, so I'll add an issue to append this information to the README

@shrugs shrugs merged commit 1c8db1d into XLNT:master Aug 4, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants