Skip to content

Commit

Permalink
feat: add base network (#609)
Browse files Browse the repository at this point in the history
* add: constants info

* add: prices/constants

* add: mc3

* add: release registry

* add: yearn.py products

* add: uni v3

* add: uni v3 2

* add: binary search barrier

* add: vaults start date

* add: base network

* add: base network make

* add: base docker-compose

* fix: set network envs

* add hacky brownie init fix

* rebase

* fix: batch size

* update contant

* fix: vaults.py

* update: treasury.py

* rebase

* refactor: yearn.py

* bump dank

* bump ypm

* add: delegated partners contract

* add: lens v2

* update: s3

* fix: registry

* temp: no curve pool base

* delete: no cache

* rebase: async update ypm

* update: uni v3 quoter for base

* fix: typo

* add: batch_size and block info to transactions.py

* fix: transactions batch end block

* update: s3 registry

* update s3 registry adapter

* increase: batchsize

* fix: wallets.py start time

* fix: wallets

* fix-treasury rebase messed up

* fix: tuple error wallets

* bump ypm

* add: base wrapped gas coin

* chore: add debug logger

* fix: rebase err

* fix: EventLookupError

---------

Co-authored-by: BobTheBuidler <[email protected]>
  • Loading branch information
0xBasically and BobTheBuidler authored Sep 11, 2023
1 parent e2d939c commit 5491960
Show file tree
Hide file tree
Showing 22 changed files with 95 additions and 25 deletions.
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ endif
#######################################
# specify all supported networks here #
#######################################
supported_networks := ethereum fantom arbitrum optimism
supported_networks := ethereum fantom arbitrum optimism base

###############################################
# specify all supported exporter scripts here #
Expand Down Expand Up @@ -65,7 +65,6 @@ down:
.PHONY: build
build:
docker build -t ghcr.io/yearn/yearn-exporter .

logs:
$(eval filter = $(if $(filter),yearn-exporter-$(filter),$(if $(network),$(network),yearn-exporter-worker)))
$(eval since = $(if $(since),$(since),300s))
Expand Down Expand Up @@ -98,6 +97,7 @@ up:
make down filter=yearn-exporter-worker-fantom-exporters-treasury-transactions
make down filter=yearn-exporter-worker-arbitrum-exporters-treasury-transactions
make down filter=yearn-exporter-worker-optimism-exporters-treasury-transactions
make down filter=yearn-exporter-worker-base-exporters-treasury-transactions

# LOGGING
$(eval with_logs = $(if $(with_logs),$(with_logs),true))
Expand Down Expand Up @@ -197,6 +197,10 @@ optimism:
gnosis:
make up logs network=gnosis

# Base Chain
base:
make up logs network=base

############################
# Exporter-specifc recipes #
############################
Expand Down
5 changes: 3 additions & 2 deletions brownie_init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ set -e

BROWNIE_NETWORK=${BROWNIE_NETWORK:-mainnet} # default to Ethereum mainnet
EXPLORER=${EXPLORER:-$DEFAULT_EXPLORER}
brownie networks add Base base-main host=https://base.meowrpc.com chainid=8453 explorer=https://api.basescan.org/api || true

# modify the network
# modify the network & add Base network
if [[ ! -z "$WEB3_PROVIDER" ]]; then
brownie networks modify $BROWNIE_NETWORK host=$WEB3_PROVIDER explorer=$EXPLORER
fi
fi
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ eth_retry>=0.1.18
eth-hash[pysha3]
ez-a-sync==0.6.6
python-telegram-bot==13.15
git+https://www.github.com/BobTheBuidler/ypricemagic@88ae753ba020f74b4febb1216c83e63a0ed8294e
git+https://www.github.com/banteg/multicall.py@5cdb0f08ddadf1c381dc0966b8bd71e3ac7c6272
git+https://www.github.com/BobTheBuidler/ypricemagic@2f1895d0efde0802c1ada8a5361701f759273ddd
git+https://www.github.com/BobTheBuidler/eth-portfolio@6c71e6200663063c92b7d7f27bbafba7a0b02997
git+https://www.github.com/BobTheBuidler/toolcache@e37b53cec64556d2b35df66767fca4c8f366a2fa
memray
Expand Down
2 changes: 2 additions & 0 deletions scripts/exporters/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
Network.Gnosis: 2_000_000,
Network.Arbitrum: 1_500_000,
Network.Optimism: 4_000_000,
Network.Base: 100_000,
}[chain.id]

