erc_4626.discovery_base

Documentation for eth_defi.erc_4626.discovery_base Python module.

Events we use in the vault discovery.

  • Shared across RPC/Hypersync discovery

  • Supports standard ERC-4626 Deposit/Withdraw events

  • Supports BrinkVault DepositFunds/WithdrawFunds events

  • Supports EmberVault VaultDeposit/RequestRedeemed events

  • Supports TokenGateway Deposit(5-arg)/RedeemRequested/RedeemTokenGatewayDepreciated events

  • Supports Royco tranche Redeem event

  • Supports Upshift multi-asset Deposit/WithdrawalRequested/WithdrawalProcessed events

  • Supports Atoma WithdrawalClaimed events

  • Supports T3tris flow and vault-configuration events

  • Supports Securitize DSToken Issue events

Module Attributes

DEFAULT_HARDCODED_VAULT_LEAD_SOURCES

Protocol deployments that cannot be discovered from supported vault events.

Functions

add_mellow_factory_candidate_lead(report, ...)

Add a Mellow factory candidate to the shared lead map if new.

create_mellow_potential_vault_match(candidate)

Create a normal lead object from a Mellow factory candidate.

get_atoma_vault_discovery_events(web3)

Get Atoma custom events we use in vault discovery.

get_atoma_vault_event_contract(web3)

Get Atoma vault interface for custom flow events.

get_brink_vault_contract(web3)

Get IBrinkVault interface for BrinkVault events.

get_brink_vault_discovery_events(web3)

Get list of BrinkVault events we use in vault discovery.

get_ember_vault_discovery_events(web3)

Get list of EmberVault events we use in vault discovery.

get_ember_vault_event_contract(web3)

Get IEmberVaultEvents interface for EmberVault events.

get_royco_tranche_discovery_events(web3)

Get Royco tranche events we use in vault discovery.

get_royco_tranche_event_contract(web3)

Get Royco tranche interface for custom redemption events.

get_securitize_dstoken_discovery_events(web3)

Get Securitize DSToken issuance events used for lead discovery.

get_standard_erc_4626_vault_discovery_events(web3)

Get list of standard ERC-4626 events we use in vault discovery.

get_t3tris_vault_configuration_discovery_events(web3)

Get T3tris vault configuration events that can seed a lead.

get_t3tris_vault_discovery_events(web3)

Get T3tris custom events we use in vault discovery.

get_t3tris_vault_event_contract(web3)

Get T3tris vault interface for custom flow events.

get_token_gateway_discovery_events(web3)

Get list of TokenGateway events we use in vault discovery.

get_token_gateway_event_contract(web3)

Get ITokenGatewayEvents interface for TokenGateway events.

get_upshift_multi_asset_discovery_events(web3)

Get Upshift multi-asset events we use in vault discovery.

get_upshift_multi_asset_event_contract(web3)

Get Upshift multi-asset vault interface for custom flow events.

get_vault_discovery_events(web3)

Get all events used in vault discovery, including protocol-specific ones.

get_vault_event_topic_map(web3)

Build a mapping from topic0 signature to event kind.

is_configuration_event(event_kind)

Check if an event kind is vault configuration.

is_deposit_event(event_kind)

Check if the event kind represents a deposit.

is_withdraw_event(event_kind)

Check if the event kind represents a withdrawal.

Classes

LeadScanReport

ERC-4626 vault detection data we extract in one duty cycle.

PotentialVaultMatch

Categorise contracts that emit vault discovery events.

VaultDiscoveryBase

VaultEventKind

Classify vault discovery events by their type.

