Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x61197051 | 20203215 | 67 days ago | IN | 0 ETH | 0.00369554 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0xB82A687d...4c8C79777 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
AdapterVault Pendle Adapter
Compiler Version
vyper:0.3.10
Contract Source Code (Vyper language format)
#pragma version 0.3.10 #pragma evm-version cancun """ @title AdapterVault Pendle Adapter @license Copyright 2023, 2024 Biggest Lab Co Ltd, Benjamin Scherrey, Sajal Kayan, and Eike Caldeweyher @author BiggestLab (https://biggestlab.io) Sajal Kayan """ from vyper.interfaces import ERC20 #gas optimization for swap things can be computed offchain struct ApproxParams: guessMin: uint256 #The minimum value for binary search guessMax: uint256 #The maximum value for binary search guessOffchain: uint256 #This is the first answer to be checked before performing any binary search. If the answer already satisfies, we skip the search and save significant gas maxIteration: uint256 #The maximum number of times binary search will be performed eps: uint256 #The precision of binary search - the maximum proportion of the input that can be unused. eps is 1e18-based, so an eps of 1e14 implies that no more than 0.01% of the input might be unused struct SwapData: swapType: uint8 extRouter: address extCalldata: Bytes[100] needScale: bool #Note: "If no aggregator is used, tokenIn = tokenMintSy, pendleSwap = address(0) & swapData is empty" #This should always be the case for us, so in TokenInput and TokenOutput we dont need to care # about pendleSwap and swapData as those would be empty. struct TokenInput: tokenIn: address #Always asset in our case netTokenIn: uint256 #Amount of assets to "deposit" tokenMintSy: address #Should also be asset as we only deal with markets using asset directy pendleSwap: address #Address of swap helper, do not hardcode - empty for us swapData: SwapData #Empty for us struct TokenOutput: tokenOut: address #Always asset in our case minTokenOut: uint256 #Minimum amount of assets to "withdraw" tokenRedeemSy: address #Should also be asset as we only deal with markets using asset directy pendleSwap: address #Address of swap helper, do not hardcode - empty for us swapData: SwapData #Empty for us struct Order: salt: uint256 expiry: uint256 nonce: uint256 orderType: uint8 token: address YT: address maker: address receiver: address makingAmount: uint256 lnImpliedRate: uint256 failSafeRate: uint256 permit: Bytes[100] struct FillOrderParams: order: Order signature: Bytes[100] makingAmount: uint256 struct LimitOrderData: limitRouter: address epsSkipMarket: uint256 normalFills: DynArray[FillOrderParams,1] flashFills: DynArray[FillOrderParams,1] optData: Bytes[100] struct PregenInfo: #13 words, so 416 bytes. Is there need to compress this for l2? future optimization. assumed_asset_amount: uint256 #What asset amount is the below data corresponding to. Doesnt need to be exact mint_returns: uint256 #Expected PT gained when converting assumed_asset_amount to PT using mint method spot_returns: uint256 #Expected PT gained when converting assumed_asset_amount to PT using AMM method approx_params_swapExactYtForPt: ApproxParams #ApproxParams for swapping YT to PT (needed if deposit using mint method) approx_params_swapExactTokenForPt: ApproxParams #ApproxParams for swapping token to PT (needed if deposit using AMM method) interface PendleRouter: #swapExactTokenForPt to swap asset to PT using AMM, docs mention there are #bits of the computation that can be done offchan and fed to the call. #Likely look for this in version 2 of the adapter. def swapExactTokenForPt(receiver: address, market: address, minPtOut: uint256, guessPtOut: ApproxParams, input: TokenInput, limit: LimitOrderData) -> (uint256, uint256, uint256): nonpayable #swapExactPtForToken is used for converting PT to asset, typically to #service user withdrawals which would (almost) always occur mid-term def swapExactPtForToken(receiver: address, market: address, exactPtIn: uint256, output: TokenOutput, limit: LimitOrderData) -> (uint256, uint256, uint256) : nonpayable #RedeemPyToToken: PY stands for PT and YT. However, you no longer need YT post-expiry to redeem. #PEGGED: We would use this to redeem all outstanding PT to asset at end of term def redeemPyToToken(receiver: address, YT: address, netPyIn: uint256, output: TokenOutput) -> (uint256, uint256): nonpayable #PEGGED minting def mintPyFromToken(receiver: address, YT: address, minPyOut: uint256, input: TokenInput) -> (uint256, uint256): nonpayable #swapExactYtForPt to sell intermidiate YT minted for PT def swapExactYtForPt(receiver: address, market: address, exactYtIn: uint256, minPtOut: uint256, guessTotalPtFromSwap: ApproxParams) -> (uint256, uint256): nonpayable interface PendleRouterStatic: def getPtToAssetRate(market: address) -> uint256: view def mintPyFromTokenStatic(YT: address, tokenIn: address, netTokenIn: uint256) -> uint256: view def swapExactYtForPtStatic(market: address, exactYtIn: uint256) -> (uint256, uint256, uint256, uint256, uint256): view def swapExactTokenForPtStatic(market: address, tokenIn: address, netTokenIn: uint256) -> (uint256, uint256, uint256, uint256, uint256): view interface PendleMarket: def readTokens() -> (address, address, address): view def expiry() -> uint256: view #NOTE: Currently markets checked have 1 reward token. If there is more please update the limit below def getRewardTokens() -> DynArray[address, 20]: view def redeemRewards(user: address) -> DynArray[uint256, 20]: nonpayable interface SYToken: def previewDeposit(tokenIn: address, amountTokenToDeposit: uint256) -> uint256: view def previewRedeem(tokenOut: address, amountSharesToRedeem: uint256) -> uint256: view def exchangeRate() -> uint256: view def deposit(receiver: address, tokenIn: address, amountTokenToDeposit: uint256, minSharesOut: uint256) -> uint256: nonpayable interface YieldToken: def pyIndexStored() -> uint256: view def doCacheIndexSameBlock() -> bool: view def pyIndexLastUpdatedBlock() -> uint128: view interface PendlePtLpOracle: def getPtToAssetRate(market: address, duration: uint32) -> uint256: view def getPtToSyRate(market: address, duration: uint32) -> uint256: view def getOracleState(market: address, duration: uint32) -> (bool, uint16, bool): nonpayable ONE: constant(uint256) = 10**18 TWAP_DURATION: constant(uint32) = 1200 asset: immutable(address) pendleRouter: immutable(address) pendleRouterStatic: immutable(address) pendleMarket: immutable(address) pendleOracle: immutable(address) pt_token: immutable(address) yt_token: immutable(address) sy_token: immutable(address) adapterAddr: immutable(address) #Its immutable in pendle so we cache it here for cheaper access expiry: immutable(uint256) @external def __init__( _asset: address, _pendleRouter: address, _pendleRouterStatic: address, _pendleMarket: address, _pendleOracle: address ): _sy: address = empty(address) _pt: address = empty(address) _yt: address = empty(address) _sy, _pt, _yt = PendleMarket(_pendleMarket).readTokens() sy_token = _sy pt_token = _pt yt_token = _yt asset = _asset pendleOracle = _pendleOracle pendleRouter = _pendleRouter pendleRouterStatic = _pendleRouterStatic pendleMarket = _pendleMarket adapterAddr = self expiry = PendleMarket(_pendleMarket).expiry() #Check oracle's cardinality increaseCardinalityRequired: bool= False cardinalityRequired: uint16 = 0 oldestObservationSatisfied: bool = False increaseCardinalityRequired, cardinalityRequired, oldestObservationSatisfied = PendlePtLpOracle(pendleOracle).getOracleState(pendleMarket, TWAP_DURATION) assert increaseCardinalityRequired == False, "Oracle requires cardinality increase" assert oldestObservationSatisfied == True, "Oracle is not bootstrapped sufficiently" #Workaround because vyper does not allow doing delegatecall from inside view. #we do a static call instead, but need to fix the correct vault location for queries. @internal @view def vault_location() -> address: if self == adapterAddr: #if "self" is adapter, meaning this is not delegate call and we treat msg.sender as the vault return msg.sender #Otherwise we are inside DELEGATECALL, therefore self would be the 4626 return self @internal @view def asset_to_sy(asset_amount: uint256) -> uint256: #How much SY does given asset amount mint return SYToken(sy_token).previewDeposit(asset, asset_amount) @internal @view def sy_to_asset(sy_amount: uint256) -> uint256: #How much SY does given asset amount mint return SYToken(sy_token).previewRedeem(asset, sy_amount) @internal @view def assetToPT(asset_amount: uint256) -> uint256: if asset_amount == 0: #optimization for empty adapter return 0 sy_amount: uint256 = self.asset_to_sy(asset_amount) rate: uint256 = PendlePtLpOracle(pendleOracle).getPtToSyRate(pendleMarket, TWAP_DURATION) pt: uint256 = (sy_amount * ONE) / rate return pt @internal @view def PTToAsset(pt: uint256) -> uint256: if pt == 0 : #optimization for empty adapter return 0 rate: uint256 = PendlePtLpOracle(pendleOracle).getPtToSyRate(pendleMarket, TWAP_DURATION) sy_amount: uint256 = (pt * rate) / ONE return self.sy_to_asset(sy_amount) @internal @view def is_matured() -> bool: #upstream solidity logic: return (expiry <= block.timestamp); return expiry <= block.timestamp @internal @view def _assetBalance() -> uint256: wrappedBalance: uint256 = ERC20(pt_token).balanceOf(self.vault_location()) #aToken unWrappedBalance: uint256 = self.PTToAsset(wrappedBalance) #asset return unWrappedBalance #How much asset can be withdrawn in a single transaction @external @view def maxWithdraw() -> uint256: """ @notice returns the maximum possible asset amount thats withdrawable from Pendle @dev In case of pendle, all markets allow withdrawals... """ #Should we check for funds availability in the AMM? return self._assetBalance() #How much asset can be deposited in a single transaction @external @view def maxDeposit() -> uint256: """ @notice returns the maximum possible asset amount thats depositable into AAVE @dev So for Pendle, we would use zero if the market is matured or if its not active. Otherwise we send max uint """ if self.is_matured(): return 0 return max_value(uint256) #How much asset this LP is responsible for. @external @view def totalAssets() -> uint256: """ @notice returns the balance currently held by the adapter. @dev This method returns a valid response if it has been DELEGATECALL or STATICCALL-ed from the AdapterVault contract it services. It is not intended to be called directly by third parties. """ return self._assetBalance() @internal @view def estimate_spot_returns(asset_amount: uint256) -> uint256: """ @notice estimates the PT amount returned if we based calculation on spot price alone, ignoring any slippage. """ # rate: uint256 = PendleRouterStatic(pendleRouterStatic).getPtToAssetRate(pendleMarket) netPtOut: uint256 = 0 netSyMinted: uint256 = 0 netSyFee: uint256 = 0 priceImpact: uint256 = 0 exchangeRateAfter: uint256 = 0 netPtOut, netSyMinted, netSyFee, priceImpact, exchangeRateAfter = PendleRouterStatic(pendleRouterStatic).swapExactTokenForPtStatic(pendleMarket, asset, asset_amount) return netPtOut @internal @view def estimate_mint_returns(asset_amount: uint256) -> (uint256, uint256): """ @notice estimates the PT amount returned if we based calculation on minting PY and then swapping the returned YT for PT. """ if self.is_matured(): #Not possible to mint after maturity return 0, 0 #estimate asset to PY py_amount: uint256 = PendleRouterStatic(pendleRouterStatic).mintPyFromTokenStatic(yt_token, asset, asset_amount) #Estimate cost of YT to PT netPtOut: uint256 = 0 totalPtSwapped: uint256 = 0 netSyFee: uint256 = 0 priceImpact: uint256 = 0 exchangeRateAfter: uint256 = 0 netPtOut, totalPtSwapped, netSyFee, priceImpact, exchangeRateAfter = PendleRouterStatic(pendleRouterStatic).swapExactYtForPtStatic(pendleMarket, py_amount) return (py_amount + netPtOut), totalPtSwapped #Deposit the asset into underlying LP @external @nonpayable def deposit(asset_amount: uint256, pregen_info: Bytes[4096]=empty(Bytes[4096])): """ @notice deposit asset into Pendle market. @param asset_amount The amount of asset we want to deposit into Pendle market @param pregen_info optional argument of data computed off-chain to optimize the on-chain call @dev This method is only valid if it has been DELEGATECALL-ed from the AdapterVault contract it services. It is not intended to be called directly by third parties. """ pg: PregenInfo = empty(PregenInfo) if len(pregen_info) > 0: pg = _abi_decode(pregen_info, PregenInfo) else: #Info not provided, compute it expensively pg.approx_params_swapExactYtForPt = self.default_approx_params() pg.approx_params_swapExactTokenForPt = self.default_approx_params() ytToPTL: uint256 = 0 pg.mint_returns, ytToPTL = self.estimate_mint_returns(asset_amount) pg.spot_returns = self.estimate_spot_returns(asset_amount) #we already paid the tax... why not reuse it... pg.approx_params_swapExactTokenForPt.guessOffchain = pg.spot_returns pg.approx_params_swapExactYtForPt.guessOffchain = ytToPTL #mint if minting price is better, then sell the YT. if pg.mint_returns > pg.spot_returns: #Mint PY inp: TokenInput = empty(TokenInput) inp.tokenIn = asset inp.netTokenIn = asset_amount inp.tokenMintSy = asset netPyOut: uint256 = 0 netSyInterm: uint256 = 0 ERC20(asset).approve(pendleRouter, asset_amount) #Mint PY+PT using asset netPyOut, netSyInterm = PendleRouter(pendleRouter).mintPyFromToken( self, yt_token, 0, inp ) #Swap any YT gained to PT ERC20(yt_token).approve(pendleRouter, netPyOut) PendleRouter(pendleRouter).swapExactYtForPt( self, pendleMarket, netPyOut, 0, pg.approx_params_swapExactYtForPt ) else: #swapExactTokenForPt inp: TokenInput = empty(TokenInput) inp.tokenIn = asset inp.netTokenIn = asset_amount inp.tokenMintSy = asset limit: LimitOrderData = empty(LimitOrderData) ERC20(asset).approve(pendleRouter, asset_amount) PendleRouter(pendleRouter).swapExactTokenForPt( self, pendleMarket, 0, pg.approx_params_swapExactTokenForPt, inp, limit ) #NOTE: Not doing any checks and balances, minPtOut=0 is intentional. #It's up to the vault to revert if it does not like what it sees. #Withdraw the asset from the LP @external @nonpayable def withdraw(asset_amount: uint256 , withdraw_to: address, pregen_info: Bytes[4096]=empty(Bytes[4096])) -> uint256: """ @notice withdraw asset from AAVE. @param asset_amount The amount of asset we want to withdraw from Pendle @param withdraw_to The ultimate reciepent of the withdrawn assets @param pregen_info optional argument of data computed off-chain to optimize the on-chain call @dev This method is only valid if it has been DELEGATECALL-ed from the AdapterVault contract it services. It is not intended to be called directly by third parties. """ #NOTE: accepting pregen_info to satisfy the interface, but there is no need for #it during withdraw, unless we find an alternate withdrawal method. #Compute the amount of PT we must consume based on oracle pt_amount: uint256 = self.assetToPT(asset_amount) amount_withdrawn: uint256 = 0 if self.is_matured(): #redeemPyToToken #No positive slippage possible as we assume 1:1 peg ERC20(pt_token).approve(pendleRouter, pt_amount) out: TokenOutput = empty(TokenOutput) out.tokenOut = asset out.minTokenOut = 0 #remember slippage protection is by the vault out.tokenRedeemSy = asset netTokenOut: uint256 = 0 netSyInterm: uint256 = 0 netTokenOut, netSyInterm = PendleRouter(pendleRouter).redeemPyToToken(withdraw_to, yt_token, pt_amount, out) amount_withdrawn = netTokenOut else: #swapExactPtForToken #For now we so swapExactPtForToken to the vault, and then keep the positive yield as asset. #Would have liked the positive slippage remain as PT... ERC20(pt_token).approve(pendleRouter, pt_amount) out: TokenOutput = empty(TokenOutput) out.tokenOut = asset out.minTokenOut = 0 #remember slippage protection is by the vault out.tokenRedeemSy = asset limit: LimitOrderData = empty(LimitOrderData) #positive yield needs to goto the vault, check note above for optimization netTokenOut: uint256 = 0 netSyFee: uint256 = 0 netSyInterm: uint256 = 0 netTokenOut, netSyFee, netSyInterm = PendleRouter(pendleRouter).swapExactPtForToken(self, pendleMarket, pt_amount, out, limit) if netTokenOut > asset_amount: #Excess remains in vault as asset amount_withdrawn = asset_amount else: #Any slippage from oracle is users responsibility amount_withdrawn = netTokenOut if withdraw_to != self: ERC20(asset).transfer(withdraw_to, amount_withdrawn) return amount_withdrawn @external def claimRewards(claimant: address): """ @notice hook to claim reward from underlying LP @param claimant An address who is to be the ultimate beneficiary of any tokens claimed @dev runs the IPMarket.redeemRewards method, and sends the loot to provided address """ PendleMarket(pendleMarket).redeemRewards(self) tokens: DynArray[address, 20] = PendleMarket(pendleMarket).getRewardTokens() for token in tokens: if token == pt_token: #if its really rewarded in pt, let the vault have that continue #Assumes reward token is ERC20 vault_balance: uint256 = ERC20(token).balanceOf(self) if vault_balance > 0: #A misbehaving token could potentially re-enter here, but #there is no harm as we are within the claim call, not touching #any vault logic ERC20(token).transfer(claimant, vault_balance) @internal @pure def default_approx_params() -> ApproxParams: ap: ApproxParams = empty(ApproxParams) ap.guessMax = max_value(uint256) ap.maxIteration = 256 ap.eps = 10**14 return ap @external @view def abi_helper() -> PregenInfo: """ @notice This is just here so the PregenInfo struct is visible in ABI """ return empty(PregenInfo) @external @view def generate_pregen_info(asset_amount: uint256) -> Bytes[4096]: """ @notice retuns byte data to be precomputed in an off-chain call which is to be included during on-chain call. Optimize gas costs. @param asset_amount The asset amount that is expected to be deposited or withdrawn """ #Under ideal situation, we pendle's hosted API to get better paramaters and inject here pg: PregenInfo = empty(PregenInfo) #Because we assume (approx) all asset amount will either go in or out of single adapter pg.assumed_asset_amount = asset_amount ytToPT: uint256 = 0 pg.mint_returns, ytToPT = self.estimate_mint_returns(asset_amount) pg.spot_returns = self.estimate_spot_returns(asset_amount) #Not having approx params costs additional 180k gas (source: https://github.com/pendle-finance/pendle-examples-public/blob/9ce43f4d16003a3ea2a9fe3050e637f0fed64fee/src/StructGen.sol#L14) #Check with pendle about guidance on how this precompute works, maybe need to use their REST API #Hardcoding defaults pg.approx_params_swapExactYtForPt = self.default_approx_params() pg.approx_params_swapExactTokenForPt = self.default_approx_params() pg.approx_params_swapExactYtForPt.guessOffchain = ytToPT pg.approx_params_swapExactTokenForPt.guessOffchain = pg.spot_returns return _abi_encode(pg) @external @view def managed_tokens() -> DynArray[address, 10]: ret: DynArray[address, 10] = empty(DynArray[address, 10]) ret.append(pt_token) return ret
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_asset","type":"address"},{"name":"_pendleRouter","type":"address"},{"name":"_pendleRouterStatic","type":"address"},{"name":"_pendleMarket","type":"address"},{"name":"_pendleOracle","type":"address"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"maxWithdraw","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"maxDeposit","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"totalAssets","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"deposit","inputs":[{"name":"asset_amount","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"deposit","inputs":[{"name":"asset_amount","type":"uint256"},{"name":"pregen_info","type":"bytes"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"asset_amount","type":"uint256"},{"name":"withdraw_to","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"asset_amount","type":"uint256"},{"name":"withdraw_to","type":"address"},{"name":"pregen_info","type":"bytes"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"claimRewards","inputs":[{"name":"claimant","type":"address"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"abi_helper","inputs":[],"outputs":[{"name":"","type":"tuple","components":[{"name":"assumed_asset_amount","type":"uint256"},{"name":"mint_returns","type":"uint256"},{"name":"spot_returns","type":"uint256"},{"name":"approx_params_swapExactYtForPt","type":"tuple","components":[{"name":"guessMin","type":"uint256"},{"name":"guessMax","type":"uint256"},{"name":"guessOffchain","type":"uint256"},{"name":"maxIteration","type":"uint256"},{"name":"eps","type":"uint256"}]},{"name":"approx_params_swapExactTokenForPt","type":"tuple","components":[{"name":"guessMin","type":"uint256"},{"name":"guessMax","type":"uint256"},{"name":"guessOffchain","type":"uint256"},{"name":"maxIteration","type":"uint256"},{"name":"eps","type":"uint256"}]}]}]},{"stateMutability":"view","type":"function","name":"generate_pregen_info","inputs":[{"name":"asset_amount","type":"uint256"}],"outputs":[{"name":"","type":"bytes"}]},{"stateMutability":"view","type":"function","name":"managed_tokens","inputs":[],"outputs":[{"name":"","type":"address[]"}]}]
Deployed Bytecode
0x5f3560e01c60026009820660011b61183e01601e395f51565b63ac7a1b5b811861003a573461183a5760206100356101e06115f9565b6101e0f35b63cff54c8e81186113dd573461183a576101a0366040376101a06040f36113dd565b636083e59a81186100b6573461183a5761007660406115e8565b6040511561008b575f606052602060606100b4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff604052602060405bf35b6362b2b5f081186113dd5760843610341761183a5760443560040161100081351161183a57602081350180826101a03750505b6024358060a01c61183a576101805260043560c0526101096111e0611490565b6111e0516111c0525f6111e0526101216112006115e8565b6112005161066d5760206118f05f395f5163095ea7b3611200526020611870611220396111c051611240526020611200604461121c5f855af1610166573d5f5f3e3d5ffd5b60203d1061183a57611200518060011c61183a5761126052611260505061018036611200376020611850611200395f61122052602061185061124039610700366113803760206118705f395f5163594a88cc611a805260a030611aa05260206118b0611ac0396111c051611ae05280611b005280611aa00160a061120051825261122051602083015261124051604083015261126051606083015280608083015280820160806112805182526112a051602083015280604083015280820160206112c05101806112c0835e508051806020830101601f825f03163682375050601f19601f8251602001011690508101905061136051606083015290508101905090508101905080611b205280611aa00160a06113805182526113a05160208301528060408301528082015f6113c0518083528060051b5f826001811161183a5780156103e457905b828160051b6020880101526102c081026113e0018360208801016060808252808201610180845182526020850151602083015260408501516040830152606085015160608301526080850151608083015260a085015160a083015260c085015160c083015260e085015160e083015261010085015161010083015261012085015161012083015261014085015161014083015280610160830152610160850181830160208251018083835e508051806020830101601f825f03163682375050601f19601f825160200101169050905081019050905081019050806020830152610200830181830160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506102a0830151604083015290509050830192506001018181186102ae575b505082016020019150509050810190508060608301528082015f6116a0518083528060051b5f826001811161183a57801561055157905b828160051b6020880101526102c081026116c0018360208801016060808252808201610180845182526020850151602083015260408501516040830152606085015160608301526080850151608083015260a085015160a083015260c085015160c083015260e085015160e083015261010085015161010083015261012085015161012083015261014085015161014083015280610160830152610160850181830160208251018083835e508051806020830101601f825f03163682375050601f19601f825160200101169050905081019050905081019050806020830152610200830181830160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506102a08301516040830152905090508301925060010181811861041b575b505082016020019150509050810190508060808301528082016020611980510180611980835e508051806020830101601f825f03163682375050601f19601f825160200101169050810190509050810150506060611a80610a64611a9c5f855af16105be573d5f5f3e3d5ffd5b60603d1061183a57611a8090508051611a20526020810151611a40526040810151611a605250600435611a2051116105fd57611a20516111e052610605565b6004356111e0525b3061018051146107f35760206118505f395f5163a9059cbb611a805261018051611aa0526111e051611ac0526020611a806044611a9c5f855af161064b573d5f5f3e3d5ffd5b60203d1061183a57611a80518060011c61183a57611ae052611ae050506107f3565b60206118f05f395f5163095ea7b3611220526020611870611240396111c051611260526020611220604461123c5f855af16106aa573d5f5f3e3d5ffd5b60203d1061183a57611220518060011c61183a5761128052611280505061018036611220376020611850611220395f611240526020611850611260396040366113a03760206118705f395f516347f1de226113e052608061018051611400526020611910611420396111c051611440528061146052806114000160a061122051825261124051602083015261126051604083015261128051606083015280608083015280820160806112a05182526112c051602083015280604083015280820160206112e05101806112e0835e508051806020830101601f825f03163682375050601f19601f8251602001011690508101905061138051606083015290508101905090508101505060406113e06102446113fc5f855af16107cd573d5f5f3e3d5ffd5b60403d1061183a576113e0905080516113a05260208101516113c052506113a0516111e0525b60206111e0f36113dd565b6301e1d1148118610820573461183a57602061081b6101e06115f9565b6101e0f35b63ef5cfb8c8118610a1d5760243610341761183a576004358060a01c61183a5760405260206118b05f395f51639262187b606052306080526102c060606024607c5f855af1610871573d5f5f3e3d5ffd5b60403d1061183a57606051606001601481511161183a57805160208160051b0180836103405e505050610340505060206118b05f395f5163c4f59f9b610300526102c0610300600461031c845afa6108cb573d5f5f3e3d5ffd5b60403d1061183a576103005161030001601481511161183a5780515f816014811161183a57801561091e57905b8060051b6020850101518060a01c61183a578160051b61060001526001018181186108f8575b5050806105e05250506105e09050805160208160051b01808360605e5050505f6060516014811161183a578015610a1957905b8060051b608001516103005260206118f05f395f51610300511861097457610a0e565b610300516370a082316103405230610360526020610340602461035c845afa61099f573d5f5f3e3d5ffd5b60203d1061183a57610340905051610320526103205115610a0e576103005163a9059cbb610340526040516103605261032051610380526020610340604461035c5f855af16109f0573d5f5f3e3d5ffd5b60203d1061183a57610340518060011c61183a576103a0526103a050505b600101818118610951575b5050005b63c7773e0081146003361116156113dd5760243610341761183a576101a0366101e0376004356101e0525f61038052600435604052610a5d6103a06116f1565b6103a080516102005260208101516103805250600435604052610a816103a061166c565b6103a05161022052610a946103a06117f7565b6103a060a0816102405e50610aaa6103a06117f7565b6103a060a0816102e05e5061038051610280526102205161032052602080610560526101a06101e06103c05e6101a06103a0526103a0816105600160208251018083835e508051806020830101601f825f03163682375050601f19601f825160200101169050905081019050610560f36113dd565b63b6b55f2581186113dd5760243610341761183a575f6101e052610b75566113dd565b635d303519811861132c5760643610341761183a5760243560040161100081351161183a57602081350180826101e03750505b6101a036611200376101e05115610bbe576101a06101e0511861183a5760606102006113a05e60a06102606114005e60a06103006114a05e6113a06101a0816112005e50610c3d565b610bc96113a06117f7565b6113a060a0816112605e50610bdf6113a06117f7565b6113a060a0816113005e505f6113a052600435604052610c006113c06116f1565b6113c080516112205260208101516113a05250600435604052610c246113c061166c565b6113c0516112405261124051611340526113a0516112a0525b6112405161122051116110f957610180366113a03760206118506113a0396004356113c05260206118506113e0396106a0366115203760206118505f395f5163095ea7b3611bc0526020611870611be039600435611c00526020611bc06044611bdc5f855af1610caf573d5f5f3e3d5ffd5b60203d1061183a57611bc0518060011c61183a57611c2052611c20505060206118705f395f5163c81f847a611bc05261014030611be05260206118b0611c00395f611c205260a0611300611c405e80611ce05280611be00160a06113a05182526113c05160208301526113e051604083015261140051606083015280608083015280820160806114205182526114405160208301528060408301528082016020611460510180611460835e508051806020830101601f825f03163682375050601f19601f8251602001011690508101905061150051606083015290508101905090508101905080611d005280611be00160a06115205182526115405160208301528060408301528082015f611560518083528060051b5f826001811161183a578015610f0d57905b828160051b6020880101526102c08102611580018360208801016060808252808201610180845182526020850151602083015260408501516040830152606085015160608301526080850151608083015260a085015160a083015260c085015160c083015260e085015160e083015261010085015161010083015261012085015161012083015261014085015161014083015280610160830152610160850181830160208251018083835e508051806020830101601f825f03163682375050601f19601f825160200101169050905081019050905081019050806020830152610200830181830160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506102a083015160408301529050905083019250600101818118610dd7575b505082016020019150509050810190508060608301528082015f611840518083528060051b5f826001811161183a57801561107a57905b828160051b6020880101526102c08102611860018360208801016060808252808201610180845182526020850151602083015260408501516040830152606085015160608301526080850151608083015260a085015160a083015260c085015160c083015260e085015160e083015261010085015161010083015261012085015161012083015261014085015161014083015280610160830152610160850181830160208251018083835e508051806020830101601f825f03163682375050601f19601f825160200101169050905081019050905081019050806020830152610200830181830160208251018083835e508051806020830101601f825f03163682375050601f19601f8251602001011690509050810190506102a083015160408301529050905083019250600101818118610f44575b505082016020019150509050810190508060808301528082016020611b20510180611b20835e508051806020830101601f825f03163682375050601f19601f825160200101169050810190509050810150506060611bc0610b04611bdc5f855af16110e7573d5f5f3e3d5ffd5b60603d1061183a57611bc0505061132a565b610180366113a03760206118506113a0396004356113c05260206118506113e0396040366115203760206118505f395f5163095ea7b3611560526020611870611580396004356115a0526020611560604461157c5f855af161115d573d5f5f3e3d5ffd5b60203d1061183a57611560518060011c61183a576115c0526115c0505060206118705f395f5163d0f42385611560526080306115805260206119106115a0395f6115c052806115e052806115800160a06113a05182526113c05160208301526113e051604083015261140051606083015280608083015280820160806114205182526114405160208301528060408301528082016020611460510180611460835e508051806020830101601f825f03163682375050601f19601f82516020010116905081019050611500516060830152905081019050905081015050604061156061024461157c5f855af1611254573d5f5f3e3d5ffd5b60403d1061183a5761156090508051611520526020810151611540525060206119105f395f5163095ea7b361156052602061187061158039611520516115a0526020611560604461157c5f855af16112ae573d5f5f3e3d5ffd5b60203d1061183a57611560518060011c61183a576115c0526115c0505060206118705f395f5163448b9b9561156052306115805260206118b06115a039611520516115c0525f6115e05260a06112606116005e604061156061012461157c5f855af161131c573d5f5f3e3d5ffd5b60403d1061183a5761156050505b005b63ed21271881186113dd573461183a575f6040526040516009811161183a5760206118f08260051b6060013960018101604052506020806101a052806101a0015f6040518083528060051b5f82600a811161183a5780156113a657905b8060051b606001518160051b602088010152600101818118611389575b505082016020019150509050810190506101a0f36113dd565b62f714ce81186113dd5760443610341761183a575f6101a0526100e9565b5f5ffd5b60206119505f395f5130186113f957338152506113fe565b308152505b565b60206119305f395f5163b8f82b26606052602061185060803960405160a052602060606044607c845afa611436573d5f5f3e3d5ffd5b60203d1061183a576060905051815250565b60206119305f395f5163cbe52ae3606052602061185060803960405160a052602060606044607c845afa61147e573d5f5f3e3d5ffd5b60203d1061183a576060905051815250565b60c0516114a0575f815250611543565b60c0516040526114b1610100611400565b6101005160e05260206118d05f395f5163a31426d16101205260206118b0610140396104b0610160526020610120604461013c845afa6114f3573d5f5f3e3d5ffd5b60203d1061183a576101209050516101005260e051670de0b6b3a7640000810281670de0b6b3a764000082041861183a57905061010051801561183a578082049050905061012052610120518152505b565b60c051611555575f8152506115e6565b60206118d05f395f5163a31426d16101005260206118b0610120396104b0610140526020610100604461011c845afa611590573d5f5f3e3d5ffd5b60203d1061183a5761010090505160e05260c05160e05180820281158383830414171561183a5790509050670de0b6b3a76400008104905061010052610100516040526115de610120611448565b610120518152505b565b4260206119705f395f511115815250565b60206118f05f395f516370a082316101a0526116166101806113e1565b610180516101c05260206101a060246101bc845afa611637573d5f5f3e3d5ffd5b60203d1061183a576101a0905051610160526101605160c05261165b6101a0611545565b6101a0516101805261018051815250565b60a03660603760206118905f395f516326e44ccf6101005260206118b0610120396020611850610140396040516101605260a0610100606461011c845afa6116b6573d5f5f3e3d5ffd5b60a03d1061183a57610100905080516060526020810151608052604081015160a052606081015160c052608081015160e05250606051815250565b6116fb60606115e8565b60605115611712575f81525f6020820152506117f5565b60206118905f395f51635fbdb155608052602061191060a039602061185060c03960405160e052602060806064609c845afa611750573d5f5f3e3d5ffd5b60203d1061183a57608090505160605260a03660803760206118905f395f51633b672dcd6101205260206118b0610140396060516101605260a0610120604461013c845afa6117a1573d5f5f3e3d5ffd5b60a03d1061183a5761012090508051608052602081015160a052604081015160c052606081015160e0526080810151610100525060605160805180820182811061183a5790509050815260a0516020820152505b565b60a0366040377fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60605261010060a052655af3107a400060c05260a06040825e50565b5f80fd0b42001807fe0b1f005c13dd13dd13dd13bf000000000000000000000000fae103dc9cf190ed75350761e95403b7b8afa6c000000000000000000000000000000000005bbb0ef59571e58418f9a4357b68a0000000000000000000000000263833d47ea3fa4a30f269323aba6a107f9eb14c000000000000000000000000038c1b03dab3b891afbca4371ec807edaa3e6eb600000000000000000000000066a1096c6366b2529274df4f5d8247827fe4cea8000000000000000000000000f0574d8b9dc3a9de768eaa7dbb7bb0c68521b148000000000000000000000000d66b560f4e3e85f22c192d91da847886d5c5fd000000000000000000000000007786729eee8b9d30fe7d91fdff23a0f1d0c615d90000000000000000000000000fdc8648c00e749474345458059ac0e9b53989570000000000000000000000000000000000000000000000000000000066f4a400
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.