FIRST_END_BLOCK = {
Expand All @@ -47,6 +48,7 @@
Network.Gnosis: 21_440_000, # # NOTE block some arbitrary time after first vault deployment
Network.Arbitrum: 4_837_859,
Network.Optimism: 18_111_485,
Network.Base: 3_571_971,
}[chain.id]

def main():
Expand Down
4 changes: 4 additions & 0 deletions scripts/exporters/vaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
# end: 2020-02-12 first iearn deployment
start = datetime(2020, 2, 12, 0, 1, tzinfo=timezone.utc)
data_query = 'iearn{network="' + Network.label() + '"}'
elif Network(chain.id) == Network.Base:
# end: release registry Aug-29-2023 01:37:43 PM +UTC block 3263458
start = datetime(2023, 8, 29, tzinfo=timezone.utc)
data_query = 'yearn_vault{network="' + Network.label() + '"}'
else:
raise NotImplementedError()

Expand Down
7 changes: 6 additions & 1 deletion scripts/exporters/wallets.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@

# start: 2020-02-12 first iearn deployment
# start opti: 2022-01-01 an arbitrary start timestamp because the default start is < block 1 on opti and messes things up
start = datetime(2022, 1, 1, tzinfo=timezone.utc) if chain.id in [Network.Arbitrum, Network.Optimism] else datetime(2020, 2, 12, tzinfo=timezone.utc)
if chain.id in [Network.Arbitrum, Network.Optimism]:
start = datetime(2022, 1, 1, tzinfo=timezone.utc)
elif Network.Base:
start = datetime(2023, 9, 1, tzinfo=timezone.utc)
else:
start = datetime(2020, 2, 12, tzinfo=timezone.utc)

@ttl_cache(ttl=60)
def get_last_recorded_block():
Expand Down
2 changes: 2 additions & 0 deletions scripts/s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ async def get_registry_adapter():
registry_adapter_address = "0x57AA88A0810dfe3f9b71a9b179Dd8bF5F956C46A"
elif chain.id == Network.Optimism:
registry_adapter_address = "0xBcfCA75fF12E2C1bB404c2C216DBF901BE047690"
elif chain.id == Network.Base:
registry_adapter_address = "0xACd0CEa837A6E6f5824F4Cac6467a67dfF4B0868"
return await Contract.coroutine(registry_adapter_address)


Expand Down
1 change: 1 addition & 0 deletions services/dashboard/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ x-envs: &envs
- FTMSCAN_TOKEN
- ARBISCAN_TOKEN
- OPTISCAN_TOKEN
- BASESCAN_TOKEN

# POSTGRES ENVS
- PGHOST=postgres
Expand Down
7 changes: 7 additions & 0 deletions set_network_envs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ elif [[ "$network" =~ ^op$|^OPTI$|^opti$|^optimism$ ]]; then
export EXPLORER=$OPTI_EXPLORER
export DEFAULT_EXPLORER=https://api-optimistic.etherscan.io/api

elif [[ "$network" =~ ^base$|^BASE$ ]]; then
export NETWORK=base
export BROWNIE_NETWORK=base-main
export WEB3_PROVIDER=$BASE_WEB3_PROVIDER
export EXPLORER=$BASE_EXPLORER
export DEFAULT_EXPLORER=https://api.basescan.org/api

else
echo "Error! Unsupported network $network specified!"
exit 1
Expand Down
10 changes: 10 additions & 0 deletions yearn/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
Network.Gnosis: "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d",
Network.Optimism: "0x4200000000000000000000000000000000000006",
Network.Polygon: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
Network.Base: "0x4200000000000000000000000000000000000006"
}.get(chain.id, None)