DEFAULT_HARDCODED_VAULT_LEAD_SOURCES: tuple[tuple[str, tuple[tuple[int, eth_typing.evm.HexAddress, int, datetime.datetime], ...]], ...] = (('ODA-FACT', ((1, '0x09864f52b035ae22ee739dfa5c748fa080d07bd8', 25042223, datetime.datetime(2026, 5, 7, 9, 20, 11)), (1, '0x6a7c6aa2b8b8a6a891de552bdeffa87c3f53bd46', 23890166, datetime.datetime(2025, 11, 27, 12, 52, 11)))), ('Midas', ((1, '0xdd629e5241cbc5919847783e6c96b2de4754e438', 18691255, datetime.datetime(2023, 12, 1, 11, 25, 59)), (1, '0x2a8c22e3b10036f3aef5875d04f8441d4188b656', 20068373, datetime.datetime(2024, 6, 11, 11, 46, 11)), (1, '0x007115416ab6c266329a03b09a8aa39ac2ef7d9d', 20991269, datetime.datetime(2024, 10, 18, 8, 31, 47)), (1, '0xbb51e2a15a9158ebe2b0ceb8678511e063ab7a55', 21665964, datetime.datetime(2025, 1, 20, 13, 20, 35)), (1, '0x030b69280892c888670edcdcd8b69fd8026a0bf3', 21771599, datetime.datetime(2025, 2, 4, 7, 19, 11)), (1, '0x87c9053c819bb28e0d73d33059e1b3da80afb0cf', 21786049, datetime.datetime(2025, 2, 6, 7, 44, 47)), (1, '0x76cc16608aa7cd32631bb151801bb095313f7bbd', 22274978, datetime.datetime(2025, 4, 15, 14, 28, 23)), (1, '0x238a700ed6165261cf8b2e544ba797bc11e466ba', 22437927, datetime.datetime(2025, 5, 8, 9, 27, 23)), (1, '0x9b5528528656dbc094765e2abb79f293c21191b9', 22924118, datetime.datetime(2025, 7, 15, 10, 55, 11)), (1, '0x7cf9dec92ca9fd46f8d86e7798b72624bc116c05', 22924553, datetime.datetime(2025, 7, 15, 12, 22, 35)), (1, '0x841eeb3e2489b2282b0e14202dc8bd8f7624e29a', 22466394, datetime.datetime(2025, 5, 12, 9, 43, 59)), (1, '0x8e2c2c9def45efb9bd3c448945830ddb254154be', 22516836, datetime.datetime(2025, 5, 19, 11, 54, 11)), (1, '0xffa36b4b011d87d89fef3098ab30fef7bcc3571e', 22517088, datetime.datetime(2025, 5, 19, 12, 44, 47)), (1, '0xa48cfd53263ade6abdb0ac75287cc0d5a2eee17f', 22530554, datetime.datetime(2025, 5, 21, 10, 4, 23)), (1, '0xa01227a26a7710bc75071286539e47adb6dea417', 22594324, datetime.datetime(2025, 5, 30, 8, 21, 11)), (1, '0xa1150cd4a014e06f5e0a6ec9453fe0208da5adab', 22594497, datetime.datetime(2025, 5, 30, 8, 55, 59)), (1, '0x6b6b870c7f449266a9f40f94eca5a6ff9b0857e4', 22594563, datetime.datetime(2025, 5, 30, 9, 9, 23)), (1, '0xb64c014307622eb15046c66ff71d04258f5963dc', 22867636, datetime.datetime(2025, 7, 7, 13, 32, 47)), (1, '0xa19f6e0df08a7917f2f8a33db66d0af31ff5eca6', 23073881, datetime.datetime(2025, 8, 5, 9, 11, 11)), (1, '0x20226607b4fa64228abf3072ce561d6257683464', 23232613, datetime.datetime(2025, 8, 27, 12, 59, 35)), (1, '0x2fe058ccf29f123f9dd2aec0418aa66a877d8e50', 23339333, datetime.datetime(2025, 9, 11, 10, 50, 47)), (1, '0x766255b53ae70fa39a18aa296f41fab17db6a810', 23269210, datetime.datetime(2025, 9, 1, 15, 34, 35)), (1, '0x513bd45be7643fe6c30c41cd4b327e8e341aaf9a', 23274171, datetime.datetime(2025, 9, 2, 8, 16, 47)), (1, '0x48e284d0729eb1925066307072758d95dbbb49c4', 23274478, datetime.datetime(2025, 9, 2, 9, 18, 47)), (1, '0xc470e9fc12a60f72c543516dc23de1f55c29e3d5', 23274808, datetime.datetime(2025, 9, 2, 10, 25, 11)), (1, '0x9fb442d6b612a6dcd2acc67bb53771ef1d9f661a', 23288661, datetime.datetime(2025, 9, 4, 8, 48, 59)), (1, '0xc344db27feba7f0a881a50f0f702a525a44f2368', 23367405, datetime.datetime(2025, 9, 15, 8, 52, 23)), (1, '0x605a84861ee603e385b01b9048bea6a86118db0a', 23432101, datetime.datetime(2025, 9, 24, 9, 48, 11)), (1, '0x548857309befb6fb6f20a9c5a56c9023d892785b', 23496808, datetime.datetime(2025, 10, 3, 10, 58, 35)), (1, '0x462be06b03641f0880f694ebc82295572837ba53', 25172925, datetime.datetime(2026, 5, 25, 14, 30, 23)), (1, '0x5a42864b14c0c8241ef5ab62dae975b163a2e0c1', 23547132, datetime.datetime(2025, 10, 10, 11, 47, 59)), (1, '0xc8495eaff71d3a563b906295fcf2f685b1783085', 23576630, datetime.datetime(2025, 10, 14, 14, 46, 59)), (1, '0x9004b9890d6b901a17f734efe028b1be5bd6cd22', 23675979, datetime.datetime(2025, 10, 28, 12, 40, 11)), (1, '0xe70b5eb021dc3af653d61fd792d8f0b60f36c493', 24083710, datetime.datetime(2025, 12, 24, 16, 35, 35)), (1, '0x67e1f506b148d0fc95a4e3ffb49068ceb6855c05', 24425757, datetime.datetime(2026, 2, 10, 10, 24, 35)), (1, '0xcc5c22c7a6bcc25e66726aef011dde74289ed203', 24534309, datetime.datetime(2026, 2, 25, 13, 44, 35)), (1, '0xad4748098c2a771cc034d7dfc10fad9f9ed605fd', 24849841, datetime.datetime(2026, 4, 10, 14, 11, 59)), (1, '0x0a640e217a3c5579b920f740b556f44b6e9820c5', 24850328, datetime.datetime(2026, 4, 10, 15, 49, 35)), (1, '0x9114650a2b8f8598a6b6aa1cb2837e145f59f9fd', 24869298, datetime.datetime(2026, 4, 13, 7, 16, 23)), (1, '0x827ce7e8e35861d9ac7fe002755767b695a5594a', 25122809, datetime.datetime(2026, 5, 18, 14, 52, 35)), (1, '0x2bf11d2e04bc40daa95c24b8b90ec4f5c57dd326', 25128195, datetime.datetime(2026, 5, 19, 8, 53, 35)), (1, '0x4e72025984424e52838cf8953e2863eff036b67a', 25236860, datetime.datetime(2026, 6, 3, 12, 27, 23)), (1, '0xe68f4e819ad09f2e0e668297cc1a905994808d38', 25286287, datetime.datetime(2026, 6, 10, 9, 55, 35)), (1, '0x5c9e1c4d60dba50a68cbe3b0c1b5731a6fd08af6', 25338248, datetime.datetime(2026, 6, 17, 15, 45, 11)), (1, '0xc462f87f78abdd27b1e41c9ede862275d2c7f36b', 25387099, datetime.datetime(2026, 6, 24, 11, 12, 47)), (42161, '0xdd629e5241cbc5919847783e6c96b2de4754e438', 310814679, datetime.datetime(2025, 2, 28, 14, 44, 25)), (42161, '0x2448cf256192ee8e122e52026758ae28398afb4f', 310831851, datetime.datetime(2025, 2, 28, 15, 55, 55)), (42161, '0x130f99c2396e02dbaaa4c1643b10e06ecfe7edab', 311756173, datetime.datetime(2025, 3, 3, 8, 39, 59)), (42161, '0xecacb5434f05a548faf92a31874e0c014beeee91', 311756840, datetime.datetime(2025, 3, 3, 8, 42, 45)), (42161, '0x27329b57666413b84dcb872fe611edbfe9a1a9ad', 311757192, datetime.datetime(2025, 3, 3, 8, 44, 13)), (8453, '0xdd629e5241cbc5919847783e6c96b2de4754e438', 19975742, datetime.datetime(2024, 9, 19, 10, 13, 51)), (8453, '0x1c2757c1fef1038428b5bef062495ce94bbe92b2', 21444525, datetime.datetime(2024, 10, 23, 10, 13, 17)), (8453, '0x4089dc8b6637218f13465d28950a82a7e90cbe27', 26499551, datetime.datetime(2025, 2, 17, 10, 34, 9)), (8453, '0x141f0e9ed8ba2295254c9df9476cce7bc29172b1', 26500311, datetime.datetime(2025, 2, 17, 10, 59, 29)), (8453, '0x34bdda6beb128130158811e5b881da67902325b2', 29566149, datetime.datetime(2025, 4, 29, 10, 14, 5)), (8453, '0x6b35f2e4c9d4c1da0edaf7fd7dc90d9bca4b0873', 30256530, datetime.datetime(2025, 5, 15, 9, 46, 47)), (8453, '0xccbad2823328bccaea6476df3aa529316ab7474a', 37775645, datetime.datetime(2025, 11, 5, 11, 3, 57)), (999, '0x5e105266db42f78fa814322bce7f388b4c2e61eb', 3270801, datetime.datetime(2025, 5, 2, 10, 28, 32)), (999, '0x6eb6724d8d3d4ff9e24d872e8c38403169dc05f8', 5474555, datetime.datetime(2025, 6, 11, 8, 27, 34)), (999, '0x81e064d0eb539de7c3170edf38c1a42cbd752a76', 8115617, datetime.datetime(2025, 7, 11, 10, 25)), (999, '0x441794d6a8f9a3739f5d4e98a728937b33489d29', 8725211, datetime.datetime(2025, 7, 18, 9, 3)), (999, '0x057ced81348d57aad579a672d521d7b4396e8a61', 10226740, datetime.datetime(2025, 8, 4, 12, 29)), (999, '0xd66d69c288d9a6fd735d7be8b2e389970fc4fd42', 10921614, datetime.datetime(2025, 8, 12, 10, 23)), (999, '0x949a7250bb55eb79bc6bcc97fcd1c473db3e6f29', 11445176, datetime.datetime(2025, 8, 18, 9, 28)), (999, '0x8858a307a85982c2b3cb2ace1720237f2f09c39b', 12423459, datetime.datetime(2025, 8, 29, 12, 57)), (999, '0xb39c200d3094c05e048a8f13b69a221db56d012a', 13375947, datetime.datetime(2025, 9, 9, 9, 14)), (999, '0xd385ba55a22ac732cf435c5b5c3a1dfe5939ba4d', 12955859, datetime.datetime(2025, 9, 4, 14, 26)), (999, '0xaf801b65239b4de90f73e26f9bd1260943a5e248', 13017103, datetime.datetime(2025, 9, 5, 7, 10)), (999, '0x61896940f60a536f1d3dae9580524542d58d3683', 13021617, datetime.datetime(2025, 9, 5, 8, 24)), (999, '0x27bfb8d29af693865e3926e752b2f56c7a33a2a8', 15223761, datetime.datetime(2025, 9, 30, 10, 10)), (999, '0x2540bddc5e854419496192688e8257c5ded7ad78', 15226933, datetime.datetime(2025, 9, 30, 11, 2)), (999, '0x80cae1bb1b90980148c5bc9c5701b69fafe7d6b2', 15230410, datetime.datetime(2025, 9, 30, 11, 59)), (999, '0x94bf32bd7de56e80778530919292beff503ec9e6', 15403040, datetime.datetime(2025, 10, 2, 11, 9)), (747474, '0xc6135d59f8d10c9c035963ce9037b3635170d716', 4540503, datetime.datetime(2025, 6, 30, 11, 35, 14)), (747474, '0x184cfda782ce61366010cab23294fb22fa6189f5', 9366730, datetime.datetime(2025, 8, 25, 8, 12, 21)), (747474, '0x926a8a63fa1e1fdbbeb811a0319933b1a0f1edbb', 22684661, datetime.datetime(2026, 1, 26, 11, 37, 52)), (239, '0x0a72ed3c34352ab2dd912b30f2252638c873d6f0', 12121424, datetime.datetime(2026, 1, 8, 10, 29, 38)), (239, '0x06a317991f2f479a6213278b32d17a126fcab501', 6292451, datetime.datetime(2025, 9, 26, 11, 14, 55)), (9745, '0xf91c31299e998c5127bc5f11e4a657fc0cf358cd', 2210548, datetime.datetime(2025, 9, 29, 9, 55, 30)), (9745, '0x616185600989bf8339b58ac9e539d49536598343', 2213033, datetime.datetime(2025, 9, 29, 10, 36, 55)), (9745, '0xb31bea5c2a43f942a3800558b1aa25978da75f8a', 2828525, datetime.datetime(2025, 10, 6, 13, 35, 7)), (56, '0xc8739fbbd54c587a2ad43b50cbcc30ae34fe9e34', 63687212, datetime.datetime(2025, 10, 6, 15, 32, 6)), (56, '0x762fd99ee22742deecb8eecb12165752d9a18164', 64016550, datetime.datetime(2025, 10, 9, 12, 10, 43)), (143, '0x1c8ee940b654bfced403f2a44c1603d5be0f50fa', 41557850, datetime.datetime(2025, 12, 12, 13, 16, 35)), (143, '0xd90f6bfed23ffde40106fc4498dd2e9edb95e4e7', 48387891, datetime.datetime(2026, 1, 13, 6, 43, 5)), (143, '0xf7cf282ec810fded974f99c0163e792f432892bc', 61813077, datetime.datetime(2026, 3, 16, 13, 57, 2)), (10, '0xe7ba07519dfa06e60059563f484d6090dedf21b3', 149716831, datetime.datetime(2026, 4, 1, 8, 33, 59)), (10, '0xcc476b1a49bcdf5192561e87b6fb8ea78aa28c13', 149935744, datetime.datetime(2026, 4, 6, 10, 11, 5)), (10, '0xca5921df65e2e1b0b98ae91c0187ba80d4124898', 149938537, datetime.datetime(2026, 4, 6, 11, 44, 11)), (10, '0x17bc8ffd82b8a36e737ca1141c025089589b915e', 152185362, datetime.datetime(2026, 5, 28, 11, 58, 21)))), ('Fidelity FDIT', ((1, '0x48ab4e39ac59f4e88974804b04a991b3a402717f', 22588721, datetime.datetime(2025, 5, 29, 13, 31, 35)),)), ('KAIO', ((1, '0x42975aae7a124257e7fda7f5e8382f51449b784a', 22347365, datetime.datetime(2025, 4, 25, 16, 55, 59)),)), ('OpenEden', ((1, '0xdd50c053c096cb04a3e3362e2b622529ec5f2e8a', 18376020, datetime.datetime(2023, 10, 18, 8, 21, 47)),)), ('wstGBP', ((1, '0x57c3571f10767e49c9d7b60feb6c67804783b7ae', 24852292, datetime.datetime(2026, 4, 10, 22, 24, 23)),)), ('Vault Street', ((1, '0x7ea76108975ec0998b9bc2db04b4eca986400dd7', 25293536, datetime.datetime(2026, 6, 11, 10, 11, 47)),)), ('Ondo', ((1, '0x96f6ef951840721adbf46ac996b59e0235cb985c', 17672244, datetime.datetime(2023, 7, 11, 18, 46, 23)), (1, '0x1b19c19393e2d034d8ff31ff34c81252fcbbee92', 16234210, datetime.datetime(2022, 12, 21, 16, 16, 23)))), ('Circle USYC', ((1, '0x136471a34f6ef19fe571effc1ca711fdb8e49f2b', 17381914, datetime.datetime(2023, 5, 31, 22, 48, 59)),)), ('Franklin Templeton', ((1, '0x90276e9d4a023b5229e0c2e9d4b2a83fe3a2b48c', 22118491, datetime.datetime(2025, 3, 24, 18, 15, 35)), (1, '0x3ddc84940ab509c11b20b76b466933f40b750dc9', 20587120, datetime.datetime(2024, 8, 22, 22, 25, 47)))), ('Centrifuge Tranche', ((1, '0x8c213ee79581ff4984583c6a801e5263418c4b86', 20460672, datetime.datetime(2024, 8, 5, 6, 47, 59)),)), ('WisdomTree', ((1, '0x1fecf3d9d4fee7f2c02917a66028a48c6706c179', 20750716, datetime.datetime(2024, 9, 15, 1, 51, 27)),)), ('Libeara', ((1, '0x85d38585c3ac08268f598282a84b7c0ddfc0d04f', 23038326, datetime.datetime(2025, 7, 31, 6, 34, 35)), (1, '0x237c717df1b60501f8d029d3fe7385fd090df180', 23595754, datetime.datetime(2025, 10, 17, 9, 1, 23)), (1, '0x50293dd8889b931eb3441d2664dce8396640b419', 21469784, datetime.datetime(2024, 12, 24, 3, 55, 23)), (42161, '0xc26af85ede9cc25d449bcebef866bb85afd5d346', 358954981, datetime.datetime(2025, 7, 18, 7, 9, 32)))), ('Spiko', ((1, '0xe4880249745eac5f1ed9d8f7df844792d560e750', 19690265, datetime.datetime(2024, 4, 19, 15, 6, 11)),)), ('Superstate', ((1, '0x43415eb6ff9db7e26a15b704e7a3edce97d31c4e', 18725909, datetime.datetime(2023, 12, 5, 17, 11, 35)),)), ('Sygnum', ((1, '0x54a4fc78431f9201824643e99bec891bb7462a1d', 24972132, datetime.datetime(2026, 4, 27, 2, 19, 35)), (1, '0xf0db6f529581e7f6ebac7a7f6882923c00fc3a66', 24972189, datetime.datetime(2026, 4, 27, 15, 10, 59)))), ('Theo iToken', ((1, '0x5fa487bca6158c64046b2813623e20755091da0b', 22976986, datetime.datetime(2025, 7, 22, 20, 5, 35)),)), ('Nara', ((1, '0x1aa23cdfc941f6b54251c72012a9bfa4bf5394d6', 24983816, datetime.datetime(2026, 4, 29, 6, 1, 47)),)), ('T3tris', ((42161, '0x5684b18275c0830dafb0b3cff595ba1beca926bd', 483858363, datetime.datetime(2026, 7, 14, 18, 57, 55)),)))

