diff options
author | Leonid Logvinov <logvinov.leon@gmail.com> | 2018-07-18 22:38:16 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-18 22:38:16 +0800 |
commit | 00d1622b3f087943e750f1b3f6ee6ceab7e80285 (patch) | |
tree | 44789fff181ec24846728d885ba541c23f682321 /packages/order-watcher/src/order_watcher/collision_resistant_abi_decoder.ts | |
parent | e2fb49a8f871fd4b631bb01bb641c632b7c19435 (diff) | |
parent | a1acf19ff3c1948214dde05a91eb3fbeac728d2c (diff) | |
download | dexon-sol-tools-00d1622b3f087943e750f1b3f6ee6ceab7e80285.tar dexon-sol-tools-00d1622b3f087943e750f1b3f6ee6ceab7e80285.tar.gz dexon-sol-tools-00d1622b3f087943e750f1b3f6ee6ceab7e80285.tar.bz2 dexon-sol-tools-00d1622b3f087943e750f1b3f6ee6ceab7e80285.tar.lz dexon-sol-tools-00d1622b3f087943e750f1b3f6ee6ceab7e80285.tar.xz dexon-sol-tools-00d1622b3f087943e750f1b3f6ee6ceab7e80285.tar.zst dexon-sol-tools-00d1622b3f087943e750f1b3f6ee6ceab7e80285.zip |
Merge pull request #887 from 0xProject/feature/order-watcher-v2
Order watcher v2
Diffstat (limited to 'packages/order-watcher/src/order_watcher/collision_resistant_abi_decoder.ts')
-rw-r--r-- | packages/order-watcher/src/order_watcher/collision_resistant_abi_decoder.ts | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/packages/order-watcher/src/order_watcher/collision_resistant_abi_decoder.ts b/packages/order-watcher/src/order_watcher/collision_resistant_abi_decoder.ts new file mode 100644 index 000000000..e13663c7a --- /dev/null +++ b/packages/order-watcher/src/order_watcher/collision_resistant_abi_decoder.ts @@ -0,0 +1,54 @@ +import { AbiDecoder } from '@0xproject/utils'; +import { ContractAbi, DecodedLogArgs, LogEntry, LogWithDecodedArgs, RawLog } from 'ethereum-types'; + +const TOKEN_TYPE_COLLISION = `Token can't be marked as ERC20 and ERC721 at the same time`; + +/** + * ERC20 and ERC721 have some events with different args but colliding signature. + * For exmaple: + * Transfer(_from address, _to address, _value uint256) + * Transfer(_from address, _to address, _tokenId uint256) + * Both have the signature: + * Transfer(address,address,uint256) + * + * In order to correctly decode those events we need to know the token type by address in advance. + * You can pass it by calling `this.addERC20Token(address)` or `this.addERC721Token(address)` + */ +export class CollisionResistanceAbiDecoder { + private readonly _erc20AbiDecoder: AbiDecoder; + private readonly _erc721AbiDecoder: AbiDecoder; + private readonly _restAbiDecoder: AbiDecoder; + private readonly _knownERC20Tokens = new Set(); + private readonly _knownERC721Tokens = new Set(); + constructor(erc20Abi: ContractAbi, erc721Abi: ContractAbi, abis: ContractAbi[]) { + this._erc20AbiDecoder = new AbiDecoder([erc20Abi]); + this._erc721AbiDecoder = new AbiDecoder([erc721Abi]); + this._restAbiDecoder = new AbiDecoder(abis); + } + public tryToDecodeLogOrNoop<ArgsType extends DecodedLogArgs>(log: LogEntry): LogWithDecodedArgs<ArgsType> | RawLog { + if (this._knownERC20Tokens.has(log.address)) { + const maybeDecodedERC20Log = this._erc20AbiDecoder.tryToDecodeLogOrNoop(log); + return maybeDecodedERC20Log; + } else if (this._knownERC721Tokens.has(log.address)) { + const maybeDecodedERC721Log = this._erc721AbiDecoder.tryToDecodeLogOrNoop(log); + return maybeDecodedERC721Log; + } else { + const maybeDecodedLog = this._restAbiDecoder.tryToDecodeLogOrNoop(log); + return maybeDecodedLog; + } + } + // Hints the ABI decoder that a particular token address is ERC20 and events from it should be decoded as ERC20 events + public addERC20Token(address: string): void { + if (this._knownERC721Tokens.has(address)) { + throw new Error(TOKEN_TYPE_COLLISION); + } + this._knownERC20Tokens.add(address); + } + // Hints the ABI decoder that a particular token address is ERC721 and events from it should be decoded as ERC721 events + public addERC721Token(address: string): void { + if (this._knownERC20Tokens.has(address)) { + throw new Error(TOKEN_TYPE_COLLISION); + } + this._knownERC721Tokens.add(address); + } +} |