YEARN_ADDRESSES_PROVIDER = "0x9be19Ee7Bc4099D62737a7255f5c227fBcd6dB93"
Expand All @@ -45,6 +46,9 @@
Network.Optimism: {
"0xea3a15df68fCdBE44Fdb0DB675B2b3A14a148b26",
},
Network.Base: {
"0x01fE3347316b2223961B20689C65eaeA71348e93",
},
}.get(chain.id,set())

STRATEGIST_MULTISIG = {convert.to_address(address) for address in STRATEGIST_MULTISIG}
Expand All @@ -55,6 +59,7 @@
Network.Gnosis: "0x22eAe41c7Da367b9a15e942EB6227DF849Bb498C",
Network.Arbitrum: "0xb6bc033d34733329971b938fef32fad7e98e56ad",
Network.Optimism: "0xF5d9D6133b698cE29567a90Ab35CfB874204B3A7",
Network.Base: "0xbfAABa9F56A39B814281D68d2Ad949e88D06b02E",
}.get(chain.id, None)

if YCHAD_MULTISIG:
Expand All @@ -65,6 +70,7 @@
Network.Fantom: "0x89716Ad7EDC3be3B35695789C475F3e7A3Deb12a",
Network.Arbitrum: "0x1deb47dcc9a35ad454bf7f0fcdb03c09792c08c1",
Network.Optimism: "0x84654e35E504452769757AAe5a8C7C6599cBf954",
Network.Base: "0x02ff746D8cb62709aEEc611CeC9B17d7dD1D3480",
}.get(chain.id, None)

if TREASURY_MULTISIG:
Expand Down Expand Up @@ -97,6 +103,10 @@
YCHAD_MULTISIG,
TREASURY_MULTISIG,
},
Network.Base: {
YCHAD_MULTISIG,
TREASURY_MULTISIG,
}
}.get(chain.id,set())

TREASURY_WALLETS = {convert.to_address(address) for address in TREASURY_WALLETS}
Expand Down
1 change: 1 addition & 0 deletions yearn/middleware/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
Network.Fantom: 10_000, # 0.1 days
Network.Arbitrum: 20_000, # 0.34 days
Network.Optimism: 800_000, # 10.02 days
Network.Base: 800_000, # test value
}

def _get_batch_size() -> int:
Expand Down
3 changes: 2 additions & 1 deletion yearn/multicall2.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
Network.Gnosis: '0xFAa296891cA6CECAF2D86eF5F7590316d0A17dA0', # maker has not yet deployed multicall2. This is from another deployment
Network.Fantom: '0xD98e3dBE5950Ca8Ce5a4b59630a5652110403E5c',
Network.Arbitrum: '0x5B5CFE992AdAC0C9D48E05854B2d91C73a003858',
Network.Optimism: '0xcA11bde05977b3631167028862bE2a173976CA11' # Multicall 3
Network.Optimism: '0xcA11bde05977b3631167028862bE2a173976CA11', # Multicall 3
Network.Base: '0xcA11bde05977b3631167028862bE2a173976CA11' # MC3
}
multicall2 = contract(MULTICALL2[chain.id])

Expand Down
1 change: 1 addition & 0 deletions yearn/partners/delegated.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
Network.Fantom: "0x086865B2983320b36C42E48086DaDc786c9Ac73B",
Network.Arbitrum: "0x0e5b46E4b2a05fd53F5a4cD974eb98a9a613bcb7",
Network.Optimism: "0x7E08735690028cdF3D81e7165493F1C34065AbA2",
Network.Base: "0xD0F08E42A40569fF83D28AA783a5b6537462667c",
}[chain.id])

class AsOfDict(dict):
Expand Down
17 changes: 15 additions & 2 deletions yearn/prices/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
'weth': '0x4200000000000000000000000000000000000006',
'usdc': '0x7F5c764cBc14f9669B88837ca1490cCa17c31607',
'dai': '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
},
Network.Base: {
'weth': '0x4200000000000000000000000000000000000006',
'dai': '0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb',
'usdc': '0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA', #temp
'usdt': '0x4A3A6Dd60A34bB2Aba60D73B4C88315E9CeB6A3D', #temp
'wbtc': '0x77852193BD608A518dd7b7C2f891A1d02ceeB4d4', #temp
}
}