Protocol deployments that cannot be discovered from supported vault events.

class VaultEventKind

Bases: enum.Enum

Classify vault discovery events by their type.

deposit = 'deposit'

Deposit-like event (ERC-4626 Deposit or BrinkVault DepositFunds)

withdraw = 'withdraw'

Withdraw-like event (ERC-4626 Withdraw or BrinkVault WithdrawFunds)

configuration = 'configuration'

Vault setup or administrative configuration event.

class PotentialVaultMatch

Bases: object

Categorise contracts that emit vault discovery events.

configuration_count: int

Protocol-specific vault configuration events.

mellow_factory_candidate: MellowFactoryCandidate | None

Mellow Factory.Created metadata when this lead came from a Mellow factory event instead of vault-local deposit/withdraw events.

Mellow Core Vault user flow events are emitted by queue contracts, not by the canonical Vault. Keep this metadata on the normal lead object so the discovery path can still use one lead map and one feature-probe loop.

__init__(chain, address, first_seen_at_block, first_seen_at, deposit_count=0, withdrawal_count=0, configuration_count=0, mellow_factory_candidate=None)
Parameters
Return type

None

get_brink_vault_contract(web3)

Get IBrinkVault interface for BrinkVault events.

get_ember_vault_event_contract(web3)

Get IEmberVaultEvents interface for EmberVault events.

