Skip to content

Commit

Permalink
fix: Requesting ERC-20 or ERC-677 Transfer events in log filter. (yea…
Browse files Browse the repository at this point in the history
…rn#186)

* fix: Requesting ERC-20 or ERC-677 Transfer events in log filter.

* fix: use brownie version that contains the ability to download the latest solc compiler patch version for contract compilations and remove handling of '(unknown)' events.

* fix: don't import relative parts and use encode_* methods to encode the addresses for the log filter.

* fix: typo in yaml file

* feat: use brownie master branch which has the required changes merged in which fix event decoding for the given chainlink contract.
  • Loading branch information
mariuspod authored Jan 19, 2022
1 parent 7c8ae07 commit 4073e58
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 30 deletions.
5 changes: 5 additions & 0 deletions brownie-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@ networks:
default: mainnet

autofetch_sources: true

compiler:
solc:
use_latest_patch:
- '0x514910771AF9Ca656af840dff83E8264EcF986CA'
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
eth-brownie>=1.16.4
git+https://github.com/eth-brownie/brownie.git@master
web3>=5.23.1
click>=7.1.2
tabulate>=0.8.7
Expand Down
4 changes: 4 additions & 0 deletions yearn/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,7 @@
"0x7d2aB9CA511EBD6F03971Fb417d3492aA82513f0", # ySwap Multisig
"0x2C01B4AD51a67E2d8F02208F54dF9aC4c0B778B6", # yMechs Multisig
}

# EVENTS
ERC20_TRANSFER_EVENT_HASH = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
ERC677_TRANSFER_EVENT_HASH = '0xe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16'
66 changes: 37 additions & 29 deletions yearn/treasury/treasury.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from brownie import Contract, chain, web3
from brownie.network.event import EventLookupError
from eth_abi import encode_single
from eth_utils import encode_hex
from joblib import Parallel, delayed
from yearn.events import decode_logs
from yearn.multicall2 import fetch_multicall
Expand All @@ -16,7 +17,7 @@
from yearn.exceptions import PriceError
from yearn.utils import contract

from ..constants import TREASURY_WALLETS
from yearn.constants import TREASURY_WALLETS, ERC20_TRANSFER_EVENT_HASH, ERC677_TRANSFER_EVENT_HASH

logger = logging.getLogger(__name__)
logger_price_magic.setLevel(logging.CRITICAL)
Expand Down Expand Up @@ -62,21 +63,17 @@ def _get_price(token, block=None):

def get_token_from_event(event):
try:
address = event['Transfer'][0].address
transfer = event['Transfer']
address = transfer[0].address
# try to download the contract from etherscan
contract(address)
return address
except ValueError:
# some tokens have unverified sources with etherscan, skip them!
return None
except EventLookupError:
logger.critical(
f'One of your cached contracts has an incorrect definition: {event.address}. Please fix this manually'
)
raise Exception(
f'One of your cached contracts has an incorrect definition: {event.address}. Please fix this manually'
)

logger.critical(event)
raise

class Treasury:
'''
Expand All @@ -86,15 +83,26 @@ class Treasury:
def __init__(self, watch_events_forever=False):
self.addresses = list(TREASURY_WALLETS)
self._transfers = []
self._topics_in = [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
None,
['0x000000000000000000000000' + address[2:] for address in self.addresses],
] # Transfers into Yearn wallets
self._topics_out = [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
['0x000000000000000000000000' + address[2:] for address in self.addresses],
] # Transfers out of Yearn wallets
self._start_block = 10502337 # Treasury didn't exist prior to block 10502337

# define transfer signatures for Transfer events from ERC-20 and ERC-677 contracts
transfer_sigs = [
ERC20_TRANSFER_EVENT_HASH,
ERC677_TRANSFER_EVENT_HASH
]
treasury_addresses = [encode_hex(encode_single('address', address)) for address in self.addresses]
self._topics = [
[
transfer_sigs,
None,
treasury_addresses # Transfers into Treasury wallets
],
[
transfer_sigs,
treasury_addresses # Transfers out of Treasury wallets
]
]

self._watch_events_forever = watch_events_forever
self._done = threading.Event()
self._thread = threading.Thread(target=self.watch_transfers, daemon=True)
Expand All @@ -110,13 +118,15 @@ def assets(self, block=None) -> dict:
def token_list(self, address, block=None) -> list:
self.load_transfers()
tokens = set()
for transfer in self._transfers:
token = get_token_from_event(transfer)
for event in self._transfers:
token = get_token_from_event(event)
if token is None:
continue
if transfer['Transfer'].values()[1] == address:

transfer = event['Transfer']
if transfer.values()[1] == address:
if block:
if transfer['Transfer'][0].block_number <= block:
if transfer[0].block_number <= block:
tokens.add(token)
else:
tokens.add(token)
Expand Down Expand Up @@ -274,14 +284,12 @@ def watch_transfers(self):
logger.info(
'pulling treasury transfer events, please wait patiently this takes a while...'
)
# Treasury didn't exist prior to block 10502337
self.log_filter_in = web3.eth.filter({"fromBlock": 10502337, "topics": self._topics_in})
self.log_filter_out = web3.eth.filter({"fromBlock": 10502337, "topics": self._topics_out})
for block in chain.new_blocks(height_buffer=12):
logs = self.log_filter_in.get_new_entries()
self.process_transfers(logs)
logs = self.log_filter_out.get_new_entries()
self.process_transfers(logs)
for topics in self._topics:
topic_filter = web3.eth.filter({"fromBlock": self._start_block, "topics": topics})
logs = topic_filter.get_new_entries()
self.process_transfers(logs)

if not self._done.is_set():
self._done.set()
logger.info(
Expand Down

0 comments on commit 4073e58

Please sign in to comment.