Expand Down Expand Up @@ -87,15 +94,21 @@
'0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1': 'dai',
'0x2E3D870790dC77A83DD1d18184Acc7439A53f475': 'frax',
'0x8c6f28f2F1A3C87F0f938b96d27520d9751ec8d9': 'susd',
},
Network.Base: {
'0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA': 'usdbc',
'0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb': 'dai',
'0x4A3A6Dd60A34bB2Aba60D73B4C88315E9CeB6A3D': 'mim',
}
}

ib_snapshot_block_by_network = {
Network.Mainnet: 14051986,
Network.Fantom: 28680044,
Network.Gnosis: 1, # TODO revisit as IB is not deployed in gnosis
Network.Arbitrum: 1,
Network.Gnosis: 1, # TODO revisit as IB is not deployed on gnosis
Network.Arbitrum: 1, # TODO revisit as IB is not deployed on arbitrum
Network.Optimism: 12658427,
Network.Base: 1, # TODO revisit as IB is not deployed on base
}

# We convert to checksum address here to prevent minor annoyances. It's worth it.
Expand Down
3 changes: 3 additions & 0 deletions yearn/prices/curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ def __init__(self) -> None:

@sentry_catch_all
def watch_events(self) -> None:
if chain.id == Network.Base:
# No curve pool
return
sleep_time = 600
registries = []
registry_logs = []
Expand Down
7 changes: 7 additions & 0 deletions yearn/prices/uniswap/v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@
'router': '0xE6Df0BB08e5A97b40B21950a0A51b94c4DbA0Ff6',

}
],
Network.Base: [
{
'name': 'sushiswap',
'factory': '0x71524B4f93c58fcbF659783284E38825f0622859',
'router': '0x6BDED42c6DA8FBf0d2bA55B2fa120C5e0c8D7891',
}
]
}

Expand Down
13 changes: 10 additions & 3 deletions yearn/prices/uniswap/v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,33 @@ def __init__(self, v) -> None:

# https://github.com/Uniswap/uniswap-v3-periphery/blob/main/deploys.md
UNISWAP_V3_FACTORY = '0x1F98431c8aD98523631AE4a59f267346ea31F984'
UNISWAP_V3_QUOTER = '0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6'
FEE_DENOMINATOR = 1_000_000
USDC_SCALE = 1e6

# same addresses on all networks
addresses = {
Network.Mainnet: {
'factory': UNISWAP_V3_FACTORY,
'quoter': UNISWAP_V3_QUOTER,
'fee_tiers': [3000, 500, 10_000, 100],
},
Network.Arbitrum: {
'factory': UNISWAP_V3_FACTORY,
'quoter': UNISWAP_V3_QUOTER,
'fee_tiers': [3000, 500, 10_000],
},
Network.Optimism: {
'factory': UNISWAP_V3_FACTORY,
'quoter': UNISWAP_V3_QUOTER,
'fee_tiers': [3000, 500, 10_000, 100],
},
Network.Base: {
'factory': '0x33128a8fC17869897dcE68Ed026d694621f6FDfD',
'quoter': '0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a', # quoter v2
'fee_tiers': [3000, 500, 10_000, 100],
}
}


class UniswapV3(metaclass=Singleton):
def __init__(self) -> None:
if chain.id not in addresses:
Expand All @@ -58,7 +65,7 @@ def __init__(self) -> None:
self.factory: Contract = contract(conf['factory'])
self.quoter: Contract = Contract.from_abi(
name='Quoter',
address='0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6',
address=addresses[chain.id]['quoter'],
abi=json.load(open('interfaces/uniswap/UniswapV3Quoter.json'))
) # use direct abi from etherscan because the quoter is not verified on all chains (opti)
self.fee_tiers = [FeeTier(fee) for fee in conf['fee_tiers']]
Expand Down
3 changes: 3 additions & 0 deletions yearn/prices/yearn.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
Network.Optimism: {
'v2': '0xBcfCA75fF12E2C1bB404c2C216DBF901BE047690',
},
Network.Base: {
'v2': '0xACd0CEa837A6E6f5824F4Cac6467a67dfF4B0868',
}
}