get_token_gateway_event_contract(web3)

Get ITokenGatewayEvents interface for TokenGateway events.

TokenGateway (ForgeYieldsUSDC / fyUSDC) uses non-standard ERC-4626 flow events:

  • Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares, uint256 referralCode) — 5-arg deposit with referral code

  • RedeemRequested(address indexed owner, address indexed receiver, uint256 shares, uint256 assets, uint256 id, uint256 epoch) — async redemption request

  • RedeemTokenGatewayDepreciated(address indexed caller, address indexed receiver, uint256 shares, uint256 assets) — deprecated direct redeem

Etherscan link.

get_royco_tranche_event_contract(web3)

Get Royco tranche interface for custom redemption events.

Royco senior/junior tranche vaults use the standard ERC-4626 Deposit event topic, but do not emit the standard ERC-4626 Withdraw event. Instead, redemptions use:

  • Redeem(address indexed sender, address indexed receiver, (uint256,uint256,uint256) claims, uint256 shares)

Etherscan example.

get_upshift_multi_asset_event_contract(web3)

Get Upshift multi-asset vault interface for custom flow events.

Upshift multiAssetVault contracts can accept multiple deposit assets and therefore do not emit the standard ERC-4626 Deposit(address,address,uint256,uint256) event. Their vault-local deposit event is:

  • Deposit(address assetIn, uint256 amountIn, uint256 shares, address indexed senderAddr, address indexed receiverAddr)

  • WithdrawalRequested(uint256 shares, address indexed holderAddr, address indexed receiverAddr)

  • WithdrawalProcessed(uint256 assetsAmount, address indexed receiverAddr)

The deposit event topic is 0xc436f473cd90c9b4dd731856a14b80f713d384a1688a506d4230140c5b36d5cd. This was observed on Ethereum mainnet Upshift/RockawayX vaults:

Both vault addresses are TransparentUpgradeableProxy contracts whose public explorer ABI exposes only proxy events. We keep this event-only ABI so lead discovery can match the implementation-level log topic emitted at the proxy address without depending on a single implementation address.

get_atoma_vault_event_contract(web3)

Get Atoma vault interface for custom flow events.

Atoma’s Arbitrum vault emits the standard ERC-4626 Deposit event for deposits, but direct withdraw()/redeem() revert with UseRequestWithdrawal. Redemptions use an epoch-based request/claim flow:

  • WithdrawalRequested(address indexed user, uint256 shares, uint256 requestEpoch, uint256 settlementEpoch)

  • WithdrawalClaimed(address indexed user, uint256 indexed epochId, uint256 shares, uint256 assets, uint256 fee)

Verified source: https://arbitrum.blockscout.com/address/0xd4242FD8DE6E3128f0435b52DCe29155098CbBFF Proxy vault: https://arbiscan.io/address/0xCC56410e1a136aF0eCEb7241c6aE394F4d8b581c

get_t3tris_vault_event_contract(web3)