Expand Down
2 changes: 2 additions & 0 deletions yearn/treasury/treasury.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def __init__(self, asynchronous: bool = False, load_prices: bool = False) -> Non
Network.Gnosis: 20_000_000,
Network.Arbitrum: 4_837_859,
Network.Optimism: 18_100_336,
Network.Base: 3_264_243,
}[chain.id]

''' TODO: confirm these starts match start_block
Expand Down Expand Up @@ -122,6 +123,7 @@ def __init__(self, asynchronous: bool = False, load_prices: bool = False) -> Non
Network.Gnosis: 20_455_212,
Network.Arbitrum: 2_434_174,
Network.Optimism: 18_084_577,
Network.Base: 3_263_643,
}[chain.id]
super().__init__(constants.STRATEGIST_MULTISIG, label='sms', start_block=start_block, asynchronous=asynchronous, load_prices=load_prices)

Expand Down
1 change: 1 addition & 0 deletions yearn/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
Network.Fantom: 4_564_024, # fantom returns "missing trie node" before that
Network.Arbitrum: 0,
Network.Optimism: 0,
Network.Base: 0,
}

_erc20 = lru_cache(maxsize=None)(interface.ERC20)
Expand Down
6 changes: 5 additions & 1 deletion yearn/v2/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,18 @@ def load_registry(self):
contract('0x81291ceb9bB265185A9D07b91B5b50Df94f005BF'),
contract('0x8ED9F6343f057870F1DeF47AaE7CD88dfAA049A8'), # StakingRewardsRegistry
]
elif chain.id == Network.Base:
registries = [contract('0xF3885eDe00171997BFadAa98E01E167B53a78Ec5')]
else:
raise UnsupportedNetwork('yearn v2 is not available on this network')

for r in registries[:]:
if hasattr(r, 'releaseRegistry') and "ReleaseRegistryUpdated" in r.topics:
logs = get_logs_asap(str(r), [r.topics["ReleaseRegistryUpdated"]])
# Add all past and present Release Registries
registries.extend({contract(list(event.values())[0]) for event in decode_logs(logs)})
for rr in {list(event.values())[0] for event in decode_logs(logs)}:
registries.append(contract(rr))
logger.debug("release registry %s found for registry %s", rr, r)
return registries

def load_from_ens(self):
Expand Down
14 changes: 2 additions & 12 deletions yearn/yearn.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,11 @@ def __init__(self, load_strategies=True, load_harvests=False, load_transfers=Fal
"ib": yearn.ironbank.Registry(exclude_ib_tvl=exclude_ib_tvl),
"special": yearn.special.Registry(),
}
elif chain.id == Network.Gnosis:
elif chain.id in [Network.Gnosis, Network.Base]:
self.registries = {
"v2": yearn.v2.registry.Registry(watch_events_forever=watch_events_forever),
}
elif chain.id == Network.Fantom:
self.registries = {
"v2": yearn.v2.registry.Registry(watch_events_forever=watch_events_forever),
"ib": yearn.ironbank.Registry(exclude_ib_tvl=exclude_ib_tvl),
}
elif chain.id == Network.Arbitrum:
self.registries = {
"v2": yearn.v2.registry.Registry(watch_events_forever=watch_events_forever),
"ib": yearn.ironbank.Registry(exclude_ib_tvl=exclude_ib_tvl),
}
elif chain.id == Network.Optimism:
elif chain.id in [Network.Fantom, Network.Arbitrum, Network.Optimism]:
self.registries = {
"v2": yearn.v2.registry.Registry(watch_events_forever=watch_events_forever),
"ib": yearn.ironbank.Registry(exclude_ib_tvl=exclude_ib_tvl),
Expand Down

0 comments on commit 5491960

Please sign in to comment.