Get T3tris vault interface for custom flow events.

T3tris vaults support the standard ERC-4626 Deposit and Withdraw events in open vault mode. Closed or asynchronous vault mode can instead emit ERC-7540-like request events before any standard claim event appears:

  • DepositRequest(address indexed receiver, address indexed owner, uint256 indexed requestId, address sender, uint256 assets)

  • RedeemRequest(address indexed receiver, address indexed owner, uint256 indexed requestId, address sender, uint256 shares)

ABI source notes: eth_defi/abi/t3tris/README.md.

get_standard_erc_4626_vault_discovery_events(web3)

Get list of standard ERC-4626 events we use in vault discovery.

Note

This returns only standard ERC-4626 events. For all vault events including protocol-specific ones, use get_vault_discovery_events().

Return type

list[Type[web3.contract.contract.ContractEvent]]

get_brink_vault_discovery_events(web3)

Get list of BrinkVault events we use in vault discovery.

BrinkVault uses custom events instead of standard ERC-4626 Deposit/Withdraw:

  • Deposited(address caller, address recipient, uint256 assets, uint256 shares)

  • Withdrawal(address caller, address recipient, uint256 received, uint256 shares)

Return type

list[Type[web3.contract.contract.ContractEvent]]

get_ember_vault_discovery_events(web3)

Get list of EmberVault events we use in vault discovery.

EmberVault uses custom events instead of standard ERC-4626 Deposit/Withdraw:

  • VaultDeposit(address indexed vault, address indexed depositor, address indexed receiver, uint256 amountDeposited, uint256 sharesMinted, uint256 totalShares, uint256 timestamp, uint256 sequenceNumber)

  • RequestRedeemed(address indexed vault, address indexed owner, address indexed receiver, uint256 shares, uint256 estimatedWithdrawAmount, uint256 timestamp, uint256 sequenceNumber)

Return type

list[Type[web3.contract.contract.ContractEvent]]

get_token_gateway_discovery_events(web3)

Get list of TokenGateway events we use in vault discovery.

TokenGateway uses non-standard ERC-4626 flow events:

  • Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares, uint256 referralCode) — deposit with referral code (distinct topic from standard ERC-4626 Deposit)

  • RedeemRequested(address indexed owner, address indexed receiver, uint256 shares, uint256 assets, uint256 id, uint256 epoch) — async redemption request

  • RedeemTokenGatewayDepreciated(address indexed caller, address indexed receiver, uint256 shares, uint256 assets) — deprecated direct redeem

Return type

list[Type[web3.contract.contract.ContractEvent]]

get_royco_tranche_discovery_events(web3)

Get Royco tranche events we use in vault discovery.

Royco tranche vaults are almost ERC-4626:

  • Deposit(address,address,uint256,uint256) matches standard ERC-4626

  • Redeem(address,address,(uint256,uint256,uint256),uint256) replaces the standard Withdraw event

Only the custom redemption event is returned here because the deposit event is already covered by get_standard_erc_4626_vault_discovery_events().

Return type

list[Type[web3.contract.contract.ContractEvent]]

get_upshift_multi_asset_discovery_events(web3)

Get Upshift multi-asset events we use in vault discovery.

Upshift has two vault families relevant for discovery:

  • Older TokenizedAccount/ERC-4626-like vaults, such as Upshift AZT, emit the standard ERC-4626 Deposit/Withdraw topics and are already covered by get_standard_erc_4626_vault_discovery_events().

  • Newer multiAssetVault vaults emit a custom multi-asset Deposit topic because the event needs to include assetIn. Some large vaults have not emitted withdrawal events yet due to lock-up/pre-deposit mechanics, so the deposit event alone must be enough to seed a lead. When withdrawal request/processed events exist, we still scan them to keep the diagnostic redemption counter useful.

Upshift vault API reports Tori Ecosystem Vault as internal_type=multiAssetVault.

Returns

List of Upshift multi-asset event types used for lead discovery.

Return type

list[Type[web3.contract.contract.ContractEvent]]

get_atoma_vault_discovery_events(web3)

Get Atoma custom events we use in vault discovery.

Deposits are covered by the standard ERC-4626 Deposit event. Atoma’s withdrawal flow is asynchronous and emits custom request/claim events.

We only count WithdrawalClaimed as a redemption-like discovery event. Counting both WithdrawalRequested and WithdrawalClaimed would double count completed withdrawals, and would count requested-but-unclaimed shares as redeemed before the USDC payout exists.

Returns

List of Atoma custom event types used for lead discovery.

Return type

list[Type[web3.contract.contract.ContractEvent]]

get_t3tris_vault_discovery_events(web3)

Get T3tris custom events we use in vault discovery.

Standard ERC-4626 Deposit and Withdraw events are already covered by get_standard_erc_4626_vault_discovery_events(). These request events allow the lead scanner to find T3tris vaults that are operating in asynchronous mode before claims emit the standard flow events.

Returns

List of T3tris custom event types used for lead discovery.

Return type

list[type[web3.contract.contract.ContractEvent]]

get_t3tris_vault_configuration_discovery_events(web3)

Get T3tris vault configuration events that can seed a lead.

T3treasuryUpdated is emitted by the reviewed T3tris migration-pool deployment. Its T3tris-specific name makes it a narrower lead signal than generic administration events. The normal feature probes still confirm that the emitting contract is a T3tris vault.

Returns

T3tris vault-local configuration event types usable for discovery.

Return type

list[type[web3.contract.contract.ContractEvent]]

get_securitize_dstoken_discovery_events(web3)

Get Securitize DSToken issuance events used for lead discovery.

DSTokens are non-ERC-4626 security tokens. Their Issue event identifies token issuance and gives the scanner a candidate lead; ABI probes subsequently reject unrelated contracts that happen to emit a similarly shaped event. Issuance is not necessarily a cash subscription.

Parameters

web3 – Web3 connection used to construct the event ABI.

Returns

The DSToken Issue event type.

Return type

list[Type[web3.contract.contract.ContractEvent]]

get_vault_discovery_events(web3)

Get all events used in vault discovery, including protocol-specific ones.

This includes: - Standard ERC-4626 Deposit/Withdraw events - BrinkVault DepositFunds/WithdrawFunds events - EmberVault VaultDeposit/RequestRedeemed events - TokenGateway Deposit(5-arg)/RedeemRequested/RedeemTokenGatewayDepreciated events - Royco tranche Redeem event - Upshift multi-asset Deposit/WithdrawalRequested/WithdrawalProcessed events - Atoma WithdrawalClaimed event - T3tris DepositRequest/RedeemRequest and configuration events - Securitize DSToken Issue event

Returns

List of contract event types in order: [ERC4626.Deposit, ERC4626.Withdraw, BrinkVault.Deposited, BrinkVault.Withdrawal,

EmberVault.VaultDeposit, EmberVault.RequestRedeemed, TokenGateway.Deposit, TokenGateway.RedeemRequested, TokenGateway.RedeemTokenGatewayDepreciated, RoycoTranche.Redeem, UpshiftMultiAsset.Deposit, UpshiftMultiAsset.WithdrawalRequested, UpshiftMultiAsset.WithdrawalProcessed, AtomaVault.WithdrawalClaimed, T3trisVault.DepositRequest, T3trisVault.RedeemRequest, T3trisVault.<configuration events>, SecuritizeDSToken.Issue]

Return type

list[Type[web3.contract.contract.ContractEvent]]

get_vault_event_topic_map(web3)

Build a mapping from topic0 signature to event kind.

Used by discovery implementations to classify events.

Returns

Dict mapping topic0 hex string to VaultEventKind

Return type

dict[str, eth_defi.erc_4626.discovery_base.VaultEventKind]

is_deposit_event(event_kind)

Check if the event kind represents a deposit.

Parameters

event_kind (eth_defi.erc_4626.discovery_base.VaultEventKind) –

Return type

bool

is_withdraw_event(event_kind)

Check if the event kind represents a withdrawal.

Parameters

event_kind (eth_defi.erc_4626.discovery_base.VaultEventKind) –

Return type

bool

is_configuration_event(event_kind)

Check if an event kind is vault configuration.

Parameters

event_kind (eth_defi.erc_4626.discovery_base.VaultEventKind) –

Return type

bool

class LeadScanReport

Bases: object

ERC-4626 vault detection data we extract in one duty cycle.

leads: dict[eth_typing.evm.HexAddress, eth_defi.erc_4626.discovery_base.PotentialVaultMatch]

Any vault-like smart contracts

detections: dict[eth_typing.evm.HexAddress, eth_defi.erc_4626.core.ERC4262VaultDetection]

Confirmed ERC-4626 vaults by smart contract probing calls

rows: dict[eth_defi.vault.base.VaultSpec, dict]

Exported vault-data as rows

old_leads: int

Accounting / diagnostics

new_leads: int

Accounting / diagnostics

deposits: int

Accounting / diagnostics

withdrawals: int

Accounting / diagnostics

backend: Optional[eth_defi.erc_4626.discovery_base.VaultDiscoveryBase]

Accounting / diagnostics

start_block: int

Accounting / diagnostics

end_block: int

Accounting / diagnostics

items_scanned: int

Unique candidate addresses submitted to on-chain feature probing

__init__(leads=<factory>, detections=<factory>, rows=<factory>, old_leads=0, new_leads=0, deposits=0, withdrawals=0, backend=None, start_block=0, end_block=0, items_scanned=0)
Parameters
Return type

None

create_mellow_potential_vault_match(candidate)

Create a normal lead object from a Mellow factory candidate.

Parameters

candidate (MellowFactoryCandidate) – Decoded Mellow Factory.Created log.

Returns

Lead compatible with the shared probe_vaults() path.

Return type

eth_defi.erc_4626.discovery_base.PotentialVaultMatch

add_mellow_factory_candidate_lead(report, leads, candidate)

Add a Mellow factory candidate to the shared lead map if new.

Parameters
Return type

None

class VaultDiscoveryBase

Bases: abc.ABC

__init__(max_workers)
Parameters

max_workers (int) –

seed_existing_leads(leads)

Seed existing leads to continue the scan where we were left last time.

Parameters

leads (dict[eth_typing.evm.HexAddress, eth_defi.erc_4626.discovery_base.PotentialVaultMatch]) –

scan_vaults(start_block, end_block, display_progress=True, hardcoded_lead_sources=None)

Scan vaults.

  • Detect vault leads by events using scan_potential_vaults()

  • Then perform multicall probing for each vault smart contract to detect protocol

Parameters
Return type

eth_defi.erc_4626.discovery_base.LeadScanReport