diff --git a/pallets/asset-manager/src/benchmarks.rs b/pallets/asset-manager/src/benchmarks.rs index 148e316e93..20cc94df94 100644 --- a/pallets/asset-manager/src/benchmarks.rs +++ b/pallets/asset-manager/src/benchmarks.rs @@ -16,17 +16,39 @@ #![cfg(feature = "runtime-benchmarks")] -use crate::{Call, Config, Pallet}; -use frame_benchmarking::{benchmarks, impl_benchmark_test_suite}; +use crate::{pallet::LocalAssetIdCreator, Call, Config, DepositBalanceOf, Pallet}; +use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite}; +use frame_support::traits::{Currency, Get}; use frame_system::RawOrigin; use xcm::latest::prelude::*; +///RLocal asset deposit amount +fn min_candidate_stk() -> DepositBalanceOf { + <::LocalAssetDeposit as Get>>::get() +} + +/// Create a funded user. +/// Used for generating the necessary amount for local assets +fn create_funded_user( + string: &'static str, + n: u32, + extra: DepositBalanceOf, +) -> (T::AccountId, DepositBalanceOf) { + const SEED: u32 = 0; + let user = account(string, n, SEED); + let min_reserve_amount = min_candidate_stk::(); + let total = min_reserve_amount + extra; + T::Currency::make_free_balance_be(&user, total); + T::Currency::issue(total); + (user, total) +} + benchmarks! { - // This where clause allows us to create assetTypes - where_clause { where T::AssetType: From } - register_asset { + // This where clause allows us to create ForeignAssetTypes + where_clause { where T::ForeignAssetType: From } + register_foreign_asset { // does not really matter what we register - let asset_type = T::AssetType::default(); + let asset_type = T::ForeignAssetType::default(); let metadata = T::AssetRegistrarMetadata::default(); let amount = 1u32.into(); let asset_id: T::AssetId = asset_type.clone().into(); @@ -40,19 +62,34 @@ benchmarks! { // We make it dependent on the number of existing assets already let x in 5..100; for i in 0..x { - let asset_type: T::AssetType = MultiLocation::new(0, X1(GeneralIndex(i as u128))).into(); + let asset_type: T::ForeignAssetType = MultiLocation::new( + 0, + X1(GeneralIndex(i as u128)) + ).into(); let metadata = T::AssetRegistrarMetadata::default(); let amount = 1u32.into(); - Pallet::::register_asset(RawOrigin::Root.into(), asset_type.clone(), metadata, amount, true)?; + Pallet::::register_foreign_asset( + RawOrigin::Root.into(), + asset_type.clone(), + metadata, + amount, + true + )?; Pallet::::set_asset_units_per_second(RawOrigin::Root.into(), asset_type.clone(), 1, i)?; } // does not really matter what we register, as long as it is different than the previous - let asset_type = T::AssetType::default(); + let asset_type = T::ForeignAssetType::default(); let metadata = T::AssetRegistrarMetadata::default(); let amount = 1u32.into(); let asset_id: T::AssetId = asset_type.clone().into(); - Pallet::::register_asset(RawOrigin::Root.into(), asset_type.clone(), metadata, amount, true)?; + Pallet::::register_foreign_asset( + RawOrigin::Root.into(), + asset_type.clone(), + metadata, + amount, + true + )?; }: _(RawOrigin::Root, asset_type.clone(), 1, x) verify { @@ -64,20 +101,25 @@ benchmarks! { // We make it dependent on the number of existing assets already let x in 5..100; for i in 0..x { - let asset_type: T::AssetType = MultiLocation::new(0, X1(GeneralIndex(i as u128))).into(); + let asset_type: T::ForeignAssetType = MultiLocation::new(0, X1(GeneralIndex(i as u128))).into(); let metadata = T::AssetRegistrarMetadata::default(); let amount = 1u32.into(); - Pallet::::register_asset(RawOrigin::Root.into(), asset_type.clone(), metadata, amount, true)?; + Pallet::::register_foreign_asset( + RawOrigin::Root.into(), + asset_type.clone(), + metadata, + amount, + true + )?; Pallet::::set_asset_units_per_second(RawOrigin::Root.into(), asset_type.clone(), 1, i)?; } - let new_asset_type = T::AssetType::default(); - let asset_type_to_be_changed: T::AssetType = MultiLocation::new( + let new_asset_type = T::ForeignAssetType::default(); + let asset_type_to_be_changed: T::ForeignAssetType = MultiLocation::new( 0, X1(GeneralIndex((x-1) as u128)) ).into(); let asset_id_to_be_changed = asset_type_to_be_changed.into(); - }: _(RawOrigin::Root, asset_id_to_be_changed, new_asset_type.clone(), x) verify { assert_eq!(Pallet::::asset_id_type(asset_id_to_be_changed), Some(new_asset_type.clone())); @@ -89,13 +131,19 @@ benchmarks! { // We make it dependent on the number of existing assets already let x in 5..100; for i in 0..x { - let asset_type: T::AssetType = MultiLocation::new(0, X1(GeneralIndex(i as u128))).into(); + let asset_type: T::ForeignAssetType = MultiLocation::new(0, X1(GeneralIndex(i as u128))).into(); let metadata = T::AssetRegistrarMetadata::default(); let amount = 1u32.into(); - Pallet::::register_asset(RawOrigin::Root.into(), asset_type.clone(), metadata, amount, true)?; + Pallet::::register_foreign_asset( + RawOrigin::Root.into(), + asset_type.clone(), + metadata, + amount, + true + )?; Pallet::::set_asset_units_per_second(RawOrigin::Root.into(), asset_type.clone(), 1, i)?; } - let asset_type_to_be_removed: T::AssetType = MultiLocation::new( + let asset_type_to_be_removed: T::ForeignAssetType = MultiLocation::new( 0, X1(GeneralIndex((x-1) as u128)) ).into(); @@ -106,19 +154,45 @@ benchmarks! { assert_eq!(Pallet::::asset_type_units_per_second(asset_type_to_be_removed), None); } + register_local_asset { + const USER_SEED: u32 = 1; + let (caller, deposit_amount) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let asset_id = T::LocalAssetIdCreator::create_asset_id_from_metadata(0); + let owner: T::AccountId = account("account id", 1u32, 0u32); + let current_local_counter: u128 =Pallet::::local_asset_counter(); + let min_balance: T::Balance = 1u32.into(); + + }: _( + RawOrigin::Root, + caller.clone(), + owner.clone(), + true, + min_balance.clone() + ) + verify { + assert_eq!(Pallet::::local_asset_counter(), current_local_counter+1); + assert!(Pallet::::local_asset_deposit(asset_id).is_some()); + + } remove_existing_asset_type { // We make it dependent on the number of existing assets already // Worst case is we need to remove it from SupportedAAssetsFeePayment too let x in 5..100; for i in 0..x { - let asset_type: T::AssetType = MultiLocation::new(0, X1(GeneralIndex(i as u128))).into(); + let asset_type: T::ForeignAssetType = MultiLocation::new(0, X1(GeneralIndex(i as u128))).into(); let metadata = T::AssetRegistrarMetadata::default(); let amount = 1u32.into(); - Pallet::::register_asset(RawOrigin::Root.into(), asset_type.clone(), metadata, amount, true)?; + Pallet::::register_foreign_asset( + RawOrigin::Root.into(), + asset_type.clone(), + metadata, + amount, + true + )?; Pallet::::set_asset_units_per_second(RawOrigin::Root.into(), asset_type.clone(), 1, i)?; } - let asset_type_to_be_removed: T::AssetType = MultiLocation::new( + let asset_type_to_be_removed: T::ForeignAssetType = MultiLocation::new( 0, X1(GeneralIndex((x-1) as u128)) ).into(); @@ -128,7 +202,6 @@ benchmarks! { assert!(Pallet::::asset_id_type(asset_id).is_none()); assert!(Pallet::::asset_type_units_per_second(&asset_type_to_be_removed).is_none()); assert!(!Pallet::::supported_fee_payment_assets().contains(&asset_type_to_be_removed)); - } } diff --git a/pallets/asset-manager/src/lib.rs b/pallets/asset-manager/src/lib.rs index c4025cb6d7..40a95173bd 100644 --- a/pallets/asset-manager/src/lib.rs +++ b/pallets/asset-manager/src/lib.rs @@ -19,18 +19,28 @@ //! //! This pallet allows to register new assets if certain conditions are met //! The main goal of this pallet is to allow moonbeam to register XCM assets +//! and control the creation of local assets //! The assumption is we work with AssetTypes, which can then be comperted to AssetIds //! -//! This pallet has three storage items: AssetIdType, which holds a mapping from AssetId->AssetType -//! AssetTypeUnitsPerSecond: an AssetType->u128 mapping that holds how much each AssetType should be -//! charged per unit of second, in the case such an Asset is received as a XCM asset. Finally, -//! AssetTypeId holds a mapping from AssetType -> AssetId. +//! This pallet has five storage items: AssetIdType, which holds a mapping from AssetId->AssetType +//! AssetTypeUnitsPerSecond: an AssetType->u128 mapping that holds how much each AssetType should +//! be charged per unit of second, in the case such an Asset is received as a XCM asset. Finally, +//! AssetTypeId holds a mapping from AssetType -> AssetId. LocalAssetCounter +//! which holds the counter of local assets that have been created so far. And LocalAssetDeposit, +//! which holds a mapping between assetId and assetInfo, i.e., the asset creator (from which +//! we take the deposit) and the deposit amount itself. //! -//! This pallet has three extrinsics: register_asset, which registers an Asset in this pallet and -//! creates the asset as dictated by the AssetRegistrar trait. set_asset_units_per_second: which -//! sets the unit per second that should be charged for a particular asset. +//! This pallet has eight extrinsics: register_foreign_asset, which registers a foreign +//! asset in this pallet and creates the asset as dictated by the AssetRegistrar trait. +//! set_asset_units_per_second: which sets the unit per second that should be charged for +//! a particular asset. //! change_existing_asset_type: which allows to update the correspondence between AssetId and //! AssetType +//! remove_supported_asset: which removes an asset from the supported assets for fee payment +//! remove_existing_asset_type: which removes a mapping from a foreign asset to an assetId +//! register_local_asset: which creates a local asset with a specific owner +//! destroy_foreign_asset: which destroys a foreign asset and all its associated data +//! destroy_local_asset: which destroys a local asset and all its associated data #![cfg_attr(not(feature = "std"), no_std)] @@ -49,7 +59,11 @@ pub mod weights; pub mod pallet { use crate::weights::WeightInfo; - use frame_support::{pallet_prelude::*, PalletId}; + use frame_support::{ + pallet_prelude::*, + traits::{Currency, ReservableCurrency}, + PalletId, + }; use frame_system::pallet_prelude::*; use parity_scale_codec::HasCompact; use sp_runtime::traits::{AccountIdConversion, AtLeast32BitUnsigned}; @@ -62,36 +76,90 @@ pub mod pallet { /// The AssetManagers's pallet id pub const PALLET_ID: PalletId = PalletId(*b"asstmngr"); + pub(crate) type DepositBalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + + #[derive(Default, Clone, Encode, Decode, RuntimeDebug, PartialEq, scale_info::TypeInfo)] + #[scale_info(skip_type_params(T))] + pub struct AssetInfo { + pub creator: T::AccountId, + pub deposit: DepositBalanceOf, + } + // The registrar trait. We need to comply with this pub trait AssetRegistrar { - // How to create an asset - fn create_asset( - asset: T::AssetId, - min_balance: T::Balance, - metadata: T::AssetRegistrarMetadata, + // How to create a foreign asset, meaning an asset whose reserve chain + // is not our chain + fn create_foreign_asset( + _asset: T::AssetId, + _min_balance: T::Balance, + _metadata: T::AssetRegistrarMetadata, // Wether or not an asset-receiving account increments the sufficient counter - is_sufficient: bool, - ) -> DispatchResult; + _is_sufficient: bool, + ) -> DispatchResult { + unimplemented!() + } + + // Create a local asset, meaning an asset whose reserve chain is our chain + // These are created as non-sufficent by default + fn create_local_asset( + _asset: T::AssetId, + _account: T::AccountId, + _min_balance: T::Balance, + _is_sufficient: bool, + _owner: T::AccountId, + ) -> DispatchResult { + unimplemented!() + } + + // How to destroy a foreign asset + fn destroy_foreign_asset( + _asset: T::AssetId, + _witness: T::AssetDestroyWitness, + ) -> DispatchResult { + unimplemented!() + } + + // How to destroy a local asset + fn destroy_local_asset( + _asset: T::AssetId, + _witness: T::AssetDestroyWitness, + ) -> DispatchResult { + unimplemented!() + } + + // Get destroy asset weight dispatch info + fn destroy_asset_dispatch_info_weight( + _asset: T::AssetId, + _witness: T::AssetDestroyWitness, + ) -> Weight; + } + + // The local asset id creator. We cannot let users choose assetIds for their assets + // because they can look for collisions in the EVM. + pub trait LocalAssetIdCreator { + // How to create an assetId from the local asset counter + fn create_asset_id_from_metadata(local_asset_counter: u128) -> T::AssetId; } // We implement this trait to be able to get the AssetType and units per second registered - impl xcm_primitives::AssetTypeGetter for Pallet { - fn get_asset_type(asset_id: T::AssetId) -> Option { + impl xcm_primitives::AssetTypeGetter for Pallet { + fn get_asset_type(asset_id: T::AssetId) -> Option { AssetIdType::::get(asset_id) } - fn get_asset_id(asset_type: T::AssetType) -> Option { + fn get_asset_id(asset_type: T::ForeignAssetType) -> Option { AssetTypeId::::get(asset_type) } } - impl xcm_primitives::UnitsToWeightRatio for Pallet { - fn payment_is_supported(asset_type: T::AssetType) -> bool { + impl xcm_primitives::UnitsToWeightRatio for Pallet { + fn payment_is_supported(asset_type: T::ForeignAssetType) -> bool { SupportedFeePaymentAssets::::get() .binary_search(&asset_type) .is_ok() } - fn get_units_per_second(asset_type: T::AssetType) -> Option { + fn get_units_per_second(asset_type: T::ForeignAssetType) -> Option { AssetTypeUnitsPerSecond::::get(asset_type) } } @@ -106,8 +174,8 @@ pub mod pallet { /// The Asset Metadata we want to store type AssetRegistrarMetadata: Member + Parameter + Default; - /// The Asset Kind. - type AssetType: Parameter + Member + Ord + PartialOrd + Into + Default; + /// The Foreign Asset Kind. + type ForeignAssetType: Parameter + Member + Ord + PartialOrd + Into + Default; /// The units in which we record balances. type Balance: Member + Parameter + AtLeast32BitUnsigned + Default + Copy + MaxEncodedLen; @@ -115,8 +183,24 @@ pub mod pallet { /// The trait we use to register Assets type AssetRegistrar: AssetRegistrar; - /// Origin that is allowed to create and modify asset information - type AssetModifierOrigin: EnsureOrigin; + /// Origin that is allowed to create and modify asset information for foreign assets + type ForeignAssetModifierOrigin: EnsureOrigin; + + /// Origin that is allowed to create and modify asset information for local assets + type LocalAssetModifierOrigin: EnsureOrigin; + + /// Ways of creating local asset Ids + type LocalAssetIdCreator: LocalAssetIdCreator; + + /// The asset destroy Witness + type AssetDestroyWitness: Member + Parameter + Copy; + + /// The currency mechanism in which we reserve deposits for local assets. + type Currency: ReservableCurrency; + + /// The basic amount of funds that must be reserved for a local asset. + #[pallet::constant] + type LocalAssetDeposit: Get>; type WeightInfo: WeightInfo; } @@ -128,34 +212,51 @@ pub mod pallet { AssetAlreadyExists, AssetDoesNotExist, TooLowNumAssetsWeightHint, + LocalAssetLimitReached, + ErrorDestroyingAsset, + NotSufficientDeposit, + NonExistentLocalAsset, } #[pallet::event] #[pallet::generate_deposit(pub(crate) fn deposit_event)] pub enum Event { /// New asset with the asset manager is registered - AssetRegistered { + ForeignAssetRegistered { asset_id: T::AssetId, - asset: T::AssetType, + asset: T::ForeignAssetType, metadata: T::AssetRegistrarMetadata, }, /// Changed the amount of units we are charging per execution second for a given asset UnitsPerSecondChanged { - asset_type: T::AssetType, + asset_type: T::ForeignAssetType, units_per_second: u128, }, /// Changed the xcm type mapping for a given asset id - AssetTypeChanged { + ForeignAssetTypeChanged { asset_id: T::AssetId, - new_asset_type: T::AssetType, + new_asset_type: T::ForeignAssetType, }, /// Removed all information related to an assetId - AssetRemoved { + ForeignAssetRemoved { asset_id: T::AssetId, - asset_type: T::AssetType, + asset_type: T::ForeignAssetType, }, /// Supported asset type for fee payment removed - SupportedAssetRemoved { asset_type: T::AssetType }, + SupportedAssetRemoved { asset_type: T::ForeignAssetType }, + /// Local asset was created + LocalAssetRegistered { + asset_id: T::AssetId, + creator: T::AccountId, + owner: T::AccountId, + }, + /// Removed all information related to an assetId and destroyed asset + ForeignAssetDestroyed { + asset_id: T::AssetId, + asset_type: T::ForeignAssetType, + }, + /// Removed all information related to an assetId and destroyed asset + LocalAssetDestroyed { asset_id: T::AssetId }, } /// Mapping from an asset id to asset type. @@ -163,14 +264,16 @@ pub mod pallet { /// like transferring an asset from this chain to another. #[pallet::storage] #[pallet::getter(fn asset_id_type)] - pub type AssetIdType = StorageMap<_, Blake2_128Concat, T::AssetId, T::AssetType>; + pub type AssetIdType = + StorageMap<_, Blake2_128Concat, T::AssetId, T::ForeignAssetType>; /// Reverse mapping of AssetIdType. Mapping from an asset type to an asset id. /// This is mostly used when receiving a multilocation XCM message to retrieve /// the corresponding asset in which tokens should me minted. #[pallet::storage] #[pallet::getter(fn asset_type_id)] - pub type AssetTypeId = StorageMap<_, Blake2_128Concat, T::AssetType, T::AssetId>; + pub type AssetTypeId = + StorageMap<_, Blake2_128Concat, T::ForeignAssetType, T::AssetId>; /// Stores the units per second for local execution for a AssetType. /// This is used to know how to charge for XCM execution in a particular @@ -179,38 +282,62 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn asset_type_units_per_second)] pub type AssetTypeUnitsPerSecond = - StorageMap<_, Blake2_128Concat, T::AssetType, u128>; + StorageMap<_, Twox64Concat, T::ForeignAssetType, u128>; + + /// Stores the counter of the number of local assets that have been + /// created so far + /// This value can be used to salt the creation of an assetId, e.g., + /// by hashing it. This is particularly useful for cases like moonbeam + /// where letting users choose their assetId would result in collision + /// in the evm side. + #[pallet::storage] + #[pallet::getter(fn local_asset_counter)] + pub type LocalAssetCounter = StorageValue<_, u128, ValueQuery>; + + /// Local asset deposits, a mapping from assetId to a struct + /// holding the creator (from which the deposit was reserved) and + /// the deposit amount + #[pallet::storage] + #[pallet::getter(fn local_asset_deposit)] + pub type LocalAssetDeposit = + StorageMap<_, Blake2_128Concat, T::AssetId, AssetInfo>; // Supported fee asset payments #[pallet::storage] #[pallet::getter(fn supported_fee_payment_assets)] - pub type SupportedFeePaymentAssets = StorageValue<_, Vec, ValueQuery>; + pub type SupportedFeePaymentAssets = + StorageValue<_, Vec, ValueQuery>; #[pallet::call] impl Pallet { /// Register new asset with the asset manager - #[pallet::weight(T::WeightInfo::register_asset())] - pub fn register_asset( + #[pallet::weight(T::WeightInfo::register_foreign_asset())] + pub fn register_foreign_asset( origin: OriginFor, - asset: T::AssetType, + asset: T::ForeignAssetType, metadata: T::AssetRegistrarMetadata, min_amount: T::Balance, is_sufficient: bool, ) -> DispatchResult { - T::AssetModifierOrigin::ensure_origin(origin)?; + T::ForeignAssetModifierOrigin::ensure_origin(origin)?; let asset_id: T::AssetId = asset.clone().into(); ensure!( AssetIdType::::get(&asset_id).is_none(), Error::::AssetAlreadyExists ); - T::AssetRegistrar::create_asset(asset_id, min_amount, metadata.clone(), is_sufficient) - .map_err(|_| Error::::ErrorCreatingAsset)?; + T::AssetRegistrar::create_foreign_asset( + asset_id, + min_amount, + metadata.clone(), + is_sufficient, + ) + .map_err(|_| Error::::ErrorCreatingAsset)?; AssetIdType::::insert(&asset_id, &asset); AssetTypeId::::insert(&asset, &asset_id); - Self::deposit_event(Event::AssetRegistered { + Self::deposit_event(Event::ForeignAssetRegistered { asset_id, asset, metadata, @@ -218,15 +345,16 @@ pub mod pallet { Ok(()) } - /// Change the amount of units we are charging per execution second for a given AssetType + /// Change the amount of units we are charging per execution second + /// for a given ForeignAssetType #[pallet::weight(T::WeightInfo::set_asset_units_per_second(*num_assets_weight_hint))] pub fn set_asset_units_per_second( origin: OriginFor, - asset_type: T::AssetType, + asset_type: T::ForeignAssetType, units_per_second: u128, num_assets_weight_hint: u32, ) -> DispatchResult { - T::AssetModifierOrigin::ensure_origin(origin)?; + T::ForeignAssetModifierOrigin::ensure_origin(origin)?; ensure!( AssetTypeId::::get(&asset_type).is_some(), @@ -263,10 +391,10 @@ pub mod pallet { pub fn change_existing_asset_type( origin: OriginFor, asset_id: T::AssetId, - new_asset_type: T::AssetType, + new_asset_type: T::ForeignAssetType, num_assets_weight_hint: u32, ) -> DispatchResult { - T::AssetModifierOrigin::ensure_origin(origin)?; + T::ForeignAssetModifierOrigin::ensure_origin(origin)?; // Grab supported assets let mut supported_assets = SupportedFeePaymentAssets::::get(); @@ -306,7 +434,7 @@ pub mod pallet { AssetTypeUnitsPerSecond::::insert(&new_asset_type, units); } - Self::deposit_event(Event::AssetTypeChanged { + Self::deposit_event(Event::ForeignAssetTypeChanged { asset_id, new_asset_type, }); @@ -316,10 +444,10 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::remove_supported_asset(*num_assets_weight_hint))] pub fn remove_supported_asset( origin: OriginFor, - asset_type: T::AssetType, + asset_type: T::ForeignAssetType, num_assets_weight_hint: u32, ) -> DispatchResult { - T::AssetModifierOrigin::ensure_origin(origin)?; + T::ForeignAssetModifierOrigin::ensure_origin(origin)?; // Grab supported assets let mut supported_assets = SupportedFeePaymentAssets::::get(); @@ -351,7 +479,7 @@ pub mod pallet { asset_id: T::AssetId, num_assets_weight_hint: u32, ) -> DispatchResult { - T::AssetModifierOrigin::ensure_origin(origin)?; + T::ForeignAssetModifierOrigin::ensure_origin(origin)?; // Grab supported assets let mut supported_assets = SupportedFeePaymentAssets::::get(); @@ -374,17 +502,173 @@ pub mod pallet { // Only if the old asset is supported we need to remove it if let Ok(index) = supported_assets.binary_search(&asset_type) { supported_assets.remove(index); + // Insert + SupportedFeePaymentAssets::::put(supported_assets); } - // Insert - SupportedFeePaymentAssets::::put(supported_assets); + Self::deposit_event(Event::ForeignAssetRemoved { + asset_id, + asset_type, + }); + Ok(()) + } + + /// Register a new local asset + /// No information is stored in this pallet about the local asset + /// The reason is that we dont need to hold a mapping between the multilocation + /// and the local asset, as this conversion is deterministic + /// Further, we dont allow xcm fee payment in local assets + #[pallet::weight(T::WeightInfo::register_local_asset())] + pub fn register_local_asset( + origin: OriginFor, + creator: T::AccountId, + owner: T::AccountId, + is_sufficient: bool, + min_balance: T::Balance, + ) -> DispatchResult { + T::LocalAssetModifierOrigin::ensure_origin(origin)?; - Self::deposit_event(Event::AssetRemoved { + // Get the deposit amount + let deposit = T::LocalAssetDeposit::get(); + + // Verify we can reserve + T::Currency::can_reserve(&creator, deposit) + .then(|| true) + .ok_or(Error::::NotSufficientDeposit)?; + + // Read Local Asset Counter + let mut local_asset_counter = LocalAssetCounter::::get(); + + // Create the assetId with LocalAssetIdCreator + let asset_id = + T::LocalAssetIdCreator::create_asset_id_from_metadata(local_asset_counter); + + // Increment the counter + local_asset_counter = local_asset_counter + .checked_add(1) + .ok_or(Error::::LocalAssetLimitReached)?; + + // Create local asset + T::AssetRegistrar::create_local_asset( + asset_id, + creator.clone(), + min_balance, + is_sufficient, + owner.clone(), + ) + .map_err(|_| Error::::ErrorCreatingAsset)?; + + // Reserve the deposit, we verified we can do this + T::Currency::reserve(&creator, deposit)?; + + // Update assetInfo + LocalAssetDeposit::::insert( + asset_id, + AssetInfo { + creator: creator.clone(), + deposit, + }, + ); + + // Update local asset counter + LocalAssetCounter::::put(local_asset_counter); + + Self::deposit_event(Event::LocalAssetRegistered { + asset_id, + creator, + owner, + }); + Ok(()) + } + + /// Destroy a given foreign assetId + /// The weight in this case is the one returned by the trait + /// plus the db writes and reads from removing all the associated + /// data + #[pallet::weight({ + let dispatch_info_weight = T::AssetRegistrar::destroy_asset_dispatch_info_weight( + *asset_id, *destroy_asset_witness + ); + T::WeightInfo::remove_existing_asset_type(*num_assets_weight_hint) + .saturating_add(dispatch_info_weight) + })] + pub fn destroy_foreign_asset( + origin: OriginFor, + asset_id: T::AssetId, + destroy_asset_witness: T::AssetDestroyWitness, + num_assets_weight_hint: u32, + ) -> DispatchResult { + T::ForeignAssetModifierOrigin::ensure_origin(origin)?; + + T::AssetRegistrar::destroy_foreign_asset(asset_id, destroy_asset_witness) + .map_err(|_| Error::::ErrorDestroyingAsset)?; + + // Grab supported assets + let mut supported_assets = SupportedFeePaymentAssets::::get(); + + ensure!( + num_assets_weight_hint >= (supported_assets.len() as u32), + Error::::TooLowNumAssetsWeightHint + ); + + let asset_type = + AssetIdType::::get(&asset_id).ok_or(Error::::AssetDoesNotExist)?; + + // Remove from AssetIdType + AssetIdType::::remove(&asset_id); + // Remove from AssetTypeId + AssetTypeId::::remove(&asset_type); + // Remove previous asset type units per second + AssetTypeUnitsPerSecond::::remove(&asset_type); + + // Only if the old asset is supported we need to remove it + if let Ok(index) = supported_assets.binary_search(&asset_type) { + supported_assets.remove(index); + // Insert + SupportedFeePaymentAssets::::put(supported_assets); + } + + Self::deposit_event(Event::ForeignAssetDestroyed { asset_id, asset_type, }); Ok(()) } + + /// Destroy a given local assetId + /// We do not store anything related to local assets in this pallet other than the counter + /// and the counter is not used for destroying the asset, so no additional db reads/writes + /// to be counter here + #[pallet::weight({ + T::AssetRegistrar::destroy_asset_dispatch_info_weight( + *asset_id, *destroy_asset_witness + ) + .saturating_add(T::DbWeight::get().reads_writes(2, 2)) + })] + pub fn destroy_local_asset( + origin: OriginFor, + asset_id: T::AssetId, + destroy_asset_witness: T::AssetDestroyWitness, + ) -> DispatchResult { + T::LocalAssetModifierOrigin::ensure_origin(origin)?; + + // Get asset creator and deposit amount + let asset_info = + LocalAssetDeposit::::get(asset_id).ok_or(Error::::NonExistentLocalAsset)?; + + // Destroy local asset + T::AssetRegistrar::destroy_local_asset(asset_id, destroy_asset_witness) + .map_err(|_| Error::::ErrorDestroyingAsset)?; + + // Unreserve deposit + T::Currency::unreserve(&asset_info.creator, asset_info.deposit); + + // Remove asset info + LocalAssetDeposit::::remove(asset_id); + + Self::deposit_event(Event::LocalAssetDestroyed { asset_id }); + Ok(()) + } } impl Pallet { diff --git a/pallets/asset-manager/src/migrations.rs b/pallets/asset-manager/src/migrations.rs index 0ede9254b5..a89bb5892c 100644 --- a/pallets/asset-manager/src/migrations.rs +++ b/pallets/asset-manager/src/migrations.rs @@ -28,9 +28,9 @@ use sp_std::vec::Vec; use xcm::latest::prelude::*; /// Migration that changes the mapping AssetId -> units_per_second to -/// a mapping of the form AssetType -> units_per_second -/// It does so by removing the AssetTypeUnitsPerSecond storage and -/// populating the new AssetTypeUnitsPerSecond +/// a mapping of the form ForeignAssetType -> units_per_second +/// It does so by removing the ForeignAssetTypeUnitsPerSecond storage and +/// populating the new ForeignAssetTypeUnitsPerSecond pub struct UnitsWithAssetType(PhantomData); impl OnRuntimeUpgrade for UnitsWithAssetType { #[cfg(feature = "try-runtime")] @@ -73,7 +73,7 @@ impl OnRuntimeUpgrade for UnitsWithAssetType { } fn on_runtime_upgrade() -> Weight { - log::info!(target: "UnitsWithAssetType", "actually running it"); + log::info!(target: "UnitsWithForeignAssetType", "actually running it"); let pallet_prefix: &[u8] = b"AssetManager"; let storage_item_prefix: &[u8] = b"AssetIdUnitsPerSecond"; @@ -91,21 +91,21 @@ impl OnRuntimeUpgrade for UnitsWithAssetType { .try_into() .expect("There are between 0 and 2**64 mappings stored."); - log::info!(target: "UnitsWithAssetType", "Migrating {:?} elements", migrated_count); + log::info!(target: "UnitsWithForeignAssetType", "Migrating {:?} elements", migrated_count); // Write to the new storage with removed and added fields for (asset_id, units) in stored_data { - // Read the assetType for the assetId + // Read the ForeignAssetType for the assetId if let Some(asset_type) = AssetIdType::::get(&asset_id) { - // Populate with assetType as key + // Populate with ForeignAssetType as key AssetTypeUnitsPerSecond::::insert(&asset_type, units) } } - log::info!(target: "UnitsWithAssetType", "almost done"); + log::info!(target: "UnitsWithForeignAssetType", "almost done"); // Return the weight used. For each migrated mapping there is a read to get it into - // memory, a read to get assetType and + // memory, a read to get ForeignAssetType and // a write to clear the old stored value, and a write to re-store it. let db_weights = T::DbWeight::get(); migrated_count.saturating_mul(2 * db_weights.write + 2 * db_weights.read) @@ -128,7 +128,7 @@ impl OnRuntimeUpgrade for UnitsWithAssetType { // Check number of entries matches what was set aside in pre_upgrade let old_mapping_count: u64 = Self::get_temp_storage("mapping_count") .expect("We stored a mapping count; it should be there; qed"); - let new_mapping_count = AssetTypeUnitsPerSecond::::iter().count() as u64; + let new_mapping_count = ForeignAssetTypeUnitsPerSecond::::iter().count() as u64; assert_eq!(old_mapping_count, new_mapping_count); // Check that our example pair is still well-mapped after the migration @@ -136,10 +136,10 @@ impl OnRuntimeUpgrade for UnitsWithAssetType { let (asset_id, units): (T::AssetId, u128) = Self::get_temp_storage("example_pair").expect("qed"); - let asset_type = - AssetIdType::::get(asset_id).expect("AssetIdType should have the assetType"); + let asset_type = AssetIdType::::get(asset_id) + .expect("AssetIdType should have the ForeignAssetType"); - let migrated_units = AssetTypeUnitsPerSecond::::get(asset_type).expect("qed"); + let migrated_units = ForeignAssetTypeUnitsPerSecond::::get(asset_type).expect("qed"); // Check units are identical assert_eq!(migrated_units, units); } @@ -148,8 +148,8 @@ impl OnRuntimeUpgrade for UnitsWithAssetType { } } -/// Migration that reads data from the AssetIdType mapping (AssetId -> AssetType) -/// and populates the reverse mapping AssetTypeId (AssetType -> AssetId) +/// Migration that reads data from the AssetIdType mapping (AssetId -> ForeignAssetType) +/// and populates the reverse mapping ForeignAssetTypeId (ForeignAssetType -> AssetId) pub struct PopulateAssetTypeIdStorage(PhantomData); impl OnRuntimeUpgrade for PopulateAssetTypeIdStorage { #[cfg(feature = "try-runtime")] @@ -166,13 +166,14 @@ impl OnRuntimeUpgrade for PopulateAssetTypeIdStorage { // there will exist the reserve mapping in the new storage // Assert new storage is empty - assert!(AssetTypeId::::iter().next().is_none()); + assert!(ForeignAssetTypeId::::iter().next().is_none()); // Check number of entries, and set it aside in temp storage - let stored_data: Vec<_> = storage_key_iter::( - pallet_prefix, - storage_item_prefix, - ) + let stored_data: Vec<_> = storage_key_iter::< + T::AssetId, + T::ForeignAssetType, + Blake2_128Concat, + >(pallet_prefix, storage_item_prefix) .collect(); let mapping_count = stored_data.len(); Self::set_temp_storage(mapping_count as u32, "mapping_count"); @@ -191,16 +192,17 @@ impl OnRuntimeUpgrade for PopulateAssetTypeIdStorage { } fn on_runtime_upgrade() -> Weight { - log::info!(target: "PopulateAssetTypeIdStorage", "actually running it"); + log::info!(target: "PopulateForeignAssetTypeIdStorage", "actually running it"); let pallet_prefix: &[u8] = b"AssetManager"; let storage_item_prefix: &[u8] = b"AssetIdType"; // Read all the data into memory. // https://crates.parity.io/frame_support/storage/migration/fn.storage_key_iter.html - let stored_data: Vec<_> = storage_key_iter::( - pallet_prefix, - storage_item_prefix, - ) + let stored_data: Vec<_> = storage_key_iter::< + T::AssetId, + T::ForeignAssetType, + Blake2_128Concat, + >(pallet_prefix, storage_item_prefix) .collect(); let migrated_count: Weight = stored_data @@ -209,18 +211,18 @@ impl OnRuntimeUpgrade for PopulateAssetTypeIdStorage { .expect("There are between 0 and 2**64 mappings stored."); log::info!( - target: "PopulateAssetTypeIdStorage", + target: "PopulateForeignAssetTypeIdStorage", "Migrating {:?} elements", migrated_count ); // Write to the new storage for (asset_id, asset_type) in stored_data { - // Populate with assetType as key + // Populate with ForeignAssetType as key AssetTypeId::::insert(&asset_type, asset_id) } - log::info!(target: "PopulateAssetTypeIdStorage", "almost done"); + log::info!(target: "PopulateForeignAssetTypeIdStorage", "almost done"); // Return the weight used. For each migrated mapping there is a read to get it into // memory, and a write to populate the new storage. @@ -235,16 +237,16 @@ impl OnRuntimeUpgrade for PopulateAssetTypeIdStorage { // Check number of entries matches what was set aside in pre_upgrade let mapping_count: u64 = Self::get_temp_storage("mapping_count") .expect("We stored a mapping count; it should be there; qed"); - let new_mapping_count = AssetTypeId::::iter().count() as u64; + let new_mapping_count = ForeignAssetTypeId::::iter().count() as u64; assert_eq!(mapping_count, new_mapping_count); // Check that our example pair is still well-mapped after the migration if new_mapping_count > 0 { - let (asset_id, asset_type): (T::AssetId, T::AssetType) = + let (asset_id, asset_type): (T::AssetId, T::ForeignAssetType) = Self::get_temp_storage("example_pair").expect("qed"); - let stored_asset_id = - AssetTypeId::::get(asset_type).expect("AssetTypeId should have the assetId"); + let stored_asset_id = ForeignAssetTypeId::::get(asset_type) + .expect("ForeignAssetTypeId should have the assetId"); // Check assetIds are identical assert_eq!(asset_id, stored_asset_id); @@ -254,7 +256,7 @@ impl OnRuntimeUpgrade for PopulateAssetTypeIdStorage { } } -/// Migration that reads the existing AssetTypes looking for old Statemine prefixes of +/// Migration that reads the existing ForeignAssetTypes looking for old Statemine prefixes of /// the form (Parachain, GeneralIndex) and changes them for the new prefix /// (Parachain, PalletInstance, GeneralIndex) pub struct ChangeStateminePrefixes( @@ -266,7 +268,7 @@ where T: Config, StatemineParaIdInfo: Get, StatemineAssetsInstanceInfo: Get, - T::AssetType: Into> + From, + T::ForeignAssetType: Into> + From, { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { @@ -276,13 +278,14 @@ where let storage_item_prefix: &[u8] = b"AssetIdType"; // We want to test that: - // If there exists an assetType matching the Statemine, it gets overwritten + // If there exists an ForeignAssetType matching the Statemine, it gets overwritten // Check number of entries, and set it aside in temp storage - let stored_data: Vec<_> = storage_key_iter::( - pallet_prefix, - storage_item_prefix, - ) + let stored_data: Vec<_> = storage_key_iter::< + T::AssetId, + T::ForeignAssetType, + Blake2_128Concat, + >(pallet_prefix, storage_item_prefix) .collect(); let statemine_para_id = StatemineParaIdInfo::get(); @@ -317,10 +320,11 @@ where // Read all the data into memory. // https://crates.parity.io/frame_support/storage/migration/fn.storage_key_iter.html - let stored_data: Vec<_> = storage_key_iter::( - pallet_prefix, - storage_item_prefix, - ) + let stored_data: Vec<_> = storage_key_iter::< + T::AssetId, + T::ForeignAssetType, + Blake2_128Concat, + >(pallet_prefix, storage_item_prefix) .collect(); let read_count: Weight = stored_data @@ -351,13 +355,13 @@ where GeneralIndex(index), ), }; - let new_asset_type: T::AssetType = new_location.into(); + let new_asset_type: T::ForeignAssetType = new_location.into(); // Insert new asset type previous asset type AssetIdType::::insert(&asset_id, &new_asset_type); - // This is checked in case AssetManagerPopulateAssetTypeIdStorage runs first + // This is checked in case AssetManagerPopulateForeignAssetTypeIdStorage runs first if AssetTypeId::::get(&asset_type) == Some(asset_id) { - // We need to update AssetTypeId too + // We need to update ForeignAssetTypeId too AssetTypeId::::remove(&asset_type); AssetTypeId::::insert(&new_asset_type, asset_id); @@ -365,9 +369,9 @@ where used_weight = used_weight.saturating_add(2 * db_weights.write); } - // This is checked in case UnitsWithAssetType runs first + // This is checked in case UnitsWithForeignAssetType runs first if let Some(units) = AssetTypeUnitsPerSecond::::take(&asset_type) { - // We need to update AssetTypeUnitsPerSecond too + // We need to update ForeignAssetTypeUnitsPerSecond too AssetTypeUnitsPerSecond::::insert(&new_asset_type, units); // Update weight due to this branch @@ -401,7 +405,7 @@ where // Check that our example pair suffered the correct migration if found { - let (asset_id, asset_type): (T::AssetId, T::AssetType) = + let (asset_id, asset_type): (T::AssetId, T::ForeignAssetType) = Self::get_temp_storage("example_pair").expect("qed"); let location: Option = asset_type.into(); @@ -413,7 +417,7 @@ where let stored_asset_type = AssetIdType::::get(asset_id).expect("This entry should be updated"); - let expected_new_asset_type: T::AssetType = MultiLocation { + let expected_new_asset_type: T::ForeignAssetType = MultiLocation { parents: 1, interior: X3( Parachain(para_id), @@ -423,7 +427,7 @@ where } .into(); - // Check assetTypes are identical + // Check ForeignAssetTypes are identical assert_eq!(stored_asset_type, expected_new_asset_type); } _ => panic!("This should never have entered this path"), @@ -451,7 +455,7 @@ impl OnRuntimeUpgrade for PopulateSupportedFeePaymentAssets { // Read all the data into memory. // https://crates.parity.io/frame_support/storage/migration/fn.storage_key_iter.html - let stored_data: Vec<_> = storage_key_iter::( + let stored_data: Vec<_> = storage_key_iter::( pallet_prefix, storage_item_prefix, ) @@ -469,7 +473,7 @@ impl OnRuntimeUpgrade for PopulateSupportedFeePaymentAssets { ); // Collect in a vec - let mut supported_assets: Vec = Vec::new(); + let mut supported_assets: Vec = Vec::new(); for (asset_type, _) in stored_data { supported_assets.push(asset_type); } diff --git a/pallets/asset-manager/src/mock.rs b/pallets/asset-manager/src/mock.rs index 544dfe2407..9ca530d5e2 100644 --- a/pallets/asset-manager/src/mock.rs +++ b/pallets/asset-manager/src/mock.rs @@ -18,7 +18,9 @@ use super::*; use crate as pallet_asset_manager; use parity_scale_codec::{Decode, Encode}; -use frame_support::{construct_runtime, parameter_types, traits::Everything, RuntimeDebug}; +use frame_support::{ + construct_runtime, parameter_types, traits::Everything, weights::Weight, RuntimeDebug, +}; use frame_system::EnsureRoot; use scale_info::TypeInfo; use sp_core::H256; @@ -33,6 +35,9 @@ use xcm::latest::prelude::*; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; +pub type AccountId = u64; +pub type Balance = u64; + construct_runtime!( pub enum Test where Block = Block, @@ -58,7 +63,7 @@ impl frame_system::Config for Test { type BlockNumber = u64; type Hash = H256; type Hashing = BlakeTwo256; - type AccountId = u64; + type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; type Event = Event; @@ -80,7 +85,7 @@ parameter_types! { } impl pallet_balances::Config for Test { - type Balance = u64; + type Balance = Balance; type DustRemoval = (); type Event = Event; type ExistentialDeposit = ExistentialDeposit; @@ -149,7 +154,7 @@ impl Into> for MockAssetType { pub struct MockAssetPalletRegistrar; impl AssetRegistrar for MockAssetPalletRegistrar { - fn create_asset( + fn create_foreign_asset( _asset: u32, _min_balance: u64, _metadata: u32, @@ -157,6 +162,44 @@ impl AssetRegistrar for MockAssetPalletRegistrar { ) -> Result<(), DispatchError> { Ok(()) } + + fn create_local_asset( + _asset: u32, + _account: u64, + _min_balance: u64, + _is_sufficient: bool, + _owner: u64, + ) -> sp_runtime::DispatchResult { + Ok(()) + } + + fn destroy_foreign_asset(_asset: u32, _witness: u32) -> Result<(), DispatchError> { + Ok(()) + } + + fn destroy_local_asset(_asset: u32, _witness: u32) -> Result<(), DispatchError> { + Ok(()) + } + + fn destroy_asset_dispatch_info_weight(_asset: u32, _witness: u32) -> Weight { + 0 + } +} + +pub struct MockLocalAssetIdCreator; +impl pallet_asset_manager::LocalAssetIdCreator for MockLocalAssetIdCreator { + fn create_asset_id_from_metadata(local_asset_counter: u128) -> AssetId { + // Our means of converting a creator to an assetId + // We basically hash nonce+account + let mut result: [u8; 4] = [0u8; 4]; + let big_endian = local_asset_counter.to_le_bytes(); + result.copy_from_slice(&big_endian[0..4]); + u32::from_le_bytes(result) + } +} + +parameter_types! { + pub const LocalAssetDeposit: u64 = 1; } impl Config for Test { @@ -164,20 +207,47 @@ impl Config for Test { type Balance = u64; type AssetId = u32; type AssetRegistrarMetadata = u32; - type AssetType = MockAssetType; + type ForeignAssetType = MockAssetType; type AssetRegistrar = MockAssetPalletRegistrar; - type AssetModifierOrigin = EnsureRoot; + type ForeignAssetModifierOrigin = EnsureRoot; + type LocalAssetModifierOrigin = EnsureRoot; + type LocalAssetIdCreator = MockLocalAssetIdCreator; + type AssetDestroyWitness = u32; + type Currency = Balances; + type LocalAssetDeposit = LocalAssetDeposit; type WeightInfo = (); } -pub(crate) fn new_test_ext() -> sp_io::TestExternalities { - let t = frame_system::GenesisConfig::default() - .build_storage::() - .unwrap(); +pub(crate) struct ExtBuilder { + // endowed accounts with balances + balances: Vec<(AccountId, Balance)>, +} - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext +impl Default for ExtBuilder { + fn default() -> ExtBuilder { + ExtBuilder { balances: vec![] } + } +} + +impl ExtBuilder { + pub(crate) fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self { + self.balances = balances; + self + } + pub(crate) fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .expect("Frame system builds valid default genesis config"); + + pallet_balances::GenesisConfig:: { + balances: self.balances, + } + .assimilate_storage(&mut t) + .expect("Pallet balances storage can be assimilated"); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } } pub(crate) fn events() -> Vec> { diff --git a/pallets/asset-manager/src/tests.rs b/pallets/asset-manager/src/tests.rs index 2e61aa300a..0156b4b938 100644 --- a/pallets/asset-manager/src/tests.rs +++ b/pallets/asset-manager/src/tests.rs @@ -26,9 +26,9 @@ use frame_support::{ use xcm::latest::prelude::*; #[test] -fn registering_works() { - new_test_ext().execute_with(|| { - assert_ok!(AssetManager::register_asset( +fn registering_foreign_works() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), MockAssetType::MockAsset(1), 0u32.into(), @@ -44,7 +44,7 @@ fn registering_works() { AssetManager::asset_type_id(MockAssetType::MockAsset(1)).unwrap(), 1 ); - expect_events(vec![crate::Event::AssetRegistered { + expect_events(vec![crate::Event::ForeignAssetRegistered { asset_id: 1, asset: MockAssetType::MockAsset(1), metadata: 0u32, @@ -52,10 +52,43 @@ fn registering_works() { }); } +#[test] +fn registering_local_works() { + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .build() + .execute_with(|| { + let asset_id = MockLocalAssetIdCreator::create_asset_id_from_metadata(0); + + assert_ok!(AssetManager::register_local_asset( + Origin::root(), + 1u64, + 1u64, + true, + 0u32.into(), + )); + + assert_eq!(AssetManager::local_asset_counter(), 1); + assert_eq!( + AssetManager::local_asset_deposit(asset_id), + Some(AssetInfo { + creator: 1, + deposit: 1 + }) + ); + + expect_events(vec![crate::Event::LocalAssetRegistered { + asset_id, + creator: 1, + owner: 1, + }]) + }); +} + #[test] fn test_asset_exists_error() { - new_test_ext().execute_with(|| { - assert_ok!(AssetManager::register_asset( + ExtBuilder::default().build().execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), MockAssetType::MockAsset(1), 0u32.into(), @@ -68,7 +101,7 @@ fn test_asset_exists_error() { MockAssetType::MockAsset(1) ); assert_noop!( - AssetManager::register_asset( + AssetManager::register_foreign_asset( Origin::root(), MockAssetType::MockAsset(1), 0u32.into(), @@ -82,8 +115,8 @@ fn test_asset_exists_error() { #[test] fn test_root_can_change_units_per_second() { - new_test_ext().execute_with(|| { - assert_ok!(AssetManager::register_asset( + ExtBuilder::default().build().execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), MockAssetType::MockAsset(1), 0u32.into(), @@ -105,7 +138,7 @@ fn test_root_can_change_units_per_second() { assert!(AssetManager::supported_fee_payment_assets().contains(&MockAssetType::MockAsset(1))); expect_events(vec![ - crate::Event::AssetRegistered { + crate::Event::ForeignAssetRegistered { asset_id: 1, asset: MockAssetType::MockAsset(1), metadata: 0, @@ -120,9 +153,9 @@ fn test_root_can_change_units_per_second() { #[test] fn test_regular_user_cannot_call_extrinsics() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build().execute_with(|| { assert_noop!( - AssetManager::register_asset( + AssetManager::register_foreign_asset( Origin::signed(1), MockAssetType::MockAsset(1), 0u32.into(), @@ -156,8 +189,8 @@ fn test_regular_user_cannot_call_extrinsics() { #[test] fn test_root_can_change_asset_id_type() { - new_test_ext().execute_with(|| { - assert_ok!(AssetManager::register_asset( + ExtBuilder::default().build().execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), MockAssetType::MockAsset(1), 0u32.into(), @@ -202,7 +235,7 @@ fn test_root_can_change_asset_id_type() { assert!(AssetManager::asset_type_id(MockAssetType::MockAsset(1)).is_none()); expect_events(vec![ - crate::Event::AssetRegistered { + crate::Event::ForeignAssetRegistered { asset_id: 1, asset: MockAssetType::MockAsset(1), metadata: 0, @@ -211,7 +244,7 @@ fn test_root_can_change_asset_id_type() { asset_type: MockAssetType::MockAsset(1), units_per_second: 200, }, - crate::Event::AssetTypeChanged { + crate::Event::ForeignAssetTypeChanged { asset_id: 1, new_asset_type: MockAssetType::MockAsset(2), }, @@ -221,8 +254,8 @@ fn test_root_can_change_asset_id_type() { #[test] fn test_change_units_per_second_after_setting_it_once() { - new_test_ext().execute_with(|| { - assert_ok!(AssetManager::register_asset( + ExtBuilder::default().build().execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), MockAssetType::MockAsset(1), 0u32.into(), @@ -257,7 +290,7 @@ fn test_change_units_per_second_after_setting_it_once() { assert!(AssetManager::supported_fee_payment_assets().contains(&MockAssetType::MockAsset(1))); expect_events(vec![ - crate::Event::AssetRegistered { + crate::Event::ForeignAssetRegistered { asset_id: 1, asset: MockAssetType::MockAsset(1), metadata: 0, @@ -276,8 +309,8 @@ fn test_change_units_per_second_after_setting_it_once() { #[test] fn test_root_can_change_units_per_second_and_then_remove() { - new_test_ext().execute_with(|| { - assert_ok!(AssetManager::register_asset( + ExtBuilder::default().build().execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), MockAssetType::MockAsset(1), 0u32.into(), @@ -309,7 +342,7 @@ fn test_root_can_change_units_per_second_and_then_remove() { ); expect_events(vec![ - crate::Event::AssetRegistered { + crate::Event::ForeignAssetRegistered { asset_id: 1, asset: MockAssetType::MockAsset(1), metadata: 0, @@ -327,8 +360,8 @@ fn test_root_can_change_units_per_second_and_then_remove() { #[test] fn test_weight_hint_error() { - new_test_ext().execute_with(|| { - assert_ok!(AssetManager::register_asset( + ExtBuilder::default().build().execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), MockAssetType::MockAsset(1), 0u32.into(), @@ -352,7 +385,7 @@ fn test_weight_hint_error() { #[test] fn test_asset_id_non_existent_error() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build().execute_with(|| { assert_noop!( AssetManager::set_asset_units_per_second( Origin::root(), @@ -376,7 +409,7 @@ fn test_asset_id_non_existent_error() { #[test] fn test_populate_supported_fee_payment_assets_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build().execute_with(|| { use frame_support::StorageHasher; let pallet_prefix: &[u8] = b"AssetManager"; let storage_item_prefix: &[u8] = b"AssetTypeUnitsPerSecond"; @@ -412,14 +445,14 @@ fn test_populate_supported_fee_payment_assets_works() { #[test] fn test_asset_manager_units_with_asset_type_migration_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build().execute_with(|| { let pallet_prefix: &[u8] = b"AssetManager"; let storage_item_prefix: &[u8] = b"AssetIdUnitsPerSecond"; use frame_support::traits::OnRuntimeUpgrade; use frame_support::StorageHasher; use parity_scale_codec::Encode; - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), MockAssetType::MockAsset(1), 0u32.into(), @@ -459,7 +492,7 @@ fn test_asset_manager_units_with_asset_type_migration_works() { #[test] fn test_asset_manager_populate_asset_type_id_storage_migration_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build().execute_with(|| { let pallet_prefix: &[u8] = b"AssetManager"; let storage_item_prefix: &[u8] = b"AssetIdType"; use frame_support::traits::OnRuntimeUpgrade; @@ -487,7 +520,7 @@ fn test_asset_manager_populate_asset_type_id_storage_migration_works() { #[test] fn test_asset_manager_change_statemine_prefixes() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build().execute_with(|| { let pallet_prefix: &[u8] = b"AssetManager"; let storage_item_prefix: &[u8] = b"AssetIdType"; use frame_support::traits::OnRuntimeUpgrade; @@ -535,7 +568,7 @@ fn test_asset_manager_change_statemine_prefixes() { ); // To mimic case 2, we can simply register the asset through the extrinsic - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), statemine_multilocation_2.clone(), 0u32.into(), @@ -545,7 +578,7 @@ fn test_asset_manager_change_statemine_prefixes() { // To mimic case 3, we can simply register the asset through the extrinsic // But we also need to set units per second - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), statemine_multilocation_3.clone(), 0u32.into(), @@ -646,8 +679,8 @@ fn test_asset_manager_change_statemine_prefixes() { #[test] fn test_root_can_remove_asset_association() { - new_test_ext().execute_with(|| { - assert_ok!(AssetManager::register_asset( + ExtBuilder::default().build().execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), MockAssetType::MockAsset(1), 0u32.into(), @@ -676,7 +709,7 @@ fn test_root_can_remove_asset_association() { assert!(AssetManager::asset_type_units_per_second(MockAssetType::MockAsset(1)).is_none()); expect_events(vec![ - crate::Event::AssetRegistered { + crate::Event::ForeignAssetRegistered { asset_id: 1, asset: MockAssetType::MockAsset(1), metadata: 0, @@ -685,7 +718,7 @@ fn test_root_can_remove_asset_association() { asset_type: MockAssetType::MockAsset(1), units_per_second: 200, }, - crate::Event::AssetRemoved { + crate::Event::ForeignAssetRemoved { asset_id: 1, asset_type: MockAssetType::MockAsset(1), }, @@ -695,8 +728,8 @@ fn test_root_can_remove_asset_association() { #[test] fn test_removing_without_asset_units_per_second_does_not_panic() { - new_test_ext().execute_with(|| { - assert_ok!(AssetManager::register_asset( + ExtBuilder::default().build().execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( Origin::root(), MockAssetType::MockAsset(1), 0u32.into(), @@ -718,15 +751,87 @@ fn test_removing_without_asset_units_per_second_does_not_panic() { assert!(AssetManager::asset_type_units_per_second(MockAssetType::MockAsset(1)).is_none()); expect_events(vec![ - crate::Event::AssetRegistered { + crate::Event::ForeignAssetRegistered { + asset_id: 1, + asset: MockAssetType::MockAsset(1), + metadata: 0, + }, + crate::Event::ForeignAssetRemoved { + asset_id: 1, + asset_type: MockAssetType::MockAsset(1), + }, + ]) + }); +} + +#[test] +fn test_destroy_foreign_asset_also_removes_everything() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( + Origin::root(), + MockAssetType::MockAsset(1), + 0u32.into(), + 1u32.into(), + true + )); + + assert_ok!(AssetManager::destroy_foreign_asset(Origin::root(), 1, 0, 1)); + + // Mappings are deleted + assert!(AssetManager::asset_type_id(MockAssetType::MockAsset(1)).is_none()); + assert!(AssetManager::asset_id_type(1).is_none()); + + // Units per second removed + assert!(AssetManager::asset_type_units_per_second(MockAssetType::MockAsset(1)).is_none()); + + expect_events(vec![ + crate::Event::ForeignAssetRegistered { asset_id: 1, asset: MockAssetType::MockAsset(1), metadata: 0, }, - crate::Event::AssetRemoved { + crate::Event::ForeignAssetDestroyed { asset_id: 1, asset_type: MockAssetType::MockAsset(1), }, ]) }); } + +#[test] +fn test_destroy_local_asset_works() { + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .build() + .execute_with(|| { + let asset_id = MockLocalAssetIdCreator::create_asset_id_from_metadata(0); + + assert_ok!(AssetManager::register_local_asset( + Origin::root(), + 1u64, + 1u64, + true, + 0u32.into(), + )); + assert_eq!( + AssetManager::local_asset_deposit(asset_id), + Some(AssetInfo { + creator: 1, + deposit: 1 + }) + ); + + assert_ok!(AssetManager::destroy_local_asset(Origin::root(), 0, 0)); + + assert_eq!(AssetManager::local_asset_counter(), 1); + assert_eq!(AssetManager::local_asset_deposit(asset_id), None); + expect_events(vec![ + crate::Event::LocalAssetRegistered { + asset_id, + creator: 1, + owner: 1, + }, + crate::Event::LocalAssetDestroyed { asset_id }, + ]); + }); +} diff --git a/pallets/asset-manager/src/weights.rs b/pallets/asset-manager/src/weights.rs index d752224ccd..2c4ee02567 100644 --- a/pallets/asset-manager/src/weights.rs +++ b/pallets/asset-manager/src/weights.rs @@ -54,7 +54,7 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_asset_manager. pub trait WeightInfo { #[rustfmt::skip] - fn register_asset() -> Weight; + fn register_foreign_asset() -> Weight; #[rustfmt::skip] fn set_asset_units_per_second(x: u32, ) -> Weight; #[rustfmt::skip] @@ -63,6 +63,8 @@ pub trait WeightInfo { fn remove_supported_asset(x: u32, ) -> Weight; #[rustfmt::skip] fn remove_existing_asset_type(x: u32, ) -> Weight; + #[rustfmt::skip] + fn register_local_asset() -> Weight; } /// Weights for pallet_asset_manager using the Substrate node and recommended hardware. @@ -73,7 +75,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Assets Metadata (r:1 w:1) // Storage: AssetManager AssetTypeId (r:0 w:1) #[rustfmt::skip] - fn register_asset() -> Weight { + fn register_foreign_asset() -> Weight { (47_597_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) @@ -101,6 +103,17 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(6 as Weight)) } + // Storage: System Account (r:1 w:1) + // Storage: AssetManager LocalAssetCounter (r:1 w:1) + // Storage: LocalAssets Asset (r:1 w:1) + // Storage: EVM AccountCodes (r:0 w:1) + // Storage: AssetManager LocalAssetDeposit (r:0 w:1) + #[rustfmt::skip] + fn register_local_asset() -> Weight { + (51_689_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } // Storage: AssetManager SupportedFeePaymentAssets (r:1 w:1) // Storage: AssetManager AssetTypeUnitsPerSecond (r:0 w:1) #[rustfmt::skip] @@ -132,7 +145,7 @@ impl WeightInfo for () { // Storage: Assets Metadata (r:1 w:1) // Storage: AssetManager AssetTypeId (r:0 w:1) #[rustfmt::skip] - fn register_asset() -> Weight { + fn register_foreign_asset() -> Weight { (47_597_000 as Weight) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) @@ -160,6 +173,17 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(6 as Weight)) } + // Storage: System Account (r:1 w:1) + // Storage: AssetManager LocalAssetCounter (r:1 w:1) + // Storage: LocalAssets Asset (r:1 w:1) + // Storage: EVM AccountCodes (r:0 w:1) + // Storage: AssetManager LocalAssetDeposit (r:0 w:1) + #[rustfmt::skip] + fn register_local_asset() -> Weight { + (51_689_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + } // Storage: AssetManager SupportedFeePaymentAssets (r:1 w:1) // Storage: AssetManager AssetTypeUnitsPerSecond (r:0 w:1) #[rustfmt::skip] diff --git a/precompiles/assets-erc20/ERC20_local.sol b/precompiles/assets-erc20/ERC20_local.sol new file mode 100644 index 0000000000..40bf6433ff --- /dev/null +++ b/precompiles/assets-erc20/ERC20_local.sol @@ -0,0 +1,191 @@ + pragma solidity ^0.8.0; + +/** +* @title ERC20 interface +*/ +interface LocalAssetExtendedErc20 { + + /** + * @dev Returns the name of the token. + * Selector: 06fdde03 + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token. + * Selector: 95d89b41 + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the decimals places of the token. + * Selector: 313ce567 + */ + function decimals() external view returns (uint8); + + /** + * @dev Total number of tokens in existence + * Selector: 18160ddd + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Gets the balance of the specified address. + * Selector: 70a08231 + * @param who The address to query the balance of. + * @return An uint256 representing the amount owned by the passed address. + */ + function balanceOf(address who) external view returns (uint256); + + /** + * @dev Function to check the amount of tokens that an owner allowed to a spender. + * Selector: dd62ed3e + * @param owner address The address which owns the funds. + * @param spender address The address which will spend the funds. + * @return A uint256 specifying the amount of tokens still available for the spender. + */ + function allowance(address owner, address spender) + external view returns (uint256); + + /** + * @dev Transfer token for a specified address + * Selector: a9059cbb + * @param to The address to transfer to. + * @param value The amount to be transferred. + */ + function transfer(address to, uint256 value) external returns (bool); + + /** + * @dev Approve the passed address to spend the specified amount of tokens on behalf + * of msg.sender. + * Beware that changing an allowance with this method brings the risk that someone may + * use both the old + * and the new allowance by unfortunate transaction ordering. One possible solution to + * mitigate this race condition is to first reduce the spender's allowance to 0 and set + * the desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * Selector: 095ea7b3 + * @param spender The address which will spend the funds. + * @param value The amount of tokens to be spent. + */ + function approve(address spender, uint256 value) + external returns (bool); + + /** + * @dev Transfer tokens from one address to another + * Selector: 23b872dd + * @param from address The address which you want to send tokens from + * @param to address The address which you want to transfer to + * @param value uint256 the amount of tokens to be transferred + */ + function transferFrom(address from, address to, uint256 value) + external returns (bool); + + /** + * @dev Mint tokens to an address + * Selector: 23b872dd + * @param to address The address to which you want to mint tokens + * @param value uint256 the amount of tokens to be minted + */ + function mint(address to, uint256 value) + external returns (bool); + + /** + * @dev Burn tokens from an address + * Selector: 23b872dd + * @param from address The address from which you want to burn tokens + * @param value uint256 the amount of tokens to be burnt + */ + function burn(address from, uint256 value) + external returns (bool); + + /** + * @dev Freeze an account, preventing it from operating with the asset + * Selector: 23b872dd + * @param account address The address that you want to freeze + */ + function freeze(address account) + external returns (bool); + + /** + * @dev Unfreeze an account, letting it from operating againt with the asset + * Selector: 23b872dd + * @param account address The address that you want to unfreeze + */ + function thaw(address account) + external returns (bool); + + /** + * @dev Freeze the entire asset operations + * Selector: 23b872dd + */ + function freeze_asset() + external returns (bool); + + /** + * @dev Unfreeze the entire asset operations + * Selector: 23b872dd + */ + function thaw_asset() + external returns (bool); + + /** + * @dev Transfer the ownership of an asset to a new account + * Selector: 23b872dd + * @param owner address The address of the new owner + */ + function transfer_ownership(address owner) + external returns (bool); + + /** + * @dev Specify the issuer, admin and freezer of an asset + * Selector: 23b872dd + * @param issuer address The address capable of issuing tokens + * @param admin address The address capable of burning tokens and unfreezing accounts/assets + * @param freezer address The address capable of freezing accounts/asset + */ + function set_team(address issuer, address admin, address freezer) + external returns (bool); + + /** + * @dev Specify the name, symbol and decimals of your asset + * Selector: 23b872dd + * @param name string The name of the asset + * @param symbol string The symbol of the asset + * @param decimals uint8 The number of decimals of your asset + */ + function set_metadata(string calldata name, string calldata symbol, uint8 decimals) + external returns (bool); + + /** + * @dev Clear the name, symbol and decimals of your asset + * Selector: 23b872dd + */ + function clear_metadata() + external returns (bool); + /** + * @dev Event emited when a transfer has been performed. + * Selector: ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef + * @param from address The address sending the tokens + * @param to address The address receiving the tokens. + * @param value uint256 The amount of tokens transfered. + */ + event Transfer( + address indexed from, + address indexed to, + uint256 value + ); + + /** + * @dev Event emited when an approval has been registered. + * Selector: 8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925 + * @param owner address Owner of the tokens. + * @param spender address Allowed spender. + * @param value uint256 Amount of tokens approved. + */ + event Approval( + address indexed owner, + address indexed spender, + uint256 value + ); +} \ No newline at end of file diff --git a/precompiles/assets-erc20/src/lib.rs b/precompiles/assets-erc20/src/lib.rs index 4ccb11fb05..68de61a6cf 100644 --- a/precompiles/assets-erc20/src/lib.rs +++ b/precompiles/assets-erc20/src/lib.rs @@ -21,7 +21,7 @@ use fp_evm::{Context, ExitSucceed, PrecompileOutput}; use frame_support::traits::fungibles::approvals::Inspect as ApprovalInspect; use frame_support::traits::fungibles::metadata::Inspect as MetadataInspect; use frame_support::traits::fungibles::Inspect; -use frame_support::traits::OriginTrait; +use frame_support::traits::{ConstBool, Get, OriginTrait}; use frame_support::{ dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}, sp_runtime::traits::StaticLookup, @@ -31,7 +31,8 @@ use precompile_utils::{ keccak256, Address, Bytes, EvmData, EvmDataReader, EvmDataWriter, EvmResult, FunctionModifier, Gasometer, LogsBuilder, RuntimeHelper, }; -use sp_runtime::traits::{Bounded, Zero}; +use sp_runtime::traits::Bounded; +use sp_std::vec::Vec; use sp_core::{H160, U256}; use sp_std::{ @@ -57,6 +58,10 @@ pub type BalanceOf = = >::AssetId; +/// Public types to use with the PrecompileSet +pub type IsLocal = ConstBool; +pub type IsForeign = ConstBool; + #[precompile_utils::generate_function_selector] #[derive(Debug, PartialEq)] pub enum Action { @@ -69,16 +74,26 @@ pub enum Action { Name = "name()", Symbol = "symbol()", Decimals = "decimals()", + Mint = "mint(address,uint256)", + Burn = "burn(address,uint256)", + Freeze = "freeze(address)", + Thaw = "thaw(address)", + FreezeAsset = "freeze_asset()", + ThawAsset = "thaw_asset()", + TransferOwnership = "transfer_ownership(address)", + SetTeam = "set_team(address,address,address)", + SetMetadata = "set_metadata(string,string,uint8)", + ClearMetadata = "clear_metadata()", } /// This trait ensure we can convert AccountIds to AssetIds /// We will require Runtime to have this trait implemented pub trait AccountIdAssetIdConversion { - // Get assetId from account - fn account_to_asset_id(account: Account) -> Option; + // Get assetId and prefix from account + fn account_to_asset_id(account: Account) -> Option<(Vec, AssetId)>; - // Get AccountId from AssetId - fn asset_id_to_account(asset_id: AssetId) -> Account; + // Get AccountId from AssetId and prefix + fn asset_id_to_account(prefix: &[u8], asset_id: AssetId) -> Account; } /// The following distribution has been decided for the precompiles @@ -95,11 +110,12 @@ pub trait AccountIdAssetIdConversion { /// This means that every address that starts with 0xFFFFFFFF will go through an additional db read, /// but the probability for this to happen is 2^-32 for random addresses -pub struct Erc20AssetsPrecompileSet( - PhantomData<(Runtime, Instance)>, +pub struct Erc20AssetsPrecompileSet( + PhantomData<(Runtime, IsLocal, Instance)>, ); -impl PrecompileSet for Erc20AssetsPrecompileSet +impl PrecompileSet + for Erc20AssetsPrecompileSet where Instance: 'static, Runtime: pallet_assets::Config + pallet_evm::Config + frame_system::Config, @@ -109,6 +125,7 @@ where BalanceOf: TryFrom + Into + EvmData, Runtime: AccountIdAssetIdConversion>, <::Call as Dispatchable>::Origin: OriginTrait, + IsLocal: Get, { fn execute( &self, @@ -118,17 +135,12 @@ where context: &Context, is_static: bool, ) -> Option> { - if let Some(asset_id) = + if let Some((_, asset_id)) = Runtime::account_to_asset_id(Runtime::AddressMapping::into_account_id(address)) { - // If the assetId has non-zero supply - // "total_supply" returns both 0 if the assetId does not exist or if the supply is 0 - // The assumption I am making here is that a 0 supply asset is not interesting from - // the perspective of the precompiles. Once pallet-assets has more publicly accesible - // storage we can use another function for this, like check_asset_existence. - // The other options is to check the asset existence in pallet-asset-manager, but - // this makes the precompiles dependent on such a pallet, which is not ideal - if !pallet_assets::Pallet::::total_supply(asset_id).is_zero() { + // We check maybe_total_supply. This function returns Some if the asset exists, + // which is all we care about at this point + if pallet_assets::Pallet::::maybe_total_supply(asset_id).is_some() { let result = { let mut gasometer = Gasometer::new(target_gas); let gasometer = &mut gasometer; @@ -154,6 +166,7 @@ where } match selector { + // Local and Foreign common Action::TotalSupply => Self::total_supply(asset_id, input, gasometer), Action::BalanceOf => Self::balance_of(asset_id, input, gasometer), Action::Allowance => Self::allowance(asset_id, input, gasometer), @@ -165,6 +178,21 @@ where Action::Name => Self::name(asset_id, gasometer), Action::Symbol => Self::symbol(asset_id, gasometer), Action::Decimals => Self::decimals(asset_id, gasometer), + // Only local + Action::Mint => Self::mint(asset_id, input, gasometer, context), + Action::Burn => Self::burn(asset_id, input, gasometer, context), + Action::Freeze => Self::freeze(asset_id, input, gasometer, context), + Action::Thaw => Self::thaw(asset_id, input, gasometer, context), + Action::FreezeAsset => Self::freeze_asset(asset_id, gasometer, context), + Action::ThawAsset => Self::thaw_asset(asset_id, gasometer, context), + Action::TransferOwnership => { + Self::transfer_ownership(asset_id, input, gasometer, context) + } + Action::SetTeam => Self::set_team(asset_id, input, gasometer, context), + Action::SetMetadata => { + Self::set_metadata(asset_id, input, gasometer, context) + } + Action::ClearMetadata => Self::clear_metadata(asset_id, gasometer, context), } }; return Some(result); @@ -174,30 +202,25 @@ where } fn is_precompile(&self, address: H160) -> bool { - if let Some(asset_id) = + if let Some((_, asset_id)) = Runtime::account_to_asset_id(Runtime::AddressMapping::into_account_id(address)) { - // If the assetId has non-zero supply - // "total_supply" returns both 0 if the assetId does not exist or if the supply is 0 - // The assumption I am making here is that a 0 supply asset is not interesting from - // the perspective of the precompiles. Once pallet-assets has more publicly accesible - // storage we can use another function for this, like check_asset_existence. - // The other options is to check the asset existence in pallet-asset-manager, but - // this makes the precompiles dependent on such a pallet, which is not ideal - !pallet_assets::Pallet::::total_supply(asset_id).is_zero() + // We check maybe_total_supply. This function returns Some if the asset exists, + // which is all we care about at this point + pallet_assets::Pallet::::maybe_total_supply(asset_id).is_some() } else { false } } } -impl Erc20AssetsPrecompileSet { +impl Erc20AssetsPrecompileSet { pub fn new() -> Self { Self(PhantomData) } } -impl Erc20AssetsPrecompileSet +impl Erc20AssetsPrecompileSet where Instance: 'static, Runtime: pallet_assets::Config + pallet_evm::Config + frame_system::Config, @@ -207,6 +230,7 @@ where BalanceOf: TryFrom + Into + EvmData, Runtime: AccountIdAssetIdConversion>, <::Call as Dispatchable>::Origin: OriginTrait, + IsLocal: Get, { fn total_supply( asset_id: AssetIdOf, @@ -522,4 +546,406 @@ where logs: Default::default(), }) } + + // From here: only for locals, we need to check whether we are in local assets otherwise fail + fn mint( + asset_id: AssetIdOf, + input: &mut EvmDataReader, + gasometer: &mut Gasometer, + context: &Context, + ) -> EvmResult { + if !IsLocal::get() { + return Err(gasometer.revert("unknown selector")); + } + + gasometer.record_log_costs_manual(3, 32)?; + + // Parse input. + input.expect_arguments(gasometer, 2)?; + + let to: H160 = input.read::
(gasometer)?.into(); + let amount = input.read::>(gasometer)?; + + // Build call with origin. + { + let origin = Runtime::AddressMapping::into_account_id(context.caller); + let to = Runtime::AddressMapping::into_account_id(to); + + // Dispatch call (if enough gas). + RuntimeHelper::::try_dispatch( + Some(origin).into(), + pallet_assets::Call::::mint { + id: asset_id, + beneficiary: Runtime::Lookup::unlookup(to), + amount, + }, + gasometer, + )?; + } + + // Build output. + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: gasometer.used_gas(), + output: EvmDataWriter::new().write(true).build(), + logs: LogsBuilder::new(context.address) + .log3( + SELECTOR_LOG_TRANSFER, + H160::default(), + to, + EvmDataWriter::new().write(amount).build(), + ) + .build(), + }) + } + + fn burn( + asset_id: AssetIdOf, + input: &mut EvmDataReader, + gasometer: &mut Gasometer, + context: &Context, + ) -> EvmResult { + if !IsLocal::get() { + return Err(gasometer.revert("unknown selector")); + } + + gasometer.record_log_costs_manual(3, 32)?; + + // Parse input. + input.expect_arguments(gasometer, 2)?; + + let to: H160 = input.read::
(gasometer)?.into(); + let amount = input.read::>(gasometer)?; + + // Build call with origin. + { + let origin = Runtime::AddressMapping::into_account_id(context.caller); + let to = Runtime::AddressMapping::into_account_id(to); + + // Dispatch call (if enough gas). + RuntimeHelper::::try_dispatch( + Some(origin).into(), + pallet_assets::Call::::burn { + id: asset_id, + who: Runtime::Lookup::unlookup(to), + amount, + }, + gasometer, + )?; + } + + // Build output. + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: gasometer.used_gas(), + output: EvmDataWriter::new().write(true).build(), + logs: LogsBuilder::new(context.address) + .log3( + SELECTOR_LOG_TRANSFER, + to, + H160::default(), + EvmDataWriter::new().write(amount).build(), + ) + .build(), + }) + } + + fn freeze( + asset_id: AssetIdOf, + input: &mut EvmDataReader, + gasometer: &mut Gasometer, + context: &Context, + ) -> EvmResult { + if !IsLocal::get() { + return Err(gasometer.revert("unknown selector")); + } + + // Parse input. + input.expect_arguments(gasometer, 1)?; + + let to: H160 = input.read::
(gasometer)?.into(); + + // Build call with origin. + { + let origin = Runtime::AddressMapping::into_account_id(context.caller); + let to = Runtime::AddressMapping::into_account_id(to); + + // Dispatch call (if enough gas). + RuntimeHelper::::try_dispatch( + Some(origin).into(), + pallet_assets::Call::::freeze { + id: asset_id, + who: Runtime::Lookup::unlookup(to), + }, + gasometer, + )?; + } + + // Build output. + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: gasometer.used_gas(), + output: EvmDataWriter::new().write(true).build(), + logs: Default::default(), + }) + } + + fn thaw( + asset_id: AssetIdOf, + input: &mut EvmDataReader, + gasometer: &mut Gasometer, + context: &Context, + ) -> EvmResult { + if !IsLocal::get() { + return Err(gasometer.revert("unknown selector")); + } + + // Parse input. + input.expect_arguments(gasometer, 1)?; + + let to: H160 = input.read::
(gasometer)?.into(); + + // Build call with origin. + { + let origin = Runtime::AddressMapping::into_account_id(context.caller); + let to = Runtime::AddressMapping::into_account_id(to); + + // Dispatch call (if enough gas). + RuntimeHelper::::try_dispatch( + Some(origin).into(), + pallet_assets::Call::::thaw { + id: asset_id, + who: Runtime::Lookup::unlookup(to), + }, + gasometer, + )?; + } + + // Build output. + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: gasometer.used_gas(), + output: EvmDataWriter::new().write(true).build(), + logs: Default::default(), + }) + } + + fn freeze_asset( + asset_id: AssetIdOf, + gasometer: &mut Gasometer, + context: &Context, + ) -> EvmResult { + if !IsLocal::get() { + return Err(gasometer.revert("unknown selector")); + } + + // Build call with origin. + { + let origin = Runtime::AddressMapping::into_account_id(context.caller); + + // Dispatch call (if enough gas). + RuntimeHelper::::try_dispatch( + Some(origin).into(), + pallet_assets::Call::::freeze_asset { id: asset_id }, + gasometer, + )?; + } + + // Build output. + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: gasometer.used_gas(), + output: EvmDataWriter::new().write(true).build(), + logs: Default::default(), + }) + } + + fn thaw_asset( + asset_id: AssetIdOf, + gasometer: &mut Gasometer, + context: &Context, + ) -> EvmResult { + if !IsLocal::get() { + return Err(gasometer.revert("unknown selector")); + } + + // Build call with origin. + { + let origin = Runtime::AddressMapping::into_account_id(context.caller); + + // Dispatch call (if enough gas). + RuntimeHelper::::try_dispatch( + Some(origin).into(), + pallet_assets::Call::::thaw_asset { id: asset_id }, + gasometer, + )?; + } + + // Build output. + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: gasometer.used_gas(), + output: EvmDataWriter::new().write(true).build(), + logs: Default::default(), + }) + } + + fn transfer_ownership( + asset_id: AssetIdOf, + input: &mut EvmDataReader, + gasometer: &mut Gasometer, + context: &Context, + ) -> EvmResult { + if !IsLocal::get() { + return Err(gasometer.revert("unknown selector")); + } + + // Parse input. + input.expect_arguments(gasometer, 1)?; + + let owner: H160 = input.read::
(gasometer)?.into(); + + // Build call with origin. + { + let origin = Runtime::AddressMapping::into_account_id(context.caller); + let owner = Runtime::AddressMapping::into_account_id(owner); + + // Dispatch call (if enough gas). + RuntimeHelper::::try_dispatch( + Some(origin).into(), + pallet_assets::Call::::transfer_ownership { + id: asset_id, + owner: Runtime::Lookup::unlookup(owner), + }, + gasometer, + )?; + } + + // Build output. + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: gasometer.used_gas(), + output: EvmDataWriter::new().write(true).build(), + logs: Default::default(), + }) + } + + fn set_team( + asset_id: AssetIdOf, + input: &mut EvmDataReader, + gasometer: &mut Gasometer, + context: &Context, + ) -> EvmResult { + if !IsLocal::get() { + return Err(gasometer.revert("unknown selector")); + } + + // Parse input. + input.expect_arguments(gasometer, 3)?; + + let issuer: H160 = input.read::
(gasometer)?.into(); + let admin: H160 = input.read::
(gasometer)?.into(); + let freezer: H160 = input.read::
(gasometer)?.into(); + + // Build call with origin. + { + let origin = Runtime::AddressMapping::into_account_id(context.caller); + let issuer = Runtime::AddressMapping::into_account_id(issuer); + let admin = Runtime::AddressMapping::into_account_id(admin); + let freezer = Runtime::AddressMapping::into_account_id(freezer); + + // Dispatch call (if enough gas). + RuntimeHelper::::try_dispatch( + Some(origin).into(), + pallet_assets::Call::::set_team { + id: asset_id, + issuer: Runtime::Lookup::unlookup(issuer), + admin: Runtime::Lookup::unlookup(admin), + freezer: Runtime::Lookup::unlookup(freezer), + }, + gasometer, + )?; + } + + // Build output. + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: gasometer.used_gas(), + output: EvmDataWriter::new().write(true).build(), + logs: Default::default(), + }) + } + + fn set_metadata( + asset_id: AssetIdOf, + input: &mut EvmDataReader, + gasometer: &mut Gasometer, + context: &Context, + ) -> EvmResult { + if !IsLocal::get() { + return Err(gasometer.revert("unknown selector")); + } + + // Parse input. + input.expect_arguments(gasometer, 3)?; + + let name: Bytes = input.read::(gasometer)?.into(); + let symbol: Bytes = input.read::(gasometer)?.into(); + let decimals: u8 = input.read::(gasometer)?.into(); + + // Build call with origin. + { + let origin = Runtime::AddressMapping::into_account_id(context.caller); + + // Dispatch call (if enough gas). + RuntimeHelper::::try_dispatch( + Some(origin).into(), + pallet_assets::Call::::set_metadata { + id: asset_id, + name: name.into(), + symbol: symbol.into(), + decimals, + }, + gasometer, + )?; + } + + // Build output. + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: gasometer.used_gas(), + output: EvmDataWriter::new().write(true).build(), + logs: Default::default(), + }) + } + + fn clear_metadata( + asset_id: AssetIdOf, + gasometer: &mut Gasometer, + context: &Context, + ) -> EvmResult { + if !IsLocal::get() { + return Err(gasometer.revert("unknown selector")); + } + + // Build call with origin. + { + let origin = Runtime::AddressMapping::into_account_id(context.caller); + + // Dispatch call (if enough gas). + RuntimeHelper::::try_dispatch( + Some(origin).into(), + pallet_assets::Call::::clear_metadata { id: asset_id }, + gasometer, + )?; + } + + // Build output. + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: gasometer.used_gas(), + output: EvmDataWriter::new().write(true).build(), + logs: Default::default(), + }) + } } diff --git a/precompiles/assets-erc20/src/mock.rs b/precompiles/assets-erc20/src/mock.rs index 3e3798faae..f52fd8bd96 100644 --- a/precompiles/assets-erc20/src/mock.rs +++ b/precompiles/assets-erc20/src/mock.rs @@ -38,6 +38,14 @@ pub type BlockNumber = u64; pub type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; pub type Block = frame_system::mocking::MockBlock; +/// The foreign asset precompile address prefix. Addresses that match against this prefix will +/// be routed to Erc20AssetsPrecompileSet being marked as foreign +pub const FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8; 4]; + +/// The local asset precompile address prefix. Addresses that match against this prefix will +/// be routed to Erc20AssetsPrecompileSet being marked as local +pub const LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8, 255u8, 255u8, 254u8]; + /// A simple account type. #[derive( Eq, @@ -59,7 +67,9 @@ pub enum Account { Bob, Charlie, Bogus, - AssetId(AssetId), + ForeignAssetId(AssetId), + LocalAssetId(AssetId), + Zero, } impl Default for Account { @@ -74,13 +84,18 @@ impl AddressMapping for Account { a if a == H160::repeat_byte(0xAA) => Self::Alice, a if a == H160::repeat_byte(0xBB) => Self::Bob, a if a == H160::repeat_byte(0xCC) => Self::Charlie, + a if a == H160::repeat_byte(0x00) => Self::Zero, _ => { let mut data = [0u8; 16]; let (prefix_part, id_part) = h160_account.as_fixed_bytes().split_at(4); if prefix_part == &[255u8; 4] { data.copy_from_slice(id_part); - return Self::AssetId(u128::from_be_bytes(data)); + return Self::ForeignAssetId(u128::from_be_bytes(data)); + } else if prefix_part == &[255u8, 255u8, 255u8, 254u8] { + data.copy_from_slice(id_part); + + return Self::LocalAssetId(u128::from_be_bytes(data)); } Self::Bogus } @@ -92,15 +107,25 @@ impl AddressMapping for Account { impl AccountIdAssetIdConversion for Runtime { /// The way to convert an account to assetId is by ensuring that the prefix is 0XFFFFFFFF /// and by taking the lowest 128 bits as the assetId - fn account_to_asset_id(account: AccountId) -> Option { + fn account_to_asset_id(account: AccountId) -> Option<(Vec, AssetId)> { match account { - Account::AssetId(asset_id) => Some(asset_id), + Account::ForeignAssetId(asset_id) => { + Some((FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX.to_vec(), asset_id)) + } + Account::LocalAssetId(asset_id) => { + Some((LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX.to_vec(), asset_id)) + } _ => None, } } - fn asset_id_to_account(asset_id: AssetId) -> AccountId { - Account::AssetId(asset_id) + // Not used for now + fn asset_id_to_account(prefix: &[u8], asset_id: AssetId) -> AccountId { + if prefix == LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX { + Account::LocalAssetId(asset_id) + } else { + Account::ForeignAssetId(asset_id) + } } } @@ -110,13 +135,21 @@ impl From for H160 { Account::Alice => H160::repeat_byte(0xAA), Account::Bob => H160::repeat_byte(0xBB), Account::Charlie => H160::repeat_byte(0xCC), - Account::AssetId(asset_id) => { + Account::Zero => H160::repeat_byte(0x00), + Account::ForeignAssetId(asset_id) => { let mut data = [0u8; 20]; let id_as_bytes = asset_id.to_be_bytes(); data[0..4].copy_from_slice(&[255u8; 4]); data[4..20].copy_from_slice(&id_as_bytes); H160::from_slice(&data) } + Account::LocalAssetId(asset_id) => { + let mut data = [0u8; 20]; + let id_as_bytes = asset_id.to_be_bytes(); + data[0..4].copy_from_slice(&[255u8, 255u8, 255u8, 254u8]); + data[4..20].copy_from_slice(&id_as_bytes); + H160::from_slice(&data) + } Account::Bogus => Default::default(), } } @@ -189,8 +222,7 @@ impl pallet_balances::Config for Runtime { } parameter_types! { - pub const PrecompilesValue: Erc20AssetsPrecompileSet = - Erc20AssetsPrecompileSet(PhantomData); + pub const PrecompilesValue: Precompiles = Precompiles(PhantomData); } impl pallet_evm::Config for Runtime { @@ -202,7 +234,7 @@ impl pallet_evm::Config for Runtime { type Currency = Balances; type Event = Event; type Runner = pallet_evm::runner::stack::Runner; - type PrecompilesType = Erc20AssetsPrecompileSet; + type PrecompilesType = Precompiles; type PrecompilesValue = PrecompilesValue; type ChainId = (); type OnChargeTransaction = (); @@ -212,6 +244,9 @@ impl pallet_evm::Config for Runtime { type WeightInfo = (); } +type ForeignAssetInstance = pallet_assets::Instance1; +type LocalAssetInstance = pallet_assets::Instance2; + // These parameters dont matter much as this will only be called by root with the forced arguments // No deposit is substracted with those methods parameter_types! { @@ -223,7 +258,24 @@ parameter_types! { pub const AssetAccountDeposit: Balance = 0; } -impl pallet_assets::Config for Runtime { +impl pallet_assets::Config for Runtime { + type Event = Event; + type Balance = Balance; + type AssetId = AssetId; + type Currency = Balances; + type ForceOrigin = EnsureRoot; + type AssetDeposit = AssetDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type AssetAccountDeposit = AssetAccountDeposit; + type WeightInfo = pallet_assets::weights::SubstrateWeight; +} + +impl pallet_assets::Config for Runtime { type Event = Event; type Balance = Balance; type AssetId = AssetId; @@ -249,9 +301,10 @@ construct_runtime!( { System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Assets: pallet_assets::{Pallet, Call, Storage, Event}, + ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event}, Evm: pallet_evm::{Pallet, Call, Storage, Event}, Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + LocalAssets: pallet_assets::::{Pallet, Call, Storage, Event} } ); @@ -288,3 +341,40 @@ impl ExtBuilder { ext } } + +#[derive(Default)] +pub struct Precompiles(PhantomData); + +impl PrecompileSet for Precompiles +where + Erc20AssetsPrecompileSet: PrecompileSet, + Erc20AssetsPrecompileSet: PrecompileSet, +{ + fn execute( + &self, + address: H160, + input: &[u8], + target_gas: Option, + context: &Context, + is_static: bool, + ) -> Option> { + match address { + // If the address matches asset prefix, the we route through the foreign asset precompile set + a if &a.to_fixed_bytes()[0..4] == LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX => { + Erc20AssetsPrecompileSet::::new() + .execute(address, input, target_gas, context, is_static) + } + // If the address matches asset prefix, the we route through the local asset precompile set + a if &a.to_fixed_bytes()[0..4] == FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX => { + Erc20AssetsPrecompileSet::::new() + .execute(address, input, target_gas, context, is_static) + } + _ => None, + } + } + + fn is_precompile(&self, address: H160) -> bool { + Erc20AssetsPrecompileSet::::new() + .is_precompile(address) + } +} diff --git a/precompiles/assets-erc20/src/tests.rs b/precompiles/assets-erc20/src/tests.rs index 9cf9d388d7..afd5dc05b9 100644 --- a/precompiles/assets-erc20/src/tests.rs +++ b/precompiles/assets-erc20/src/tests.rs @@ -25,36 +25,30 @@ use pallet_evm::PrecompileSet; use precompile_utils::{EvmDataWriter, LogsBuilder}; use sha3::{Digest, Keccak256}; -fn precompiles() -> Erc20AssetsPrecompileSet { +fn precompiles() -> Precompiles { PrecompilesValue::get() } #[test] fn selector_less_than_four_bytes() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( - Origin::signed(Account::Alice), - 0u128, - Account::Alice.into(), - 1000 - )); // This selector is only three bytes long when four are required. let bogus_selector = vec![1u8, 2u8, 3u8]; assert_matches!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &bogus_selector, None, &Context { - address: Account::AssetId(1u128).into(), + address: Account::ForeignAssetId(1u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0u32), }, @@ -69,28 +63,22 @@ fn selector_less_than_four_bytes() { #[test] fn no_selector_exists_but_length_is_right() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( - Origin::signed(Account::Alice), - 0u128, - Account::Alice.into(), - 1000 - )); let bogus_selector = vec![1u8, 2u8, 3u8, 4u8]; assert_matches!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &bogus_selector, None, &Context { - address: Account::AssetId(1u128).into(), + address: Account::ForeignAssetId(1u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0u32), }, @@ -131,14 +119,14 @@ fn get_total_supply() { .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( + assert_ok!(ForeignAssets::mint( Origin::signed(Account::Alice), 0u128, Account::Alice.into(), @@ -146,11 +134,11 @@ fn get_total_supply() { )); assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::TotalSupply).build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -172,14 +160,14 @@ fn get_balances_known_user() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( + assert_ok!(ForeignAssets::mint( Origin::signed(Account::Alice), 0u128, Account::Alice.into(), @@ -187,13 +175,13 @@ fn get_balances_known_user() { )); assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::BalanceOf) .write(Address(Account::Alice.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -215,28 +203,22 @@ fn get_balances_unknown_user() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( - Origin::signed(Account::Alice), - 0u128, - Account::Alice.into(), - 1000 - )); assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::BalanceOf) .write(Address(Account::Bob.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -258,14 +240,14 @@ fn approve() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( + assert_ok!(ForeignAssets::mint( Origin::signed(Account::Alice), 0u128, Account::Alice.into(), @@ -274,14 +256,14 @@ fn approve() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Approve) .write(Address(Account::Bob.into())) .write(U256::from(500)) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -291,7 +273,7 @@ fn approve() { exit_status: ExitSucceed::Returned, output: EvmDataWriter::new().write(true).build(), cost: 30832756u64, - logs: LogsBuilder::new(Account::AssetId(0u128).into()) + logs: LogsBuilder::new(Account::ForeignAssetId(0u128).into()) .log3( SELECTOR_LOG_APPROVAL, Account::Alice, @@ -310,14 +292,14 @@ fn approve_saturating() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( + assert_ok!(ForeignAssets::mint( Origin::signed(Account::Alice), 0u128, Account::Alice.into(), @@ -326,14 +308,14 @@ fn approve_saturating() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Approve) .write(Address(Account::Bob.into())) .write(U256::MAX) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -343,7 +325,7 @@ fn approve_saturating() { exit_status: ExitSucceed::Returned, output: EvmDataWriter::new().write(true).build(), cost: 30832756u64, - logs: LogsBuilder::new(Account::AssetId(0u128).into()) + logs: LogsBuilder::new(Account::ForeignAssetId(0u128).into()) .log3( SELECTOR_LOG_APPROVAL, Account::Alice, @@ -356,14 +338,14 @@ fn approve_saturating() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Allowance) .write(Address(Account::Alice.into())) .write(Address(Account::Bob.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -385,14 +367,14 @@ fn check_allowance_existing() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( + assert_ok!(ForeignAssets::mint( Origin::signed(Account::Alice), 0u128, Account::Alice.into(), @@ -400,14 +382,14 @@ fn check_allowance_existing() { )); precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Approve) .write(Address(Account::Bob.into())) .write(U256::from(500)) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -416,14 +398,14 @@ fn check_allowance_existing() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Allowance) .write(Address(Account::Alice.into())) .write(Address(Account::Bob.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -445,29 +427,23 @@ fn check_allowance_not_existing() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( - Origin::signed(Account::Alice), - 0u128, - Account::Alice.into(), - 1000 - )); assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Allowance) .write(Address(Account::Alice.into())) .write(Address(Account::Bob.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -489,14 +465,14 @@ fn transfer() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( + assert_ok!(ForeignAssets::mint( Origin::signed(Account::Alice), 0u128, Account::Alice.into(), @@ -505,14 +481,14 @@ fn transfer() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Transfer) .write(Address(Account::Bob.into())) .write(U256::from(400)) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -522,7 +498,7 @@ fn transfer() { exit_status: ExitSucceed::Returned, output: EvmDataWriter::new().write(true).build(), cost: 44001756u64, // 1 weight => 1 gas in mock - logs: LogsBuilder::new(Account::AssetId(0u128).into()) + logs: LogsBuilder::new(Account::ForeignAssetId(0u128).into()) .log3( SELECTOR_LOG_TRANSFER, Account::Alice, @@ -535,13 +511,13 @@ fn transfer() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::BalanceOf) .write(Address(Account::Bob.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Bob.into(), apparent_value: From::from(0), }, @@ -557,13 +533,13 @@ fn transfer() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::BalanceOf) .write(Address(Account::Alice.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -585,14 +561,14 @@ fn transfer_not_enough_founds() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( + assert_ok!(ForeignAssets::mint( Origin::signed(Account::Alice), 0u128, Account::Alice.into(), @@ -601,14 +577,14 @@ fn transfer_not_enough_founds() { assert_matches!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Transfer) .write(Address(Account::Charlie.into())) .write(U256::from(50)) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -628,14 +604,14 @@ fn transfer_from() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( + assert_ok!(ForeignAssets::mint( Origin::signed(Account::Alice), 0u128, Account::Alice.into(), @@ -643,14 +619,14 @@ fn transfer_from() { )); precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Approve) .write(Address(Account::Bob.into())) .write(U256::from(500)) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -659,7 +635,7 @@ fn transfer_from() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::TransferFrom) .write(Address(Account::Alice.into())) .write(Address(Account::Charlie.into())) @@ -667,7 +643,7 @@ fn transfer_from() { .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Bob.into(), // Bob is the one sending transferFrom! apparent_value: From::from(0), }, @@ -677,7 +653,7 @@ fn transfer_from() { exit_status: ExitSucceed::Returned, output: EvmDataWriter::new().write(true).build(), cost: 56268756u64, // 1 weight => 1 gas in mock - logs: LogsBuilder::new(Account::AssetId(0u128).into()) + logs: LogsBuilder::new(Account::ForeignAssetId(0u128).into()) .log3( SELECTOR_LOG_TRANSFER, Account::Alice, @@ -690,13 +666,13 @@ fn transfer_from() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::BalanceOf) .write(Address(Account::Alice.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -712,13 +688,13 @@ fn transfer_from() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::BalanceOf) .write(Address(Account::Bob.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Bob.into(), apparent_value: From::from(0), }, @@ -734,13 +710,13 @@ fn transfer_from() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::BalanceOf) .write(Address(Account::Charlie.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Charlie.into(), apparent_value: From::from(0), }, @@ -762,14 +738,14 @@ fn transfer_from_non_incremental_approval() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( + assert_ok!(ForeignAssets::mint( Origin::signed(Account::Alice), 0u128, Account::Alice.into(), @@ -779,14 +755,14 @@ fn transfer_from_non_incremental_approval() { // We first approve 500 assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Approve) .write(Address(Account::Bob.into())) .write(U256::from(500)) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -796,7 +772,7 @@ fn transfer_from_non_incremental_approval() { exit_status: ExitSucceed::Returned, output: EvmDataWriter::new().write(true).build(), cost: 30832756u64, - logs: LogsBuilder::new(Account::AssetId(0u128).into()) + logs: LogsBuilder::new(Account::ForeignAssetId(0u128).into()) .log3( SELECTOR_LOG_APPROVAL, Account::Alice, @@ -813,14 +789,14 @@ fn transfer_from_non_incremental_approval() { // need to clear the previous one assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Approve) .write(Address(Account::Bob.into())) .write(U256::from(300)) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -830,7 +806,7 @@ fn transfer_from_non_incremental_approval() { exit_status: ExitSucceed::Returned, output: EvmDataWriter::new().write(true).build(), cost: 62796756u64, - logs: LogsBuilder::new(Account::AssetId(0u128).into()) + logs: LogsBuilder::new(Account::ForeignAssetId(0u128).into()) .log3( SELECTOR_LOG_APPROVAL, Account::Alice, @@ -844,7 +820,7 @@ fn transfer_from_non_incremental_approval() { // This should fail, as now the new approved quantity is 300 assert_matches!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::TransferFrom) .write(Address(Account::Alice.into())) .write(Address(Account::Bob.into())) @@ -852,7 +828,7 @@ fn transfer_from_non_incremental_approval() { .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Bob.into(), // Bob is the one sending transferFrom! apparent_value: From::from(0), }, @@ -872,14 +848,14 @@ fn transfer_from_above_allowance() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( + assert_ok!(ForeignAssets::mint( Origin::signed(Account::Alice), 0u128, Account::Alice.into(), @@ -887,14 +863,14 @@ fn transfer_from_above_allowance() { )); precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Approve) .write(Address(Account::Bob.into())) .write(U256::from(300)) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -903,7 +879,7 @@ fn transfer_from_above_allowance() { assert_matches!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::TransferFrom) .write(Address(Account::Alice.into())) .write(Address(Account::Bob.into())) @@ -911,7 +887,7 @@ fn transfer_from_above_allowance() { .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Bob.into(), // Bob is the one sending transferFrom! apparent_value: From::from(0), }, @@ -931,14 +907,14 @@ fn transfer_from_self() { .with_balances(vec![(Account::Alice, 1000)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::mint( + assert_ok!(ForeignAssets::mint( Origin::signed(Account::Alice), 0u128, Account::Alice.into(), @@ -947,7 +923,7 @@ fn transfer_from_self() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::TransferFrom) .write(Address(Account::Alice.into())) .write(Address(Account::Bob.into())) @@ -955,7 +931,7 @@ fn transfer_from_self() { .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), // Alice sending transferFrom herself, no need for allowance. caller: Account::Alice.into(), apparent_value: From::from(0), @@ -966,7 +942,7 @@ fn transfer_from_self() { exit_status: ExitSucceed::Returned, output: EvmDataWriter::new().write(true).build(), cost: 44001756u64, // 1 weight => 1 gas in mock - logs: LogsBuilder::new(Account::AssetId(0u128).into()) + logs: LogsBuilder::new(Account::ForeignAssetId(0u128).into()) .log3( SELECTOR_LOG_TRANSFER, Account::Alice, @@ -979,13 +955,13 @@ fn transfer_from_self() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::BalanceOf) .write(Address(Account::Alice.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -1001,13 +977,13 @@ fn transfer_from_self() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::BalanceOf) .write(Address(Account::Bob.into())) .build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), caller: Account::Alice.into(), apparent_value: From::from(0), }, @@ -1029,14 +1005,14 @@ fn get_metadata() { .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) .build() .execute_with(|| { - assert_ok!(Assets::force_create( + assert_ok!(ForeignAssets::force_create( Origin::root(), 0u128, Account::Alice.into(), true, 1 )); - assert_ok!(Assets::force_set_metadata( + assert_ok!(ForeignAssets::force_set_metadata( Origin::root(), 0u128, b"TestToken".to_vec(), @@ -1044,20 +1020,14 @@ fn get_metadata() { 12, false )); - assert_ok!(Assets::mint( - Origin::signed(Account::Alice), - 0u128, - Account::Alice.into(), - 1000 - )); { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Name).build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), // Alice sending transferFrom herself, no need for allowance. caller: Account::Alice.into(), apparent_value: From::from(0), @@ -1076,11 +1046,11 @@ fn get_metadata() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Symbol).build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), // Alice sending transferFrom herself, no need for allowance. caller: Account::Alice.into(), apparent_value: From::from(0), @@ -1097,11 +1067,11 @@ fn get_metadata() { assert_eq!( precompiles().execute( - Account::AssetId(0u128).into(), + Account::ForeignAssetId(0u128).into(), &EvmDataWriter::new_with_selector(Action::Decimals).build(), None, &Context { - address: Account::AssetId(0u128).into(), + address: Account::ForeignAssetId(0u128).into(), // Alice sending transferFrom herself, no need for allowance. caller: Account::Alice.into(), apparent_value: From::from(0), @@ -1118,3 +1088,1035 @@ fn get_metadata() { }; }); } + +#[test] +fn local_functions_cannot_be_accessed_by_foreign_assets() { + ExtBuilder::default() + .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) + .build() + .execute_with(|| { + assert_ok!(ForeignAssets::force_create( + Origin::root(), + 0u128, + Account::Alice.into(), + true, + 1 + )); + assert_ok!(ForeignAssets::force_set_metadata( + Origin::root(), + 0u128, + b"TestToken".to_vec(), + b"Test".to_vec(), + 12, + false + )); + { + assert_matches!( + precompiles().execute( + Account::ForeignAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Mint) + .write(Address(Account::Bob.into())) + .write(U256::from(400)) + .build(), + None, + &Context { + address: Account::ForeignAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Err(PrecompileFailure::Revert { output, .. })) + if output == b"unknown selector" + ); + }; + { + assert_matches!( + precompiles().execute( + Account::ForeignAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Burn) + .write(Address(Account::Bob.into())) + .write(U256::from(400)) + .build(), + None, + &Context { + address: Account::ForeignAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Err(PrecompileFailure::Revert { output, .. })) + if output == b"unknown selector" + ); + }; + }); +} + +#[test] +fn mint_local_assets() { + ExtBuilder::default() + .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) + .build() + .execute_with(|| { + assert_ok!(LocalAssets::force_create( + Origin::root(), + 0u128, + Account::Alice.into(), + true, + 1 + )); + assert_ok!(LocalAssets::force_set_metadata( + Origin::root(), + 0u128, + b"TestToken".to_vec(), + b"Test".to_vec(), + 12, + false + )); + { + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Mint) + .write(Address(Account::Bob.into())) + .write(U256::from(400)) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 26633756u64, // 1 weight => 1 gas in mock + logs: LogsBuilder::new(Account::LocalAssetId(0u128).into()) + .log3( + SELECTOR_LOG_TRANSFER, + Account::Zero, + Account::Bob, + EvmDataWriter::new().write(U256::from(400)).build(), + ) + .build(), + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::BalanceOf) + .write(Address(Account::Bob.into())) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Bob.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(U256::from(400)).build(), + cost: Default::default(), + logs: Default::default(), + })) + ); + }; + }); +} + +#[test] +fn burn_local_assets() { + ExtBuilder::default() + .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) + .build() + .execute_with(|| { + assert_ok!(LocalAssets::force_create( + Origin::root(), + 0u128, + Account::Alice.into(), + true, + 1 + )); + assert_ok!(LocalAssets::force_set_metadata( + Origin::root(), + 0u128, + b"TestToken".to_vec(), + b"Test".to_vec(), + 12, + false + )); + assert_ok!(LocalAssets::mint( + Origin::signed(Account::Alice), + 0u128, + Account::Alice.into(), + 1000 + )); + { + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Burn) + .write(Address(Account::Alice.into())) + .write(U256::from(400)) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 30049756u64, // 1 weight => 1 gas in mock + logs: LogsBuilder::new(Account::LocalAssetId(0u128).into()) + .log3( + SELECTOR_LOG_TRANSFER, + Account::Alice, + Account::Zero, + EvmDataWriter::new().write(U256::from(400)).build(), + ) + .build(), + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::BalanceOf) + .write(Address(Account::Alice.into())) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(U256::from(600)).build(), + cost: Default::default(), + logs: Default::default(), + })) + ); + }; + }); +} + +#[test] +fn freeze_local_assets() { + ExtBuilder::default() + .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) + .build() + .execute_with(|| { + assert_ok!(LocalAssets::force_create( + Origin::root(), + 0u128, + Account::Alice.into(), + true, + 1 + )); + assert_ok!(LocalAssets::force_set_metadata( + Origin::root(), + 0u128, + b"TestToken".to_vec(), + b"Test".to_vec(), + 12, + false + )); + assert_ok!(LocalAssets::mint( + Origin::signed(Account::Alice), + 0u128, + Account::Bob.into(), + 1000 + )); + { + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Freeze) + .write(Address(Account::Bob.into())) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 18309000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + + assert_matches!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Transfer) + .write(Address(Account::Alice.into())) + .write(U256::from(400)) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Bob.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Err(PrecompileFailure::Revert { output: str, ..})) + if from_utf8(&str).unwrap() + .contains("Dispatched call failed with error: DispatchErrorWithPostInfo") + && from_utf8(&str).unwrap().contains("Frozen") + ); + }; + }); +} + +#[test] +fn thaw_local_assets() { + ExtBuilder::default() + .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) + .build() + .execute_with(|| { + assert_ok!(LocalAssets::force_create( + Origin::root(), + 0u128, + Account::Alice.into(), + true, + 1 + )); + assert_ok!(LocalAssets::force_set_metadata( + Origin::root(), + 0u128, + b"TestToken".to_vec(), + b"Test".to_vec(), + 12, + false + )); + assert_ok!(LocalAssets::mint( + Origin::signed(Account::Alice), + 0u128, + Account::Bob.into(), + 1000 + )); + { + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Freeze) + .write(Address(Account::Bob.into())) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 18309000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Thaw) + .write(Address(Account::Bob.into())) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 18290000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Transfer) + .write(Address(Account::Alice.into())) + .write(U256::from(400)) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Bob.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 44001756u64, // 1 weight => 1 gas in mock + logs: LogsBuilder::new(Account::LocalAssetId(0u128).into()) + .log3( + SELECTOR_LOG_TRANSFER, + Account::Bob, + Account::Alice, + EvmDataWriter::new().write(U256::from(400)).build(), + ) + .build(), + })) + ); + }; + }); +} + +#[test] +fn freeze_asset_local_asset() { + ExtBuilder::default() + .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) + .build() + .execute_with(|| { + assert_ok!(LocalAssets::force_create( + Origin::root(), + 0u128, + Account::Alice.into(), + true, + 1 + )); + assert_ok!(LocalAssets::force_set_metadata( + Origin::root(), + 0u128, + b"TestToken".to_vec(), + b"Test".to_vec(), + 12, + false + )); + assert_ok!(LocalAssets::mint( + Origin::signed(Account::Alice), + 0u128, + Account::Bob.into(), + 1000 + )); + { + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::FreezeAsset).build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 14744000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + + assert_matches!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Transfer) + .write(Address(Account::Alice.into())) + .write(U256::from(400)) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Bob.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Err(PrecompileFailure::Revert { output: str, ..})) + if from_utf8(&str).unwrap() + .contains("Dispatched call failed with error: DispatchErrorWithPostInfo") + && from_utf8(&str).unwrap().contains("Frozen") + ); + }; + }); +} + +#[test] +fn thaw_asset_local_assets() { + ExtBuilder::default() + .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) + .build() + .execute_with(|| { + assert_ok!(LocalAssets::force_create( + Origin::root(), + 0u128, + Account::Alice.into(), + true, + 1 + )); + assert_ok!(LocalAssets::force_set_metadata( + Origin::root(), + 0u128, + b"TestToken".to_vec(), + b"Test".to_vec(), + 12, + false + )); + assert_ok!(LocalAssets::mint( + Origin::signed(Account::Alice), + 0u128, + Account::Bob.into(), + 1000 + )); + { + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::FreezeAsset).build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 14744000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::ThawAsset).build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 14833000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Transfer) + .write(Address(Account::Alice.into())) + .write(U256::from(400)) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Bob.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 44001756u64, // 1 weight => 1 gas in mock + logs: LogsBuilder::new(Account::LocalAssetId(0u128).into()) + .log3( + SELECTOR_LOG_TRANSFER, + Account::Bob, + Account::Alice, + EvmDataWriter::new().write(U256::from(400)).build(), + ) + .build(), + })) + ); + }; + }); +} + +#[test] +fn transfer_ownership_local_assets() { + ExtBuilder::default() + .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) + .build() + .execute_with(|| { + assert_ok!(LocalAssets::force_create( + Origin::root(), + 0u128, + Account::Alice.into(), + true, + 1 + )); + assert_ok!(LocalAssets::force_set_metadata( + Origin::root(), + 0u128, + b"TestToken".to_vec(), + b"Test".to_vec(), + 12, + false + )); + { + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::TransferOwnership) + .write(Address(Account::Bob.into())) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 16654000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + + // Now Bob should be able to change ownership, and not Alice + assert_matches!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::TransferOwnership) + .write(Address(Account::Bob.into())) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Err(PrecompileFailure::Revert { output: str, ..})) + if from_utf8(&str).unwrap() + .contains("Dispatched call failed with error: DispatchErrorWithPostInfo") + && from_utf8(&str).unwrap().contains("NoPermission") + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::TransferOwnership) + .write(Address(Account::Alice.into())) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Bob.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 16654000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + }; + }); +} + +#[test] +fn set_team_local_assets() { + ExtBuilder::default() + .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) + .build() + .execute_with(|| { + assert_ok!(LocalAssets::force_create( + Origin::root(), + 0u128, + Account::Alice.into(), + true, + 1 + )); + assert_ok!(LocalAssets::force_set_metadata( + Origin::root(), + 0u128, + b"TestToken".to_vec(), + b"Test".to_vec(), + 12, + false + )); + { + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::SetTeam) + .write(Address(Account::Bob.into())) + .write(Address(Account::Bob.into())) + .write(Address(Account::Bob.into())) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 15351000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + + // Now Bob should be able to mint, and not Alice + assert_matches!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Mint) + .write(Address(Account::Bob.into())) + .write(U256::from(400)) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Err(PrecompileFailure::Revert { output: str, ..})) + if from_utf8(&str).unwrap() + .contains("Dispatched call failed with error: DispatchErrorWithPostInfo") + && from_utf8(&str).unwrap().contains("NoPermission") + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Mint) + .write(Address(Account::Bob.into())) + .write(U256::from(400)) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Bob.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 26633756u64, // 1 weight => 1 gas in mock + logs: LogsBuilder::new(Account::LocalAssetId(0u128).into()) + .log3( + SELECTOR_LOG_TRANSFER, + Account::Zero, + Account::Bob, + EvmDataWriter::new().write(U256::from(400)).build(), + ) + .build(), + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::BalanceOf) + .write(Address(Account::Bob.into())) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Bob.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(U256::from(400)).build(), + cost: Default::default(), + logs: Default::default(), + })) + ); + }; + }); +} + +#[test] +fn set_metadata() { + ExtBuilder::default() + .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) + .build() + .execute_with(|| { + assert_ok!(LocalAssets::force_create( + Origin::root(), + 0u128, + Account::Alice.into(), + true, + 1 + )); + assert_ok!(LocalAssets::force_set_metadata( + Origin::root(), + 0u128, + b"TestToken".to_vec(), + b"Test".to_vec(), + 12, + false + )); + { + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::SetMetadata) + .write::("TestToken".into()) + .write::("Test".into()) + .write::(12) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 27654000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Name).build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + // Alice sending transferFrom herself, no need for allowance. + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new() + .write::("TestToken".into()) + .build(), + cost: Default::default(), + logs: Default::default(), + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Symbol).build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + // Alice sending transferFrom herself, no need for allowance. + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write::("Test".into()).build(), + cost: Default::default(), + logs: Default::default(), + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Decimals).build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + // Alice sending transferFrom herself, no need for allowance. + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(12u8).build(), + cost: Default::default(), + logs: Default::default(), + })) + ); + }; + }); +} + +#[test] +fn clear_metadata() { + ExtBuilder::default() + .with_balances(vec![(Account::Alice, 1000), (Account::Bob, 2500)]) + .build() + .execute_with(|| { + assert_ok!(LocalAssets::force_create( + Origin::root(), + 0u128, + Account::Alice.into(), + true, + 1 + )); + assert_ok!(LocalAssets::force_set_metadata( + Origin::root(), + 0u128, + b"TestToken".to_vec(), + b"Test".to_vec(), + 12, + false + )); + { + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::SetMetadata) + .write::("TestToken".into()) + .write::("Test".into()) + .write::(12) + .build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 27654000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::ClearMetadata).build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 27710000u64, // 1 weight => 1 gas in mock + logs: vec![], + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Name).build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write::("".into()).build(), + cost: Default::default(), + logs: Default::default(), + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Symbol).build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write::("".into()).build(), + cost: Default::default(), + logs: Default::default(), + })) + ); + + assert_eq!( + precompiles().execute( + Account::LocalAssetId(0u128).into(), + &EvmDataWriter::new_with_selector(Action::Decimals).build(), + None, + &Context { + address: Account::LocalAssetId(0u128).into(), + caller: Account::Alice.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(0u8).build(), + cost: Default::default(), + logs: Default::default(), + })) + ); + }; + }); +} diff --git a/runtime/common/src/migrations.rs b/runtime/common/src/migrations.rs index 42118864eb..8931b865c6 100644 --- a/runtime/common/src/migrations.rs +++ b/runtime/common/src/migrations.rs @@ -425,7 +425,7 @@ where T: AssetManagerConfig, StatemineParaIdInfo: Get, StatemineAssetsPalletInfo: Get, - T::AssetType: Into> + From, + T::ForeignAssetType: Into> + From, { fn friendly_name(&self) -> &str { "MM_Asset_Manager_ChangeStateminePrefixes" @@ -563,7 +563,7 @@ impl GetMigrations for XcmMigrations where Runtime: xcm_transactor::Config + pallet_migrations::Config + pallet_asset_manager::Config, - ::AssetType: + ::ForeignAssetType: Into> + From, { fn get_migrations() -> Vec> { diff --git a/runtime/moonbase/src/asset_config.rs b/runtime/moonbase/src/asset_config.rs new file mode 100644 index 0000000000..755fe9fb04 --- /dev/null +++ b/runtime/moonbase/src/asset_config.rs @@ -0,0 +1,294 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! Asset configuration for Moonbase. +//! + +use super::{ + currency, xcm_config, AccountId, AssetId, AssetManager, Assets, Balance, Balances, Call, + CouncilInstance, Event, LocalAssets, Origin, Runtime, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, +}; + +use pallet_evm_precompile_assets_erc20::AccountIdAssetIdConversion; +use sp_runtime::traits::Hash as THash; + +use frame_support::{ + parameter_types, + traits::{ConstU128, EnsureOneOf}, + weights::{GetDispatchInfo, Weight}, +}; + +use frame_system::EnsureRoot; +use sp_core::{H160, H256}; + +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; + +use sp_std::{ + convert::{From, Into}, + prelude::*, +}; + +type ForeignAssetInstance = pallet_assets::Instance1; +type LocalAssetInstance = pallet_assets::Instance2; + +// For foreign assets, these parameters dont matter much +// as this will only be called by root with the forced arguments +// No deposit is substracted with those methods +// For local assets, they do matter. We use similar parameters +// to those in statemine (except for approval) +parameter_types! { + pub const AssetDeposit: Balance = 100 * currency::UNIT * currency::SUPPLY_FACTOR; + pub const ApprovalDeposit: Balance = 0; + pub const AssetsStringLimit: u32 = 50; + pub const MetadataDepositBase: Balance = currency::deposit(1,68); + pub const MetadataDepositPerByte: Balance = currency::deposit(0, 1); +} + +/// We allow root and Chain council to execute privileged asset operations. +pub type AssetsForceOrigin = EnsureOneOf< + EnsureRoot, + pallet_collective::EnsureProportionMoreThan, +>; + +// Foreign assets +impl pallet_assets::Config for Runtime { + type Event = Event; + type Balance = Balance; + type AssetId = AssetId; + type Currency = Balances; + type ForceOrigin = AssetsForceOrigin; + type AssetDeposit = AssetDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type AssetAccountDeposit = ConstU128<{ currency::deposit(1, 18) }>; + type WeightInfo = pallet_assets::weights::SubstrateWeight; +} + +// Local assets +impl pallet_assets::Config for Runtime { + type Event = Event; + type Balance = Balance; + type AssetId = AssetId; + type Currency = Balances; + type ForceOrigin = AssetsForceOrigin; + type AssetDeposit = AssetDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type AssetAccountDeposit = ConstU128<{ currency::deposit(1, 18) }>; + type WeightInfo = pallet_assets::weights::SubstrateWeight; +} + +// We instruct how to register the Assets +// In this case, we tell it to Create an Asset in pallet-assets +pub struct AssetRegistrar; +use frame_support::{pallet_prelude::DispatchResult, transactional}; + +impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { + #[transactional] + fn create_foreign_asset( + asset: AssetId, + min_balance: Balance, + metadata: AssetRegistrarMetadata, + is_sufficient: bool, + ) -> DispatchResult { + Assets::force_create( + Origin::root(), + asset, + AssetManager::account_id(), + is_sufficient, + min_balance, + )?; + + // TODO uncomment when we feel comfortable + /* + // The asset has been created. Let's put the revert code in the precompile address + let precompile_address = Runtime::asset_id_to_account(ASSET_PRECOMPILE_ADDRESS_PREFIX, asset); + pallet_evm::AccountCodes::::insert( + precompile_address, + vec![0x60, 0x00, 0x60, 0x00, 0xfd], + );*/ + + // Lastly, the metadata + Assets::force_set_metadata( + Origin::root(), + asset, + metadata.name, + metadata.symbol, + metadata.decimals, + metadata.is_frozen, + ) + } + + #[transactional] + fn create_local_asset( + asset: AssetId, + _creator: AccountId, + min_balance: Balance, + is_sufficient: bool, + owner: AccountId, + ) -> DispatchResult { + // We create with root, because we need to decide whether we want to create the asset + // as sufficient. Take into account this does not hold any reserved amount + // in pallet-assets + LocalAssets::force_create(Origin::root(), asset, owner, is_sufficient, min_balance)?; + + // No metadata needs to be set, as this can be set through regular calls + + // TODO: should we put the revert code? + // The asset has been created. Let's put the revert code in the precompile address + let precompile_address: H160 = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, asset).into(); + pallet_evm::AccountCodes::::insert( + precompile_address, + vec![0x60, 0x00, 0x60, 0x00, 0xfd], + ); + Ok(()) + } + + #[transactional] + fn destroy_foreign_asset( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> DispatchResult { + // First destroy the asset + Assets::destroy(Origin::root(), asset, asset_destroy_witness).map_err(|info| info.error)?; + + // We remove the EVM revert code + // This does not panick even if there is no code in the address + let precompile_address: H160 = + Runtime::asset_id_to_account(FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, asset).into(); + pallet_evm::AccountCodes::::remove(precompile_address); + Ok(()) + } + + #[transactional] + fn destroy_local_asset( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> DispatchResult { + // First destroy the asset + LocalAssets::destroy(Origin::root(), asset, asset_destroy_witness) + .map_err(|info| info.error)?; + + // We remove the EVM revert code + // This does not panick even if there is no code in the address + let precompile_address: H160 = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, asset).into(); + pallet_evm::AccountCodes::::remove(precompile_address); + Ok(()) + } + + fn destroy_asset_dispatch_info_weight( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> Weight { + // For us both of them (Foreign and Local) have the same annotated weight for a given + // witness + // We need to take the dispatch info from the destroy call, which is already annotated in + // the assets pallet + // Additionally, we need to add a DB write for removing the precompile revert code in the + // EVM + + // This is the dispatch info of destroy + let call = Call::Assets( + pallet_assets::Call::::destroy { + id: asset, + witness: asset_destroy_witness, + }, + ); + + // This is the db write + call.get_dispatch_info() + .weight + .saturating_add(::DbWeight::get().writes(1 as Weight)) + } +} + +pub struct LocalAssetIdCreator; +impl pallet_asset_manager::LocalAssetIdCreator for LocalAssetIdCreator { + fn create_asset_id_from_metadata(local_asset_counter: u128) -> AssetId { + // Our means of converting a local asset counter to an assetId + // We basically hash (local asset counter) + let mut result: [u8; 16] = [0u8; 16]; + let to_hash = local_asset_counter.encode(); + let hash: H256 = to_hash.using_encoded(::Hashing::hash); + result.copy_from_slice(&hash.as_fixed_bytes()[0..16]); + u128::from_le_bytes(result) + } +} + +#[derive(Clone, Default, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] +pub struct AssetRegistrarMetadata { + pub name: Vec, + pub symbol: Vec, + pub decimals: u8, + pub is_frozen: bool, +} + +impl pallet_asset_manager::Config for Runtime { + type Event = Event; + type Balance = Balance; + type AssetId = AssetId; + type AssetRegistrarMetadata = AssetRegistrarMetadata; + type ForeignAssetType = xcm_config::AssetType; + type AssetRegistrar = AssetRegistrar; + type ForeignAssetModifierOrigin = EnsureRoot; + type LocalAssetModifierOrigin = EnsureRoot; + type LocalAssetIdCreator = LocalAssetIdCreator; + type AssetDestroyWitness = pallet_assets::DestroyWitness; + type Currency = Balances; + type LocalAssetDeposit = AssetDeposit; + type WeightInfo = pallet_asset_manager::weights::SubstrateWeight; +} + +// Instruct how to go from an H160 to an AssetID +// We just take the lowest 128 bits +impl AccountIdAssetIdConversion for Runtime { + /// The way to convert an account to assetId is by ensuring that the prefix is 0XFFFFFFFF + /// and by taking the lowest 128 bits as the assetId + fn account_to_asset_id(account: AccountId) -> Option<(Vec, AssetId)> { + let h160_account: H160 = account.into(); + let mut data = [0u8; 16]; + let (prefix_part, id_part) = h160_account.as_fixed_bytes().split_at(4); + if prefix_part == FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX + || prefix_part == LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX + { + data.copy_from_slice(id_part); + let asset_id: AssetId = u128::from_be_bytes(data).into(); + Some((prefix_part.to_vec(), asset_id)) + } else { + None + } + } + + // The opposite conversion + fn asset_id_to_account(prefix: &[u8], asset_id: AssetId) -> AccountId { + let mut data = [0u8; 20]; + data[0..4].copy_from_slice(prefix); + data[4..20].copy_from_slice(&asset_id.to_be_bytes()); + AccountId::from(data) + } +} diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs index 1dfd081c33..791e685a3e 100644 --- a/runtime/moonbase/src/lib.rs +++ b/runtime/moonbase/src/lib.rs @@ -30,14 +30,15 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use cumulus_pallet_parachain_system::RelaychainBlockNumberProvider; use fp_rpc::TransactionStatus; -use pallet_evm_precompile_assets_erc20::AccountIdAssetIdConversion; use account::AccountId20; // Re-export required by get! macro. pub use frame_support::traits::Get; use frame_support::{ - construct_runtime, parameter_types, + construct_runtime, + pallet_prelude::DispatchResult, + parameter_types, traits::{ ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Contains, Currency as CurrencyT, EnsureOneOf, EqualPrivilegeOnly, FindAuthor, Imbalance, @@ -89,12 +90,14 @@ use sp_std::{ #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use xcm::latest::prelude::*; use nimbus_primitives::{CanAuthor, NimbusId}; mod precompiles; -use precompiles::{MoonbasePrecompiles, ASSET_PRECOMPILE_ADDRESS_PREFIX}; +pub use precompiles::{ + MoonbasePrecompiles, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, +}; use smallvec::smallvec; @@ -103,6 +106,7 @@ pub use sp_runtime::BuildStorage; pub type Precompiles = MoonbasePrecompiles; +pub mod asset_config; pub mod xcm_config; /// UNIT, the native token, uses 18 decimals of precision. @@ -390,33 +394,6 @@ impl FeeCalculator for FixedGasPrice { pub type SlowAdjustingFeeUpdate = TargetedFeeAdjustment; -// Instruct how to go from an H160 to an AssetID -// We just take the lowest 128 bits -impl AccountIdAssetIdConversion for Runtime { - /// The way to convert an account to assetId is by ensuring that the prefix is 0XFFFFFFFF - /// and by taking the lowest 128 bits as the assetId - fn account_to_asset_id(account: AccountId) -> Option { - let h160_account: H160 = account.into(); - let mut data = [0u8; 16]; - let (prefix_part, id_part) = h160_account.as_fixed_bytes().split_at(4); - if prefix_part == ASSET_PRECOMPILE_ADDRESS_PREFIX { - data.copy_from_slice(id_part); - let asset_id: AssetId = u128::from_be_bytes(data).into(); - Some(asset_id) - } else { - None - } - } - - // The opposite conversion - fn asset_id_to_account(asset_id: AssetId) -> AccountId { - let mut data = [0u8; 20]; - data[0..4].copy_from_slice(ASSET_PRECOMPILE_ADDRESS_PREFIX); - data[4..20].copy_from_slice(&asset_id.to_be_bytes()); - AccountId::from(data) - } -} - /// The author inherent provides an AccountId, but pallet evm needs an H160. /// This simple adapter makes the conversion for any types T, U such that T: Into pub struct FindAuthorAdapter(sp_std::marker::PhantomData<(T, U, Inner)>); @@ -912,102 +889,13 @@ impl pallet_migrations::Config for Runtime { ); } -parameter_types! { - pub const ExecutiveBody: BodyId = BodyId::Executive; -} - -/// We allow root and Chain council to execute privileged asset operations. -pub type AssetsForceOrigin = EnsureOneOf< - EnsureRoot, - pallet_collective::EnsureProportionMoreThan, ->; - -impl pallet_assets::Config for Runtime { - type Event = Event; - type Balance = Balance; - type AssetId = AssetId; - type Currency = Balances; - type ForceOrigin = AssetsForceOrigin; - // These parameters dont matter much as this will only be called by root with the forced arguments - // No deposit is substracted with those methods - type AssetDeposit = ConstU128<0>; - type MetadataDepositBase = ConstU128<0>; - type MetadataDepositPerByte = ConstU128<0>; - type ApprovalDeposit = ConstU128<0>; - type StringLimit = ConstU32<50>; - type Freezer = (); - type Extra = (); - type AssetAccountDeposit = ConstU128<{ currency::deposit(1, 18) }>; - type WeightInfo = pallet_assets::weights::SubstrateWeight; -} - -// We instruct how to register the Assets -// In this case, we tell it to Create an Asset in pallet-assets -pub struct AssetRegistrar; -use frame_support::{pallet_prelude::DispatchResult, transactional}; - -impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { - #[transactional] - fn create_asset( - asset: AssetId, - min_balance: Balance, - metadata: AssetRegistrarMetadata, - is_sufficient: bool, - ) -> DispatchResult { - Assets::force_create( - Origin::root(), - asset, - AssetManager::account_id(), - is_sufficient, - min_balance, - )?; - - // TODO uncomment when we feel comfortable - /* - // The asset has been created. Let's put the revert code in the precompile address - let precompile_address = Runtime::asset_id_to_account(asset); - pallet_evm::AccountCodes::::insert( - precompile_address, - vec![0x60, 0x00, 0x60, 0x00, 0xfd], - );*/ - - // Lastly, the metadata - Assets::force_set_metadata( - Origin::root(), - asset, - metadata.name, - metadata.symbol, - metadata.decimals, - metadata.is_frozen, - ) - } -} - -#[derive(Clone, Default, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] -pub struct AssetRegistrarMetadata { - pub name: Vec, - pub symbol: Vec, - pub decimals: u8, - pub is_frozen: bool, -} - -impl pallet_asset_manager::Config for Runtime { - type Event = Event; - type Balance = Balance; - type AssetId = AssetId; - type AssetRegistrarMetadata = AssetRegistrarMetadata; - type AssetType = xcm_config::AssetType; - type AssetRegistrar = AssetRegistrar; - type AssetModifierOrigin = EnsureRoot; - type WeightInfo = pallet_asset_manager::weights::SubstrateWeight; -} - /// Maintenance mode Call filter pub struct MaintenanceFilter; impl Contains for MaintenanceFilter { fn contains(c: &Call) -> bool { match c { Call::Assets(_) => false, + Call::LocalAssets(_) => false, Call::Balances(_) => false, Call::CrowdloanRewards(_) => false, Call::Ethereum(_) => false, @@ -1040,6 +928,16 @@ impl Contains for NormalFilter { pallet_assets::Call::cancel_approval { .. } => true, _ => false, }, + // We want to disable create, as we dont want users to be choosing the + // assetId of their choice + // We also disable destroy, as we want to route destroy through the + // asset-manager, which guarantees the removal both at the EVM and + // substrate side of things + Call::LocalAssets(method) => match method { + pallet_assets::Call::create { .. } => false, + pallet_assets::Call::destroy { .. } => false, + _ => true, + }, // We just want to enable this in case of live chains, since the default version // is populated at genesis Call::PolkadotXcm(method) => match method { @@ -1204,13 +1102,15 @@ construct_runtime! { CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 26, DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 27, PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 28, - Assets: pallet_assets::{Pallet, Call, Storage, Event} = 29, + Assets: pallet_assets::::{Pallet, Call, Storage, Event} = 29, XTokens: orml_xtokens::{Pallet, Call, Storage, Event} = 30, AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Event} = 31, Migrations: pallet_migrations::{Pallet, Storage, Config, Event} = 32, XcmTransactor: xcm_transactor::{Pallet, Call, Storage, Event} = 33, ProxyGenesisCompanion: pallet_proxy_genesis_companion::{Pallet, Config} = 34, BaseFee: pallet_base_fee::{Pallet, Call, Storage, Config, Event} = 35, + LocalAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 36, + } } diff --git a/runtime/moonbase/src/precompiles.rs b/runtime/moonbase/src/precompiles.rs index 1c5157f448..0a0abc5288 100644 --- a/runtime/moonbase/src/precompiles.rs +++ b/runtime/moonbase/src/precompiles.rs @@ -20,7 +20,7 @@ use moonbeam_relay_encoder::westend::WestendEncoder; use pallet_author_mapping_precompiles::AuthorMappingWrapper; use pallet_democracy_precompiles::DemocracyWrapper; use pallet_evm::{AddressMapping, Precompile, PrecompileResult, PrecompileSet}; -use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; +use pallet_evm_precompile_assets_erc20::{Erc20AssetsPrecompileSet, IsForeign, IsLocal}; use pallet_evm_precompile_balances_erc20::{Erc20BalancesPrecompile, Erc20Metadata}; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; @@ -63,8 +63,11 @@ impl Erc20Metadata for NativeErc20Metadata { } /// The asset precompile address prefix. Addresses that match against this prefix will be routed -/// to Erc20AssetsPrecompileSet -pub const ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8; 4]; +/// to Erc20AssetsPrecompileSet being marked as foreign +pub const FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8; 4]; +/// The asset precompile address prefix. Addresses that match against this prefix will be routed +/// to Erc20AssetsPrecompileSet being marked as local +pub const LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8, 255u8, 255u8, 254u8]; /// The PrecompileSet installed in the Moonbase runtime. /// We include the nine Istanbul precompiles @@ -100,7 +103,8 @@ where Erc20BalancesPrecompile: Precompile, // We require PrecompileSet here because indeed we are dealing with a set of precompiles // This precompile set does additional checks, e.g., total supply not being 0 - Erc20AssetsPrecompileSet: PrecompileSet, + Erc20AssetsPrecompileSet: PrecompileSet, + Erc20AssetsPrecompileSet: PrecompileSet, DemocracyWrapper: Precompile, XtokensWrapper: Precompile, RelayEncoderWrapper: Precompile, @@ -165,8 +169,13 @@ where input, target_gas, context, is_static, )), // If the address matches asset prefix, the we route through the asset precompile set - a if &a.to_fixed_bytes()[0..4] == ASSET_PRECOMPILE_ADDRESS_PREFIX => { - Erc20AssetsPrecompileSet::::new() + a if &a.to_fixed_bytes()[0..4] == FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX => { + Erc20AssetsPrecompileSet::::new() + .execute(address, input, target_gas, context, is_static) + } + // If the address matches asset prefix, the we route through the asset precompile set + a if &a.to_fixed_bytes()[0..4] == LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX => { + Erc20AssetsPrecompileSet::::new() .execute(address, input, target_gas, context, is_static) } _ => None, @@ -174,7 +183,10 @@ where } fn is_precompile(&self, address: H160) -> bool { Self::used_addresses().any(|x| x == R::AddressMapping::into_account_id(address)) - || Erc20AssetsPrecompileSet::::new().is_precompile(address) + || Erc20AssetsPrecompileSet::::new() + .is_precompile(address) + || Erc20AssetsPrecompileSet::::new() + .is_precompile(address) } } diff --git a/runtime/moonbase/src/xcm_config.rs b/runtime/moonbase/src/xcm_config.rs index 9efab7568e..4fa6f1c2bb 100644 --- a/runtime/moonbase/src/xcm_config.rs +++ b/runtime/moonbase/src/xcm_config.rs @@ -18,9 +18,9 @@ //! use super::{ - AccountId, AssetId, AssetManager, Assets, Balance, Balances, Call, DealWithFees, Event, Origin, - ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, Treasury, WeightToFee, XcmpQueue, - MAXIMUM_BLOCK_WEIGHT, + AccountId, AssetId, AssetManager, Assets, Balance, Balances, Call, DealWithFees, Event, + LocalAssets, Origin, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, Treasury, + WeightToFee, XcmpQueue, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, MAXIMUM_BLOCK_WEIGHT, }; use pallet_evm_precompile_assets_erc20::AccountIdAssetIdConversion; @@ -37,7 +37,7 @@ use sp_core::{H160, H256}; use xcm_builder::{ AccountKey20Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, - AllowTopLevelPaidExecutionFrom, ConvertedConcreteAssetId, + AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex, ConvertedConcreteAssetId, CurrencyAdapter as XcmCurrencyAdapter, EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, LocationInverter, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountKey20AsNative, SovereignSignedViaLocation, @@ -97,6 +97,31 @@ parameter_types! { OldAnchoringSelfReserve::get(), NewAnchoringSelfReserve::get() ]; + + // Old reanchor logic location for pallet assets + // We need to support both in case we talk to a chain not in 0.9.16 + // Or until we import https://github.com/open-web3-stack/open-runtime-module-library/pull/708 + // We will be able to remove this once we import the aforementioned change + // Indentified by thix prefix + generalIndex(assetId) + pub LocalAssetsPalletLocationOldReanchor: MultiLocation = MultiLocation { + parents:1, + interior: Junctions::X2( + Parachain(ParachainInfo::parachain_id().into()), + PalletInstance(::index() as u8) + ) + }; + + // New reanchor logic location for pallet assets + // This is the relative view of our local assets. This is the representation that will + // be considered canonical after we import + // https://github.com/open-web3-stack/open-runtime-module-library/pull/708 + // Indentified by thix prefix + generalIndex(assetId) + pub LocalAssetsPalletLocationNewReanchor: MultiLocation = MultiLocation { + parents:0, + interior: Junctions::X1( + PalletInstance(::index() as u8) + ) + }; } /// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used @@ -113,7 +138,8 @@ pub type LocationToAccountId = ( // The non-reserve fungible transactor type // It will use pallet-assets, and the Id will be matched against AsAssetType -pub type FungiblesTransactor = FungiblesAdapter< +// This is intended to match FOREIGN ASSETS +pub type ForeignFungiblesTransactor = FungiblesAdapter< // Use this fungibles implementation: Assets, // Use this currency when it is a fungible asset matching the given location or name: @@ -149,8 +175,72 @@ pub type LocalAssetTransactor = XcmCurrencyAdapter< // We dont allow teleport (), >; + +/// Means for transacting local assets that are not the native currency +/// This transactor uses the old reanchor logic +/// Remove once we import https://github.com/open-web3-stack/open-runtime-module-library/pull/708 +pub type LocalFungiblesTransactorOldReanchor = FungiblesAdapter< + // Use this fungibles implementation: + LocalAssets, + ( + ConvertedConcreteAssetId< + AssetId, + Balance, + // This just tells to convert an assetId into a GeneralIndex junction prepended + // by LocalAssetsPalletLocationOldReanchor + AsPrefixedGeneralIndex, + JustTry, + >, + ), + // Convert an XCM MultiLocation into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We dont want to allow teleporting assets + Nothing, + // The account to use for tracking teleports. + (), +>; + +/// Means for transacting local assets that are not the native currency +/// This transactor uses the new reanchor logic +pub type LocalFungiblesTransactorNewReanchor = FungiblesAdapter< + // Use this fungibles implementation: + LocalAssets, + // Use this currency when it is a fungible asset matching the given location or name: + ( + ConvertedConcreteAssetId< + AssetId, + Balance, + // This just tells to convert an assetId into a GeneralIndex junction prepended + // by LocalAssetsPalletLocationNewReanchor + AsPrefixedGeneralIndex, + JustTry, + >, + ), + // Convert an XCM MultiLocation into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We dont want to allow teleporting assets + Nothing, + // The account to use for tracking teleports. + (), +>; + // We use all transactors -pub type AssetTransactors = (LocalAssetTransactor, FungiblesTransactor); +// These correspond to +// SelfReserve asset, both pre and post 0.9.16 +// Foreign assets +// Local assets, both pre and post 0.9.16 +// We can remove the Old reanchor once +// we import https://github.com/open-web3-stack/open-runtime-module-library/pull/708 +pub type AssetTransactors = ( + LocalAssetTransactor, + ForeignFungiblesTransactor, + LocalFungiblesTransactorOldReanchor, + LocalFungiblesTransactorNewReanchor, +); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, /// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can @@ -382,18 +472,28 @@ impl From for AssetId { // Our currencyId. We distinguish for now between SelfReserve, and Others, defined by their Id. #[derive(Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] pub enum CurrencyId { + // Our native token SelfReserve, - OtherReserve(AssetId), + // Assets representing other chains native tokens + ForeignAsset(AssetId), + // Our local assets + LocalAssetReserve(AssetId), } - impl AccountIdToCurrencyId for Runtime { fn account_to_currency_id(account: AccountId) -> Option { match account { // the self-reserve currency is identified by the pallet-balances address a if a == H160::from_low_u64_be(2050).into() => Some(CurrencyId::SelfReserve), // the rest of the currencies, by their corresponding erc20 address - _ => Runtime::account_to_asset_id(account) - .map(|asset_id| CurrencyId::OtherReserve(asset_id)), + // We distinguish by prefix, and depending on it we create either + // Foreign or Local + _ => Runtime::account_to_asset_id(account).map(|(prefix, asset_id)| { + if prefix == FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX.to_vec() { + CurrencyId::ForeignAsset(asset_id) + } else { + CurrencyId::LocalAssetReserve(asset_id) + } + }), } } } @@ -416,7 +516,12 @@ where let multi: MultiLocation = OldAnchoringSelfReserve::get(); Some(multi) } - CurrencyId::OtherReserve(asset) => AssetXConverter::reverse_ref(asset).ok(), + CurrencyId::ForeignAsset(asset) => AssetXConverter::reverse_ref(asset).ok(), + CurrencyId::LocalAssetReserve(asset) => { + let mut location = LocalAssetsPalletLocationOldReanchor::get(); + location.push_interior(Junction::GeneralIndex(asset)).ok(); + Some(location) + } } } } diff --git a/runtime/moonbase/tests/common/mod.rs b/runtime/moonbase/tests/common/mod.rs index 9056ca82d7..993b121847 100644 --- a/runtime/moonbase/tests/common/mod.rs +++ b/runtime/moonbase/tests/common/mod.rs @@ -22,13 +22,13 @@ use frame_support::{ dispatch::Dispatchable, traits::{GenesisBuild, OnFinalize, OnInitialize}, }; +use moonbase_runtime::{asset_config::AssetRegistrarMetadata, xcm_config::AssetType}; pub use moonbase_runtime::{ currency::{GIGAWEI, SUPPLY_FACTOR, UNIT, WEI}, AccountId, AssetId, AssetManager, Assets, AuthorInherent, Balance, Balances, Call, - CrowdloanRewards, Ethereum, Event, Executive, FixedGasPrice, InflationInfo, ParachainStaking, - Range, Runtime, System, TransactionConverter, UncheckedExtrinsic, WEEKS, + CrowdloanRewards, Ethereum, Event, Executive, FixedGasPrice, InflationInfo, LocalAssets, + ParachainStaking, Range, Runtime, System, TransactionConverter, UncheckedExtrinsic, WEEKS, }; -use moonbase_runtime::{xcm_config::AssetType, AssetRegistrarMetadata}; use nimbus_primitives::{NimbusId, NIMBUS_ENGINE_ID}; use pallet_evm::GenesisAccount; use sp_core::{Encode, H160}; @@ -110,8 +110,8 @@ pub struct XcmAssetInitialization { pub struct ExtBuilder { // endowed accounts with balances balances: Vec<(AccountId, Balance)>, - // [asset, Vec] - assets: Vec<(AssetId, Vec<(AccountId, Balance)>)>, + // [asset, Vec, owner] + local_assets: Vec<(AssetId, Vec<(AccountId, Balance)>, AccountId)>, // [collator, amount] collators: Vec<(AccountId, Balance)>, // [delegator, collator, nomination_amount] @@ -136,7 +136,7 @@ impl Default for ExtBuilder { ExtBuilder { balances: vec![], delegations: vec![], - assets: vec![], + local_assets: vec![], collators: vec![], inflation: InflationInfo { expect: Range { @@ -188,8 +188,11 @@ impl ExtBuilder { self } - pub fn with_assets(mut self, assets: Vec<(AssetId, Vec<(AccountId, Balance)>)>) -> Self { - self.assets = assets; + pub fn with_local_assets( + mut self, + local_assets: Vec<(AssetId, Vec<(AccountId, Balance)>, AccountId)>, + ) -> Self { + self.local_assets = local_assets; self } @@ -288,21 +291,21 @@ impl ExtBuilder { let mut ext = sp_io::TestExternalities::new(t); - let assets = self.assets.clone(); + let local_assets = self.local_assets.clone(); let xcm_assets = self.xcm_assets.clone(); ext.execute_with(|| { - // If any assets specified, we create them here - for (asset_id, balances) in assets.clone() { - Assets::force_create(root_origin(), asset_id, ALICE.into(), true, 1).unwrap(); + // If any local assets specified, we create them here + for (asset_id, balances, owner) in local_assets.clone() { + LocalAssets::force_create(root_origin(), asset_id, owner, true, 1).unwrap(); for (account, balance) in balances { - Assets::mint(origin_of(ALICE.into()), asset_id, account, balance).unwrap(); + LocalAssets::mint(origin_of(owner.into()), asset_id, account, balance).unwrap(); } } // If any xcm assets specified, we register them here for xcm_asset_initialization in xcm_assets { let asset_id: AssetId = xcm_asset_initialization.asset_type.clone().into(); - AssetManager::register_asset( + AssetManager::register_foreign_asset( root_origin(), xcm_asset_initialization.asset_type, xcm_asset_initialization.metadata, diff --git a/runtime/moonbase/tests/integration_test.rs b/runtime/moonbase/tests/integration_test.rs index 03cc6b8c1d..50020ef871 100644 --- a/runtime/moonbase/tests/integration_test.rs +++ b/runtime/moonbase/tests/integration_test.rs @@ -25,14 +25,18 @@ use fp_evm::{Context, ExitSucceed, PrecompileOutput}; use frame_support::{ assert_noop, assert_ok, dispatch::Dispatchable, - traits::{fungible::Inspect, EnsureOrigin, PalletInfo, StorageInfo, StorageInfoTrait}, + traits::{ + fungible::Inspect, fungibles::Inspect as FungiblesInspect, EnsureOrigin, PalletInfo, + StorageInfo, StorageInfoTrait, + }, weights::{DispatchClass, Weight}, StorageHasher, Twox128, }; use moonbase_runtime::{ - currency::UNIT, get, xcm_config::AssetType, AccountId, AssetId, AssetManager, - AssetRegistrarMetadata, Assets, Balances, BaseFee, BlockWeights, Call, CrowdloanRewards, Event, - ParachainStaking, PolkadotXcm, Precompiles, Runtime, System, XTokens, XcmTransactor, + asset_config::AssetRegistrarMetadata, currency::UNIT, get, xcm_config::AssetType, AccountId, + AssetId, AssetManager, Assets, Balances, BaseFee, BlockWeights, Call, CrowdloanRewards, Event, + LocalAssets, ParachainStaking, PolkadotXcm, Precompiles, Runtime, System, XTokens, + XcmTransactor, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, }; use nimbus_primitives::NimbusId; @@ -49,7 +53,7 @@ use sha3::{Digest, Keccak256}; use sp_core::{crypto::UncheckedFrom, ByteArray, Pair, H160, U256}; use sp_runtime::{ traits::{Convert, One}, - DispatchError, ModuleError, + DispatchError, ModuleError, TokenError, }; use xcm::latest::prelude::*; @@ -1067,13 +1071,13 @@ fn asset_can_be_registered() { ExtBuilder::default().build().execute_with(|| { let source_location = AssetType::Xcm(MultiLocation::parent()); let source_id: moonbase_runtime::AssetId = source_location.clone().into(); - let asset_metadata = moonbase_runtime::AssetRegistrarMetadata { + let asset_metadata = AssetRegistrarMetadata { name: b"RelayToken".to_vec(), symbol: b"Relay".to_vec(), decimals: 12, is_frozen: false, }; - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( moonbase_runtime::Origin::root(), source_location, asset_metadata, @@ -1087,14 +1091,669 @@ fn asset_can_be_registered() { #[test] fn asset_erc20_precompiles_supply_and_balance() { ExtBuilder::default() - .with_assets(vec![(0u128, vec![(AccountId::from(ALICE), 1_000 * UNIT)])]) + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * UNIT)], + AccountId::from(ALICE), + )]) + .build() + .execute_with(|| { + // Assert the asset has been created with the correct supply + assert_eq!(LocalAssets::total_supply(0u128), 1_000 * UNIT); + + // Convert the assetId to its corresponding precompile address + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // The expected result for both total supply and balance of is the same, as only Alice + // holds balance + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(U256::from(1000 * UNIT)).build(), + cost: 1000, + logs: Default::default(), + })); + + // Access totalSupply through precompile. Important that the context is correct + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::TotalSupply).build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Access balanceOf through precompile + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::BalanceOf) + .write(EvmAddress(ALICE.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + }); +} + +#[test] +fn asset_erc20_precompiles_transfer() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * UNIT)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * UNIT), + (AccountId::from(BOB), 1_000 * UNIT), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for a transfer + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 23516u64, + logs: LogsBuilder::new(asset_precompile_address) + .log3( + SELECTOR_LOG_TRANSFER, + H160::from(ALICE), + H160::from(BOB), + EvmDataWriter::new().write(U256::from(400 * UNIT)).build(), + ) + .build(), + })); + + // Transfer tokens from Aice to Bob, 400 unit. + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Transfer) + .write(EvmAddress(BOB.into())) + .write(U256::from(400 * UNIT)) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Expected result for balanceOf BOB + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(U256::from(400 * UNIT)).build(), + cost: 1000, + logs: Default::default(), + })); + + // Make sure BOB has 400 unit + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::BalanceOf) + .write(EvmAddress(BOB.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: BOB.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + }); +} + +#[test] +fn asset_erc20_precompiles_approve() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * UNIT)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * UNIT), + (AccountId::from(BOB), 1_000 * UNIT), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 13989u64, + logs: LogsBuilder::new(asset_precompile_address) + .log3( + SELECTOR_LOG_APPROVAL, + H160::from(ALICE), + H160::from(BOB), + EvmDataWriter::new().write(U256::from(400 * UNIT)).build(), + ) + .build(), + })); + + // Aprove Bob for spending 400 unit from Alice + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Approve) + .write(EvmAddress(BOB.into())) + .write(U256::from(400 * UNIT)) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Expected result for transfer_from + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 29006u64, + logs: LogsBuilder::new(asset_precompile_address) + .log3( + SELECTOR_LOG_TRANSFER, + H160::from(ALICE), + H160::from(CHARLIE), + EvmDataWriter::new().write(U256::from(400 * UNIT)).build(), + ) + .build(), + })); + + // Transfer tokens from Alice to Charlie by using BOB as origin + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::TransferFrom) + .write(EvmAddress(ALICE.into())) + .write(EvmAddress(CHARLIE.into())) + .write(U256::from(400 * UNIT)) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: BOB.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Expected result for balance of CHARLIE + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(U256::from(400 * UNIT)).build(), + cost: 1000, + logs: Default::default(), + })); + + // Make sure CHARLIE has 400 unit + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::BalanceOf) + .write(EvmAddress(CHARLIE.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: CHARLIE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + }); +} + +#[test] +fn asset_erc20_precompiles_mint_burn() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * UNIT)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * UNIT), + (AccountId::from(BOB), 1_000 * UNIT), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 12821u64, + logs: LogsBuilder::new(asset_precompile_address) + .log3( + SELECTOR_LOG_TRANSFER, + H160::default(), + H160::from(BOB), + EvmDataWriter::new().write(U256::from(1000 * UNIT)).build(), + ) + .build(), + })); + + // Mint 1000 UNITS to BOB + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Mint) + .write(EvmAddress(BOB.into())) + .write(U256::from(1000 * UNIT)) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert the asset has been minted + assert_eq!(LocalAssets::total_supply(0u128), 2_000 * UNIT); + assert_eq!( + LocalAssets::balance(0u128, AccountId::from(BOB)), + 1_000 * UNIT + ); + + // Expected result for burn + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 12957u64, + logs: LogsBuilder::new(asset_precompile_address) + .log3( + SELECTOR_LOG_TRANSFER, + H160::from(BOB), + H160::default(), + EvmDataWriter::new().write(U256::from(500 * UNIT)).build(), + ) + .build(), + })); + + // Transfer tokens from Alice to Charlie by using BOB as origin + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Burn) + .write(EvmAddress(BOB.into())) + .write(U256::from(500 * UNIT)) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert the asset has been burnt + assert_eq!(LocalAssets::total_supply(0u128), 1_500 * UNIT); + assert_eq!( + LocalAssets::balance(0u128, AccountId::from(BOB)), + 500 * UNIT + ); + }); +} + +#[test] +fn asset_erc20_precompiles_freeze_thaw_account() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * UNIT)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * UNIT), + (AccountId::from(BOB), 1_000 * UNIT), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 6732u64, + logs: Default::default(), + })); + + // Freeze Account + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Freeze) + .write(EvmAddress(ALICE.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert account is frozen + assert_eq!( + LocalAssets::can_withdraw(0u128, &AccountId::from(ALICE), 1).into_result(), + Err(TokenError::Frozen.into()) + ); + + // Expected result for burn + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 6731u64, + logs: Default::default(), + })); + + // Thaw Account + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Thaw) + .write(EvmAddress(ALICE.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert account is not frozen + assert!(LocalAssets::can_withdraw(0u128, &AccountId::from(ALICE), 1) + .into_result() + .is_ok()); + }); +} + +#[test] +fn asset_erc20_precompiles_freeze_thaw_asset() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * UNIT)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * UNIT), + (AccountId::from(BOB), 1_000 * UNIT), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 5589u64, + logs: Default::default(), + })); + + // Freeze Asset + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::FreezeAsset).build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert account is frozen + assert_eq!( + LocalAssets::can_withdraw(0u128, &AccountId::from(ALICE), 1).into_result(), + Err(TokenError::Frozen.into()) + ); + + // Expected result for burn + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 5593u64, + logs: Default::default(), + })); + + // Thaw Asset + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::ThawAsset).build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert account is not frozen + assert!(LocalAssets::can_withdraw(0u128, &AccountId::from(ALICE), 1) + .into_result() + .is_ok()); + }); +} + +#[test] +fn asset_erc20_precompiles_freeze_transfer_ownership() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * UNIT)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * UNIT), + (AccountId::from(BOB), 1_000 * UNIT), + ]) .build() .execute_with(|| { - // Assert the asset has been created with the correct supply - assert_eq!(Assets::total_supply(0u128), 1_000 * UNIT); + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); - // Convert the assetId to its corresponding precompile address - let asset_precompile_address = Runtime::asset_id_to_account(0u128).into(); + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 6666u64, + logs: Default::default(), + })); + + // Transfer ownerhsip of an asset + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::TransferOwnership) + .write(EvmAddress(BOB.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // No clear way of testing BOB is new owner, other than doing a priviledged function + // e.g., transfer_ownership again + assert_ok!(LocalAssets::transfer_ownership( + origin_of(AccountId::from(BOB)), + 0u128, + AccountId::from(ALICE) + )); + }); +} + +#[test] +fn asset_erc20_precompiles_freeze_set_team() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * UNIT)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * UNIT), + (AccountId::from(BOB), 1_000 * UNIT), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 5614u64, + logs: Default::default(), + })); + + // Set Bob as issuer, admin and freezer + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::SetTeam) + .write(EvmAddress(BOB.into())) + .write(EvmAddress(BOB.into())) + .write(EvmAddress(BOB.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Bob should be able to mint, freeze, and thaw + assert_ok!(LocalAssets::mint( + origin_of(AccountId::from(BOB)), + 0u128, + AccountId::from(BOB), + 1_000 * UNIT + )); + assert_ok!(LocalAssets::freeze( + origin_of(AccountId::from(BOB)), + 0u128, + AccountId::from(ALICE) + )); + assert_ok!(LocalAssets::thaw( + origin_of(AccountId::from(BOB)), + 0u128, + AccountId::from(ALICE) + )); + }); +} + +#[test] +fn xcm_asset_erc20_precompiles_supply_and_balance() { + ExtBuilder::default() + .with_xcm_assets(vec![XcmAssetInitialization { + asset_type: AssetType::Xcm(MultiLocation::parent()), + metadata: AssetRegistrarMetadata { + name: b"RelayToken".to_vec(), + symbol: b"Relay".to_vec(), + decimals: 12, + is_frozen: false, + }, + balances: vec![(AccountId::from(ALICE), 1_000 * UNIT)], + is_sufficient: true, + }]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * UNIT), + (AccountId::from(BOB), 1_000 * UNIT), + ]) + .build() + .execute_with(|| { + // We have the assetId that corresponds to the relay chain registered + let relay_asset_id: AssetId = AssetType::Xcm(MultiLocation::parent()).into(); + + // Its address is + let asset_precompile_address = Runtime::asset_id_to_account( + FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + relay_asset_id, + ) + .into(); + + // Assert the asset has been created with the correct supply + assert_eq!(Assets::total_supply(relay_asset_id), 1_000 * UNIT); // The expected result for both total supply and balance of is the same, as only Alice // holds balance @@ -1142,16 +1801,34 @@ fn asset_erc20_precompiles_supply_and_balance() { } #[test] -fn asset_erc20_precompiles_transfer() { +fn xcm_asset_erc20_precompiles_transfer() { ExtBuilder::default() - .with_assets(vec![(0u128, vec![(AccountId::from(ALICE), 1_000 * UNIT)])]) + .with_xcm_assets(vec![XcmAssetInitialization { + asset_type: AssetType::Xcm(MultiLocation::parent()), + metadata: AssetRegistrarMetadata { + name: b"RelayToken".to_vec(), + symbol: b"Relay".to_vec(), + decimals: 12, + is_frozen: false, + }, + balances: vec![(AccountId::from(ALICE), 1_000 * UNIT)], + is_sufficient: true, + }]) .with_balances(vec![ (AccountId::from(ALICE), 2_000 * UNIT), (AccountId::from(BOB), 1_000 * UNIT), ]) .build() .execute_with(|| { - let asset_precompile_address = Runtime::asset_id_to_account(0u128).into(); + // We have the assetId that corresponds to the relay chain registered + let relay_asset_id: AssetId = AssetType::Xcm(MultiLocation::parent()).into(); + + // Its address is + let asset_precompile_address = Runtime::asset_id_to_account( + FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + relay_asset_id, + ) + .into(); // Expected result for a transfer let expected_result = Some(Ok(PrecompileOutput { @@ -1216,16 +1893,34 @@ fn asset_erc20_precompiles_transfer() { } #[test] -fn asset_erc20_precompiles_approve() { +fn xcm_asset_erc20_precompiles_approve() { ExtBuilder::default() - .with_assets(vec![(0u128, vec![(AccountId::from(ALICE), 1_000 * UNIT)])]) + .with_xcm_assets(vec![XcmAssetInitialization { + asset_type: AssetType::Xcm(MultiLocation::parent()), + metadata: AssetRegistrarMetadata { + name: b"RelayToken".to_vec(), + symbol: b"Relay".to_vec(), + decimals: 12, + is_frozen: false, + }, + balances: vec![(AccountId::from(ALICE), 1_000 * UNIT)], + is_sufficient: true, + }]) .with_balances(vec![ (AccountId::from(ALICE), 2_000 * UNIT), (AccountId::from(BOB), 1_000 * UNIT), ]) .build() .execute_with(|| { - let asset_precompile_address = Runtime::asset_id_to_account(0u128).into(); + // We have the assetId that corresponds to the relay chain registered + let relay_asset_id: AssetId = AssetType::Xcm(MultiLocation::parent()).into(); + + // Its address is + let asset_precompile_address = Runtime::asset_id_to_account( + FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + relay_asset_id, + ) + .into(); // Expected result for approve let expected_result = Some(Ok(PrecompileOutput { @@ -1351,7 +2046,11 @@ fn xtokens_precompiles_transfer() { let relay_asset_id: AssetId = AssetType::Xcm(MultiLocation::parent()).into(); // Its address is - let asset_precompile_address = Runtime::asset_id_to_account(relay_asset_id).into(); + let asset_precompile_address = Runtime::asset_id_to_account( + FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + relay_asset_id, + ) + .into(); // Alice has 1000 tokens. She should be able to send through precompile let destination = MultiLocation::new( @@ -1452,6 +2151,116 @@ fn xtokens_precompiles_transfer_multiasset() { }) } +#[test] +fn xtokens_precompiles_transfer_native() { + ExtBuilder::default() + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * UNIT), + (AccountId::from(BOB), 1_000 * UNIT), + ]) + .with_safe_xcm_version(2) + .build() + .execute_with(|| { + let xtokens_precompile_address = H160::from_low_u64_be(2052); + + // Its address is + let asset_precompile_address = H160::from_low_u64_be(2050); + + // Alice has 1000 tokens. She should be able to send through precompile + let destination = MultiLocation::new( + 1, + Junctions::X1(Junction::AccountId32 { + network: NetworkId::Any, + id: [1u8; 32], + }), + ); + + // We use the address of the asset as an identifier of the asset we want to transferS + assert_eq!( + Precompiles::new().execute( + xtokens_precompile_address, + &EvmDataWriter::new_with_selector(XtokensAction::Transfer) + .write(EvmAddress(asset_precompile_address)) + .write(U256::from(500 * UNIT)) + .write(destination.clone()) + .write(U256::from(4000000)) + .build(), + None, + &Context { + address: xtokens_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: 12000, + output: vec![], + logs: vec![] + })) + ); + }) +} + +#[test] +fn xtokens_precompile_transfer_local_asset() { + ExtBuilder::default() + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * UNIT), + (AccountId::from(BOB), 1_000 * UNIT), + ]) + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * UNIT)], + AccountId::from(ALICE), + )]) + .with_safe_xcm_version(2) + .build() + .execute_with(|| { + let xtokens_precompile_address = H160::from_low_u64_be(2052); + + // Its address is + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Alice has 1000 tokens. She should be able to send through precompile + let destination = MultiLocation::new( + 1, + Junctions::X1(Junction::AccountId32 { + network: NetworkId::Any, + id: [1u8; 32], + }), + ); + + // We use the address of the asset as an identifier of the asset we want to transferS + assert_eq!( + Precompiles::new().execute( + xtokens_precompile_address, + &EvmDataWriter::new_with_selector(XtokensAction::Transfer) + .write(EvmAddress(asset_precompile_address)) + .write(U256::from(500 * UNIT)) + .write(destination.clone()) + .write(U256::from(4000000)) + .build(), + None, + &Context { + address: xtokens_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: 12000, + output: vec![], + logs: vec![] + })) + ); + }) +} + fn run_with_system_weight(w: Weight, mut assertions: F) where F: FnMut() -> (), @@ -1645,7 +2454,7 @@ fn root_can_change_default_xcm_vers() { assert_noop!( XTokens::transfer( origin_of(AccountId::from(ALICE)), - moonbase_runtime::xcm_config::CurrencyId::OtherReserve(source_id), + moonbase_runtime::xcm_config::CurrencyId::ForeignAsset(source_id), 100_000_000_000_000, Box::new(xcm::VersionedMultiLocation::V1(dest.clone())), 4000000000 @@ -1662,7 +2471,7 @@ fn root_can_change_default_xcm_vers() { // Now transferring does not fail assert_ok!(XTokens::transfer( origin_of(AccountId::from(ALICE)), - moonbase_runtime::xcm_config::CurrencyId::OtherReserve(source_id), + moonbase_runtime::xcm_config::CurrencyId::ForeignAsset(source_id), 100_000_000_000_000, Box::new(xcm::VersionedMultiLocation::V1(dest)), 4000000000 @@ -1724,7 +2533,7 @@ fn transactor_cannot_use_more_than_max_weight() { origin_of(AccountId::from(ALICE)), moonbase_runtime::xcm_config::Transactors::Relay, 0, - moonbase_runtime::xcm_config::CurrencyId::OtherReserve(source_id), + moonbase_runtime::xcm_config::CurrencyId::ForeignAsset(source_id), // 20000 is the max 17000, vec![], diff --git a/runtime/moonbase/tests/xcm_mock/mod.rs b/runtime/moonbase/tests/xcm_mock/mod.rs index e2d4e834ba..e36e23f9d9 100644 --- a/runtime/moonbase/tests/xcm_mock/mod.rs +++ b/runtime/moonbase/tests/xcm_mock/mod.rs @@ -186,7 +186,10 @@ pub type StatemintChainPalletXcm = pallet_xcm::Pallet; pub type StatemintAssets = pallet_assets::Pallet; pub type ParachainPalletXcm = pallet_xcm::Pallet; -pub type Assets = pallet_assets::Pallet; +pub type Assets = pallet_assets::Pallet; +pub type LocalAssets = pallet_assets::Pallet; + +pub type Balances = pallet_balances::Pallet; pub type Treasury = pallet_treasury::Pallet; pub type AssetManager = pallet_asset_manager::Pallet; pub type XTokens = orml_xtokens::Pallet; diff --git a/runtime/moonbase/tests/xcm_mock/parachain.rs b/runtime/moonbase/tests/xcm_mock/parachain.rs index 6958ca6b70..ff16b9167b 100644 --- a/runtime/moonbase/tests/xcm_mock/parachain.rs +++ b/runtime/moonbase/tests/xcm_mock/parachain.rs @@ -19,7 +19,7 @@ use frame_support::{ construct_runtime, parameter_types, traits::{Everything, Get, Nothing, PalletInfoAccess}, - weights::Weight, + weights::{GetDispatchInfo, Weight}, PalletId, }; @@ -44,7 +44,7 @@ use xcm::latest::{ }; use xcm_builder::{ AccountKey20Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, - AllowTopLevelPaidExecutionFrom, ConvertedConcreteAssetId, + AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex, ConvertedConcreteAssetId, CurrencyAdapter as XcmCurrencyAdapter, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, FungiblesAdapter, LocationInverter, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountKey20AsNative, @@ -111,8 +111,11 @@ impl pallet_balances::Config for Runtime { type ReserveIdentifier = [u8; 8]; } +pub type ForeignAssetInstance = pallet_assets::Instance1; +pub type LocalAssetInstance = pallet_assets::Instance2; + parameter_types! { - pub const AssetDeposit: Balance = 0; // Does not really matter as this will be only called by root + pub const AssetDeposit: Balance = 10; // Does not really matter as this will be only called by root pub const ApprovalDeposit: Balance = 0; pub const AssetsStringLimit: u32 = 50; pub const MetadataDepositBase: Balance = 0; @@ -121,7 +124,24 @@ parameter_types! { pub const AssetAccountDeposit: Balance = 0; } -impl pallet_assets::Config for Runtime { +impl pallet_assets::Config for Runtime { + type Event = Event; + type Balance = Balance; + type AssetId = AssetId; + type Currency = Balances; + type ForceOrigin = EnsureRoot; + type AssetDeposit = AssetDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type AssetAccountDeposit = AssetAccountDeposit; + type WeightInfo = pallet_assets::weights::SubstrateWeight; +} + +impl pallet_assets::Config for Runtime { type Event = Event; type Balance = Balance; type AssetId = AssetId; @@ -177,7 +197,7 @@ parameter_types! { } // Instructing how incoming xcm assets will be handled -pub type FungiblesTransactor = FungiblesAdapter< +pub type ForeignFungiblesTransactor = FungiblesAdapter< // Use this fungibles implementation: Assets, // Use this currency when it is a fungible asset matching any of the locations in @@ -204,7 +224,8 @@ pub type FungiblesTransactor = FungiblesAdapter< pub type LocalAssetTransactor = XcmCurrencyAdapter< // Use this currency: Balances, - // Use this currency when it is a fungible asset matching the given location or name: + // Use this currency when it is a fungible asset matching any of the locations in + // SelfReserveRepresentations xcm_primitives::MultiIsConcrete, // We can convert the MultiLocations with our converter above: LocationToAccountId, @@ -214,8 +235,60 @@ pub type LocalAssetTransactor = XcmCurrencyAdapter< (), >; +/// Means for transacting local assets besides the native currency on this chain. +pub type LocalFungiblesTransactorOldReanchor = FungiblesAdapter< + // Use this fungibles implementation: + LocalAssets, + // Use this currency when it is a fungible asset matching the given location or name: + ( + ConvertedConcreteAssetId< + AssetId, + Balance, + AsPrefixedGeneralIndex, + JustTry, + >, + ), + // Convert an XCM MultiLocation into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We dont want to allow teleporting assets + Nothing, + // The account to use for tracking teleports. + (), +>; + +/// Means for transacting local assets besides the native currency on this chain. +pub type LocalFungiblesTransactorNewReanchor = FungiblesAdapter< + // Use this fungibles implementation: + LocalAssets, + // Use this currency when it is a fungible asset matching the given location or name: + ( + ConvertedConcreteAssetId< + AssetId, + Balance, + AsPrefixedGeneralIndex, + JustTry, + >, + ), + // Convert an XCM MultiLocation into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We dont want to allow teleporting assets + Nothing, + // The account to use for tracking teleports. + (), +>; + // These will be our transactors -pub type AssetTransactors = (LocalAssetTransactor, FungiblesTransactor); +// We use both transactors +pub type AssetTransactors = ( + LocalAssetTransactor, + ForeignFungiblesTransactor, + LocalFungiblesTransactorNewReanchor, + LocalFungiblesTransactorOldReanchor, +); pub type XcmRouter = super::ParachainXcmRouter; pub type Barrier = ( @@ -291,6 +364,21 @@ parameter_types! { OldAnchoringSelfReserve::get(), NewAnchoringSelfReserve::get() ]; + + pub LocalAssetsPalletLocationOldReanchor: MultiLocation = MultiLocation { + parents:1, + interior: Junctions::X2( + Parachain(MsgQueue::parachain_id().into()), + PalletInstance(::index() as u8) + ) + }; + + pub LocalAssetsPalletLocationNewReanchor: MultiLocation = MultiLocation { + parents:0, + interior: Junctions::X1( + PalletInstance(::index() as u8) + ) + }; } pub struct XcmConfig; impl Config for XcmConfig { @@ -328,7 +416,8 @@ impl cumulus_pallet_xcm::Config for Runtime { #[derive(Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] pub enum CurrencyId { SelfReserve, - OtherReserve(AssetId), + ForeignAsset(AssetId), + LocalAssetReserve(AssetId), } // How to convert from CurrencyId to MultiLocation @@ -349,7 +438,12 @@ where let multi: MultiLocation = OldAnchoringSelfReserve::get(); Some(multi) } - CurrencyId::OtherReserve(asset) => AssetXConverter::reverse_ref(asset).ok(), + CurrencyId::ForeignAsset(asset) => AssetXConverter::reverse_ref(asset).ok(), + CurrencyId::LocalAssetReserve(asset) => { + let mut location = LocalAssetsPalletLocationOldReanchor::get(); + location.push_interior(Junction::GeneralIndex(asset)).ok(); + Some(location) + } } } } @@ -363,6 +457,7 @@ parameter_types! { Parachain(MsgQueue::parachain_id().into()) ) }; + } parameter_type_with_key! { @@ -693,7 +788,7 @@ impl From for AssetId { pub struct AssetRegistrar; use frame_support::pallet_prelude::DispatchResult; impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { - fn create_asset( + fn create_foreign_asset( asset: AssetId, min_balance: Balance, metadata: AssetMetadata, @@ -716,6 +811,59 @@ impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { false, ) } + + fn create_local_asset( + asset: AssetId, + _creator: AccountId, + min_balance: Balance, + is_sufficient: bool, + owner: AccountId, + ) -> DispatchResult { + LocalAssets::force_create(Origin::root(), asset, owner, is_sufficient, min_balance)?; + + // TODO uncomment when we feel comfortable + /* + // The asset has been created. Let's put the revert code in the precompile address + let precompile_address = Runtime::asset_id_to_account(ASSET_PRECOMPILE_ADDRESS_PREFIX, asset); + pallet_evm::AccountCodes::::insert( + precompile_address, + vec![0x60, 0x00, 0x60, 0x00, 0xfd], + );*/ + Ok(()) + } + + fn destroy_foreign_asset( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> DispatchResult { + // First destroy the asset + Assets::destroy(Origin::root(), asset, asset_destroy_witness).map_err(|info| info.error)?; + + Ok(()) + } + + fn destroy_local_asset( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> DispatchResult { + // First destroy the asset + Assets::destroy(Origin::root(), asset, asset_destroy_witness).map_err(|info| info.error)?; + + Ok(()) + } + + fn destroy_asset_dispatch_info_weight( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> Weight { + let call = Call::Assets( + pallet_assets::Call::::destroy { + id: asset, + witness: asset_destroy_witness, + }, + ); + call.get_dispatch_info().weight + } } #[derive(Clone, Default, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] @@ -725,14 +873,32 @@ pub struct AssetMetadata { pub decimals: u8, } +pub struct LocalAssetIdCreator; +impl pallet_asset_manager::LocalAssetIdCreator for LocalAssetIdCreator { + fn create_asset_id_from_metadata(local_asset_counter: u128) -> AssetId { + // Our means of converting a local asset counter to an assetId + // We basically hash (local asset counter) + let mut result: [u8; 16] = [0u8; 16]; + let to_hash = local_asset_counter.encode(); + let hash: H256 = to_hash.using_encoded(::Hashing::hash); + result.copy_from_slice(&hash.as_fixed_bytes()[0..16]); + u128::from_le_bytes(result) + } +} + impl pallet_asset_manager::Config for Runtime { type Event = Event; type Balance = Balance; type AssetId = AssetId; type AssetRegistrarMetadata = AssetMetadata; - type AssetType = AssetType; + type ForeignAssetType = AssetType; type AssetRegistrar = AssetRegistrar; - type AssetModifierOrigin = EnsureRoot; + type ForeignAssetModifierOrigin = EnsureRoot; + type LocalAssetModifierOrigin = EnsureRoot; + type LocalAssetIdCreator = LocalAssetIdCreator; + type AssetDestroyWitness = pallet_assets::DestroyWitness; + type Currency = Balances; + type LocalAssetDeposit = AssetDeposit; type WeightInfo = (); } @@ -853,15 +1019,17 @@ construct_runtime!( XcmVersioner: mock_version_changer::{Pallet, Storage, Event}, PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, - Assets: pallet_assets::{Pallet, Storage, Event}, + Assets: pallet_assets::::{Pallet, Call, Storage, Event}, CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin}, XTokens: orml_xtokens::{Pallet, Call, Storage, Event}, AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Event}, XcmTransactor: xcm_transactor::{Pallet, Call, Storage, Event}, Treasury: pallet_treasury::{Pallet, Storage, Config, Event, Call}, + LocalAssets: pallet_assets::::{Pallet, Call, Storage, Event}, Timestamp: pallet_timestamp::{Pallet, Call, Storage}, EVM: pallet_evm::{Pallet, Call, Storage, Config, Event}, + } ); diff --git a/runtime/moonbase/tests/xcm_tests.rs b/runtime/moonbase/tests/xcm_tests.rs index 89fc46a6c5..422c8f6451 100644 --- a/runtime/moonbase/tests/xcm_tests.rs +++ b/runtime/moonbase/tests/xcm_tests.rs @@ -26,10 +26,13 @@ use xcm::{VersionedMultiLocation, WrapVersion}; use xcm_mock::*; use xcm_primitives::UtilityEncodeCall; +use pallet_asset_manager::LocalAssetIdCreator; use sp_std::boxed::Box; use xcm::latest::prelude::*; use xcm_executor::traits::Convert; use xcm_simulator::TestExt; +mod common; +use common::ExtBuilder; // Send a relay asset (like DOT) to a parachain A #[test] fn receive_relay_asset_from_relay() { @@ -44,7 +47,7 @@ fn receive_relay_asset_from_relay() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -98,7 +101,7 @@ fn send_relay_asset_to_relay() { // First send relay chain asset to Parachain like in previous test ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -150,7 +153,7 @@ fn send_relay_asset_to_relay() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 123, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -182,7 +185,7 @@ fn send_relay_asset_to_para_b() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), @@ -198,7 +201,7 @@ fn send_relay_asset_to_para_b() { }); ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -248,7 +251,7 @@ fn send_relay_asset_to_para_b() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -281,7 +284,7 @@ fn send_para_a_asset_to_para_b() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -346,7 +349,7 @@ fn send_para_a_asset_from_para_b_to_para_c() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), @@ -362,7 +365,7 @@ fn send_para_a_asset_from_para_b_to_para_c() { }); ParaC::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -426,7 +429,7 @@ fn send_para_a_asset_from_para_b_to_para_c() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 80 @@ -455,7 +458,7 @@ fn send_para_a_asset_to_para_b_and_back_to_para_a() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -518,7 +521,7 @@ fn send_para_a_asset_to_para_b_and_back_to_para_a() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 80 @@ -550,7 +553,7 @@ fn send_para_a_asset_to_para_b_and_back_to_para_a_with_new_reanchoring() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -664,7 +667,7 @@ fn receive_relay_asset_with_trader() { // we know later we will divide by 1e12 // Lets put 1e6 as units per second ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -723,7 +726,7 @@ fn send_para_a_asset_to_para_b_with_trader() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -797,7 +800,7 @@ fn send_para_a_asset_to_para_b_with_trader_and_fee() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -872,7 +875,7 @@ fn error_when_not_paying_enough() { // we know later we will divide by 1e12 // Lets put 1e6 as units per second ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -920,7 +923,7 @@ fn transact_through_derivative_multilocation() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -992,7 +995,7 @@ fn transact_through_derivative_multilocation() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -1074,7 +1077,7 @@ fn transact_through_sovereign() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1141,7 +1144,7 @@ fn transact_through_sovereign() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -1223,7 +1226,7 @@ fn test_automatic_versioning_on_runtime_upgrade_with_relay() { // register relay asset in parachain A and set XCM version to 1 ParaA::execute_with(|| { parachain::XcmVersioner::set_version(1); - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1373,7 +1376,7 @@ fn test_automatic_versioning_on_runtime_upgrade_with_para_b() { // Let's try with v0 parachain::XcmVersioner::set_version(0); - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1506,7 +1509,7 @@ fn receive_asset_with_no_sufficients_not_possible_if_non_existent_account() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1584,7 +1587,7 @@ fn receive_assets_with_sufficients_true_allows_non_funded_account_to_receive_ass }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1644,7 +1647,7 @@ fn evm_account_receiving_assets_should_handle_sufficients_ref_count() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1707,7 +1710,7 @@ fn empty_account_should_not_be_reset() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1815,7 +1818,7 @@ fn test_statemint_like() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), @@ -1886,7 +1889,7 @@ fn test_statemint_like() { assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 123, Box::new(VersionedMultiLocation::V1(dest)), 8000 @@ -1924,7 +1927,7 @@ fn test_statemint_like_prefix_change() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), @@ -2023,6 +2026,246 @@ fn test_statemint_like_prefix_change() { }); } +#[test] +fn send_para_a_local_asset_to_para_b() { + ExtBuilder::default().build().execute_with(|| { + MockNet::reset(); + + let asset_id = parachain::LocalAssetIdCreator::create_asset_id_from_metadata(0); + let para_a_local_asset = MultiLocation::new( + 1, + X3(Parachain(1), PalletInstance(11u8), GeneralIndex(asset_id)), + ); + let source_location = parachain::AssetType::Xcm(para_a_local_asset); + let source_id: parachain::AssetId = source_location.clone().into(); + + let asset_metadata = parachain::AssetMetadata { + name: b"ParaALocalAsset".to_vec(), + symbol: b"ParaALocalAsset".to_vec(), + decimals: 12, + }; + + ParaA::execute_with(|| { + assert_ok!(AssetManager::register_local_asset( + parachain::Origin::root(), + PARAALICE.into(), + PARAALICE.into(), + true, + 1 + )); + + assert_ok!(LocalAssets::mint( + parachain::Origin::signed(PARAALICE.into()), + asset_id, + PARAALICE.into(), + 300000000000000 + )); + }); + + ParaB::execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( + parachain::Origin::root(), + source_location.clone(), + asset_metadata, + 1u128, + true + )); + assert_ok!(AssetManager::set_asset_units_per_second( + parachain::Origin::root(), + source_location, + 0u128, + 0 + )); + }); + + let dest = MultiLocation { + parents: 1, + interior: X2( + Parachain(2), + AccountKey20 { + network: NetworkId::Any, + key: PARAALICE.into(), + }, + ), + }; + + ParaA::execute_with(|| { + // free execution, full amount received + assert_ok!(XTokens::transfer( + parachain::Origin::signed(PARAALICE.into()), + parachain::CurrencyId::LocalAssetReserve(asset_id), + 100, + Box::new(VersionedMultiLocation::V1(dest)), + 800000 + )); + }); + + ParaB::execute_with(|| { + // free execution, full amount received + assert_eq!(Assets::balance(source_id, &PARAALICE.into()), 100); + }); + }); +} + +#[test] +fn send_para_a_local_asset_to_para_b_and_send_it_back_together_with_some_dev() { + ExtBuilder::default().build().execute_with(|| { + MockNet::reset(); + + let asset_id = parachain::LocalAssetIdCreator::create_asset_id_from_metadata(0); + let para_a_local_asset = MultiLocation::new( + 1, + X3(Parachain(1), PalletInstance(11u8), GeneralIndex(asset_id)), + ); + let source_location_local_asset = parachain::AssetType::Xcm(para_a_local_asset); + let source_id_local_asset: parachain::AssetId = source_location_local_asset.clone().into(); + + let asset_metadata_local_asset = parachain::AssetMetadata { + name: b"ParaALocalAsset".to_vec(), + symbol: b"ParaALocalAsset".to_vec(), + decimals: 12, + }; + + let para_a_balances = MultiLocation::new(1, X2(Parachain(1), PalletInstance(1u8))); + let source_location_balances = parachain::AssetType::Xcm(para_a_balances); + let source_id_balances: parachain::AssetId = source_location_balances.clone().into(); + + let asset_metadata_balances = parachain::AssetMetadata { + name: b"ParaAToken".to_vec(), + symbol: b"ParaA".to_vec(), + decimals: 18, + }; + + ParaB::execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( + parachain::Origin::root(), + source_location_local_asset.clone(), + asset_metadata_local_asset, + 1u128, + true + )); + assert_ok!(AssetManager::set_asset_units_per_second( + parachain::Origin::root(), + source_location_local_asset, + 0u128, + 0 + )); + + assert_ok!(AssetManager::register_foreign_asset( + parachain::Origin::root(), + source_location_balances.clone(), + asset_metadata_balances, + 1u128, + true + )); + assert_ok!(AssetManager::set_asset_units_per_second( + parachain::Origin::root(), + source_location_balances, + 0u128, + 1 + )); + }); + + ParaA::execute_with(|| { + assert_ok!(AssetManager::register_local_asset( + parachain::Origin::root(), + PARAALICE.into(), + PARAALICE.into(), + true, + 1 + )); + + assert_ok!(LocalAssets::mint( + parachain::Origin::signed(PARAALICE.into()), + asset_id, + PARAALICE.into(), + 300000000000000 + )); + }); + + let dest = MultiLocation { + parents: 1, + interior: X2( + Parachain(2), + AccountKey20 { + network: NetworkId::Any, + key: PARAALICE.into(), + }, + ), + }; + + ParaA::execute_with(|| { + // free execution, full amount received + assert_ok!(XTokens::transfer_multicurrencies( + parachain::Origin::signed(PARAALICE.into()), + vec![ + (parachain::CurrencyId::LocalAssetReserve(asset_id), 100), + (parachain::CurrencyId::SelfReserve, 1000000) + ], + 0, + Box::new(VersionedMultiLocation::V1(dest)), + 800000 + )); + }); + + let mut alith_balance_asset_before = 0; + let mut alith_balance_native_token_before = 0; + + ParaA::execute_with(|| { + alith_balance_asset_before = LocalAssets::balance(asset_id, &PARAALICE.into()); + alith_balance_native_token_before = Balances::free_balance(&PARAALICE.into()); + }); + + let new_dest = MultiLocation { + parents: 1, + interior: X2( + Parachain(1), + AccountKey20 { + network: NetworkId::Any, + key: PARAALICE.into(), + }, + ), + }; + + ParaB::execute_with(|| { + // free execution, full amount received + assert_eq!( + Assets::balance(source_id_local_asset, &PARAALICE.into()), + 100 + ); + assert_eq!( + Assets::balance(source_id_balances, &PARAALICE.into()), + 1000000 + ); + + // free execution, full amount received + assert_ok!(XTokens::transfer_multicurrencies( + parachain::Origin::signed(PARAALICE.into()), + vec![ + (parachain::CurrencyId::ForeignAsset(source_id_balances), 4), + ( + parachain::CurrencyId::ForeignAsset(source_id_local_asset), + 50 + ) + ], + 0, + Box::new(VersionedMultiLocation::V1(new_dest)), + 4 + )); + }); + + ParaA::execute_with(|| { + let alith_balance_asset_after = LocalAssets::balance(asset_id, &PARAALICE.into()); + let alith_balance_native_token_after = Balances::free_balance(&PARAALICE.into()); + assert_eq!(alith_balance_asset_after, alith_balance_asset_before + 50); + assert_eq!( + alith_balance_native_token_before, + alith_balance_native_token_after + ); + }); + }); +} + use parity_scale_codec::{Decode, Encode}; use sp_io::hashing::blake2_256; diff --git a/runtime/moonbeam/src/asset_config.rs b/runtime/moonbeam/src/asset_config.rs new file mode 100644 index 0000000000..831ea62993 --- /dev/null +++ b/runtime/moonbeam/src/asset_config.rs @@ -0,0 +1,224 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! Asset configuration for Moonbase. +//! + +use super::{ + currency, xcm_config, AccountId, AssetId, AssetManager, Assets, Balance, Balances, Call, + CouncilInstance, Event, Origin, Runtime, ASSET_PRECOMPILE_ADDRESS_PREFIX, +}; + +use pallet_evm_precompile_assets_erc20::AccountIdAssetIdConversion; +use sp_runtime::traits::Hash as THash; + +use frame_support::{ + parameter_types, + traits::{ConstU128, EnsureOneOf}, + weights::{GetDispatchInfo, Weight}, +}; + +use frame_system::EnsureRoot; +use sp_core::{H160, H256}; + +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; + +use sp_std::{ + convert::{From, Into}, + prelude::*, +}; + +// For foreign assets, these parameters dont matter much +// as this will only be called by root with the forced arguments +// No deposit is substracted with those methods +// For local assets, they do matter. We use similar parameters +// to those in statemine (except for approval) +parameter_types! { + pub const AssetDeposit: Balance = 100 * currency::GLMR * currency::SUPPLY_FACTOR; + pub const ApprovalDeposit: Balance = 0; + pub const AssetsStringLimit: u32 = 50; + pub const MetadataDepositBase: Balance = currency::deposit(1,68); + pub const MetadataDepositPerByte: Balance = currency::deposit(0, 1); +} + +/// We allow root and Chain council to execute privileged asset operations. +pub type AssetsForceOrigin = EnsureOneOf< + EnsureRoot, + pallet_collective::EnsureProportionMoreThan, +>; + +impl pallet_assets::Config for Runtime { + type Event = Event; + type Balance = Balance; + type AssetId = AssetId; + type Currency = Balances; + type ForceOrigin = AssetsForceOrigin; + type AssetDeposit = AssetDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type AssetAccountDeposit = ConstU128<{ currency::deposit(1, 18) }>; + type WeightInfo = pallet_assets::weights::SubstrateWeight; +} + +// We instruct how to register the Assets +// In this case, we tell it to Create an Asset in pallet-assets +pub struct AssetRegistrar; +use frame_support::{pallet_prelude::DispatchResult, transactional}; + +impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { + #[transactional] + fn create_foreign_asset( + asset: AssetId, + min_balance: Balance, + metadata: AssetRegistrarMetadata, + is_sufficient: bool, + ) -> DispatchResult { + Assets::force_create( + Origin::root(), + asset, + AssetManager::account_id(), + is_sufficient, + min_balance, + )?; + + // TODO uncomment when we feel comfortable + /* + // The asset has been created. Let's put the revert code in the precompile address + let precompile_address = Runtime::asset_id_to_account(asset); + pallet_evm::AccountCodes::::insert( + precompile_address, + vec![0x60, 0x00, 0x60, 0x00, 0xfd], + );*/ + + // Lastly, the metadata + Assets::force_set_metadata( + Origin::root(), + asset, + metadata.name, + metadata.symbol, + metadata.decimals, + metadata.is_frozen, + ) + } + + #[transactional] + fn destroy_foreign_asset( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> DispatchResult { + // First destroy the asset + Assets::destroy(Origin::root(), asset, asset_destroy_witness).map_err(|info| info.error)?; + + // We remove the EVM revert code + // This does not panick even if there is no code in the address + let precompile_address: H160 = + Runtime::asset_id_to_account(ASSET_PRECOMPILE_ADDRESS_PREFIX, asset).into(); + pallet_evm::AccountCodes::::remove(precompile_address); + Ok(()) + } + + fn destroy_asset_dispatch_info_weight( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> Weight { + // For us both of them (Foreign and Local) have the same annotated weight for a given + // witness + // We need to take the dispatch info from the destroy call, which is already annotated in + // the assets pallet + // Additionally, we need to add a DB write for removing the precompile revert code in the + // EVM + + // This is the dispatch info of destroy + let call = Call::Assets(pallet_assets::Call::::destroy { + id: asset, + witness: asset_destroy_witness, + }); + + // This is the db write + call.get_dispatch_info() + .weight + .saturating_add(::DbWeight::get().writes(1 as Weight)) + } +} + +pub struct LocalAssetIdCreator; +impl pallet_asset_manager::LocalAssetIdCreator for LocalAssetIdCreator { + fn create_asset_id_from_metadata(local_asset_counter: u128) -> AssetId { + // Our means of converting a local asset counter to an assetId + // We basically hash (local asset counter) + let mut result: [u8; 16] = [0u8; 16]; + let to_hash = local_asset_counter.encode(); + let hash: H256 = to_hash.using_encoded(::Hashing::hash); + result.copy_from_slice(&hash.as_fixed_bytes()[0..16]); + u128::from_le_bytes(result) + } +} + +#[derive(Clone, Default, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] +pub struct AssetRegistrarMetadata { + pub name: Vec, + pub symbol: Vec, + pub decimals: u8, + pub is_frozen: bool, +} + +impl pallet_asset_manager::Config for Runtime { + type Event = Event; + type Balance = Balance; + type AssetId = AssetId; + type AssetRegistrarMetadata = AssetRegistrarMetadata; + type ForeignAssetType = xcm_config::AssetType; + type AssetRegistrar = AssetRegistrar; + type ForeignAssetModifierOrigin = EnsureRoot; + type LocalAssetModifierOrigin = EnsureRoot; + type LocalAssetIdCreator = LocalAssetIdCreator; + type AssetDestroyWitness = pallet_assets::DestroyWitness; + type Currency = Balances; + type LocalAssetDeposit = AssetDeposit; + type WeightInfo = pallet_asset_manager::weights::SubstrateWeight; +} + +// Instruct how to go from an H160 to an AssetID +// We just take the lowest 128 bits +impl AccountIdAssetIdConversion for Runtime { + /// The way to convert an account to assetId is by ensuring that the prefix is 0XFFFFFFFF + /// and by taking the lowest 128 bits as the assetId + fn account_to_asset_id(account: AccountId) -> Option<(Vec, AssetId)> { + let h160_account: H160 = account.into(); + let mut data = [0u8; 16]; + let (prefix_part, id_part) = h160_account.as_fixed_bytes().split_at(4); + if prefix_part == ASSET_PRECOMPILE_ADDRESS_PREFIX { + data.copy_from_slice(id_part); + let asset_id: AssetId = u128::from_be_bytes(data).into(); + Some((prefix_part.to_vec(), asset_id)) + } else { + None + } + } + + // The opposite conversion + fn asset_id_to_account(prefix: &[u8], asset_id: AssetId) -> AccountId { + let mut data = [0u8; 20]; + data[0..4].copy_from_slice(prefix); + data[4..20].copy_from_slice(&asset_id.to_be_bytes()); + AccountId::from(data) + } +} diff --git a/runtime/moonbeam/src/lib.rs b/runtime/moonbeam/src/lib.rs index 450f298dd1..f8c2202d86 100644 --- a/runtime/moonbeam/src/lib.rs +++ b/runtime/moonbeam/src/lib.rs @@ -35,7 +35,9 @@ use fp_rpc::TransactionStatus; // Re-export required by get! macro. pub use frame_support::traits::Get; use frame_support::{ - construct_runtime, parameter_types, + construct_runtime, + pallet_prelude::DispatchResult, + parameter_types, traits::{ ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Contains, EnsureOneOf, EqualPrivilegeOnly, Imbalance, InstanceFilter, OffchainWorker, OnFinalize, OnIdle, @@ -79,10 +81,6 @@ use sp_runtime::{ }; use sp_std::{convert::TryFrom, prelude::*}; -use pallet_evm_precompile_assets_erc20::AccountIdAssetIdConversion; - -use xcm::latest::prelude::*; - use cumulus_primitives_core::{relay_chain::BlockNumber as RelayBlockNumber, DmpMessageHandler}; #[cfg(feature = "std")] @@ -92,13 +90,14 @@ use sp_version::RuntimeVersion; use nimbus_primitives::{CanAuthor, NimbusId}; mod precompiles; -use precompiles::{MoonbeamPrecompiles, ASSET_PRECOMPILE_ADDRESS_PREFIX}; +pub use precompiles::{MoonbeamPrecompiles, ASSET_PRECOMPILE_ADDRESS_PREFIX}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; pub type Precompiles = MoonbeamPrecompiles; +pub mod asset_config; pub mod xcm_config; /// GLMR, the native token, uses 18 decimals of precision. @@ -828,123 +827,6 @@ impl pallet_migrations::Config for Runtime { >; } -// These parameters dont matter much as this will only be called by root with the forced arguments -// No deposit is substracted with those methods -parameter_types! { - pub const ExecutiveBody: BodyId = BodyId::Executive; -} - -/// We allow root and Chain council to execute privileged asset operations. -pub type AssetsForceOrigin = EnsureOneOf< - EnsureRoot, - pallet_collective::EnsureProportionMoreThan, ->; - -impl pallet_assets::Config for Runtime { - type Event = Event; - type Balance = Balance; - type AssetId = AssetId; - type Currency = Balances; - type ForceOrigin = AssetsForceOrigin; - type AssetDeposit = ConstU128<0>; - type MetadataDepositBase = ConstU128<0>; - type MetadataDepositPerByte = ConstU128<0>; - type ApprovalDeposit = ConstU128<0>; - type StringLimit = ConstU32<50>; - type Freezer = (); - type Extra = (); - type AssetAccountDeposit = ConstU128<{ currency::deposit(1, 18) }>; - type WeightInfo = pallet_assets::weights::SubstrateWeight; -} - -// We instruct how to register the Assets -// In this case, we tell it to Create an Asset in pallet-assets -pub struct AssetRegistrar; -use frame_support::{pallet_prelude::DispatchResult, transactional}; - -impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { - #[transactional] - fn create_asset( - asset: AssetId, - min_balance: Balance, - metadata: AssetRegistrarMetadata, - is_sufficient: bool, - ) -> DispatchResult { - Assets::force_create( - Origin::root(), - asset, - AssetManager::account_id(), - is_sufficient, - min_balance, - )?; - - // TODO uncomment when we feel comfortable - /* - // The asset has been created. Let's put the revert code in the precompile address - let precompile_address = Runtime::asset_id_to_account(asset); - pallet_evm::AccountCodes::::insert( - precompile_address, - vec![0x60, 0x00, 0x60, 0x00, 0xfd], - );*/ - - // Lastly, the metadata - Assets::force_set_metadata( - Origin::root(), - asset, - metadata.name, - metadata.symbol, - metadata.decimals, - metadata.is_frozen, - ) - } -} - -#[derive(Clone, Default, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] -pub struct AssetRegistrarMetadata { - pub name: Vec, - pub symbol: Vec, - pub decimals: u8, - pub is_frozen: bool, -} - -impl pallet_asset_manager::Config for Runtime { - type Event = Event; - type Balance = Balance; - type AssetId = AssetId; - type AssetRegistrarMetadata = AssetRegistrarMetadata; - type AssetType = xcm_config::AssetType; - type AssetRegistrar = AssetRegistrar; - type AssetModifierOrigin = EnsureRoot; - type WeightInfo = pallet_asset_manager::weights::SubstrateWeight; -} - -// Instruct how to go from an H160 to an AssetID -// We just take the lowest 128 bits -impl AccountIdAssetIdConversion for Runtime { - /// The way to convert an account to assetId is by ensuring that the prefix is 0XFFFFFFFF - /// and by taking the lowest 128 bits as the assetId - fn account_to_asset_id(account: AccountId) -> Option { - let h160_account: H160 = account.into(); - let mut data = [0u8; 16]; - let (prefix_part, id_part) = h160_account.as_fixed_bytes().split_at(4); - if prefix_part == ASSET_PRECOMPILE_ADDRESS_PREFIX { - data.copy_from_slice(id_part); - let asset_id: AssetId = u128::from_be_bytes(data).into(); - Some(asset_id) - } else { - None - } - } - - // The opposite conversion - fn asset_id_to_account(asset_id: AssetId) -> AccountId { - let mut data = [0u8; 20]; - data[0..4].copy_from_slice(ASSET_PRECOMPILE_ADDRESS_PREFIX); - data[4..20].copy_from_slice(&asset_id.to_be_bytes()); - AccountId::from(data) - } -} - /// Maintenance mode Call filter pub struct MaintenanceFilter; impl Contains for MaintenanceFilter { diff --git a/runtime/moonbeam/src/precompiles.rs b/runtime/moonbeam/src/precompiles.rs index c84eff8e22..58d267ec78 100644 --- a/runtime/moonbeam/src/precompiles.rs +++ b/runtime/moonbeam/src/precompiles.rs @@ -20,7 +20,7 @@ use moonbeam_relay_encoder::polkadot::PolkadotEncoder; use pallet_author_mapping_precompiles::AuthorMappingWrapper; use pallet_democracy_precompiles::DemocracyWrapper; use pallet_evm::{AddressMapping, Precompile, PrecompileResult, PrecompileSet}; -use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; +use pallet_evm_precompile_assets_erc20::{Erc20AssetsPrecompileSet, IsForeign}; use pallet_evm_precompile_balances_erc20::{Erc20BalancesPrecompile, Erc20Metadata}; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; @@ -101,8 +101,8 @@ where Dispatch: Precompile, ParachainStakingWrapper: Precompile, CrowdloanRewardsWrapper: Precompile, + Erc20AssetsPrecompileSet: PrecompileSet, Erc20BalancesPrecompile: Precompile, - Erc20AssetsPrecompileSet: PrecompileSet, XtokensWrapper: Precompile, RelayEncoderWrapper: Precompile, XcmTransactorWrapper: Precompile, @@ -168,7 +168,7 @@ where )), // If the address matches asset prefix, the we route through the asset precompile set a if &a.to_fixed_bytes()[0..4] == ASSET_PRECOMPILE_ADDRESS_PREFIX => { - Erc20AssetsPrecompileSet::::new() + Erc20AssetsPrecompileSet::::new() .execute(address, input, target_gas, context, is_static) } _ => None, @@ -176,7 +176,7 @@ where } fn is_precompile(&self, address: H160) -> bool { Self::used_addresses().any(|x| x == R::AddressMapping::into_account_id(address)) - || Erc20AssetsPrecompileSet::::new().is_precompile(address) + || Erc20AssetsPrecompileSet::::new().is_precompile(address) } } diff --git a/runtime/moonbeam/src/xcm_config.rs b/runtime/moonbeam/src/xcm_config.rs index 889815d07c..133337f81f 100644 --- a/runtime/moonbeam/src/xcm_config.rs +++ b/runtime/moonbeam/src/xcm_config.rs @@ -330,7 +330,7 @@ impl From for AssetId { #[derive(Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] pub enum CurrencyId { SelfReserve, - OtherReserve(AssetId), + ForeignAsset(AssetId), } impl AccountIdToCurrencyId for Runtime { @@ -340,7 +340,7 @@ impl AccountIdToCurrencyId for Runtime { a if a == H160::from_low_u64_be(2050).into() => Some(CurrencyId::SelfReserve), // the rest of the currencies, by their corresponding erc20 address _ => Runtime::account_to_asset_id(account) - .map(|asset_id| CurrencyId::OtherReserve(asset_id)), + .map(|(_, asset_id)| CurrencyId::ForeignAsset(asset_id)), } } } @@ -358,7 +358,7 @@ where let multi: MultiLocation = SelfReserve::get(); Some(multi) } - CurrencyId::OtherReserve(asset) => AssetXConverter::reverse_ref(asset).ok(), + CurrencyId::ForeignAsset(asset) => AssetXConverter::reverse_ref(asset).ok(), } } } diff --git a/runtime/moonbeam/tests/common/mod.rs b/runtime/moonbeam/tests/common/mod.rs index 63c3ae0770..2a3fba29d2 100644 --- a/runtime/moonbeam/tests/common/mod.rs +++ b/runtime/moonbeam/tests/common/mod.rs @@ -23,11 +23,12 @@ use frame_support::{ traits::{GenesisBuild, OnFinalize, OnInitialize}, }; pub use moonbeam_runtime::{ + asset_config::AssetRegistrarMetadata, currency::{GIGAWEI, GLMR, SUPPLY_FACTOR, WEI}, xcm_config::AssetType, - AccountId, AssetId, AssetManager, AssetRegistrarMetadata, Assets, AuthorInherent, Balance, - Balances, Call, CrowdloanRewards, Ethereum, Event, Executive, FixedGasPrice, InflationInfo, - ParachainStaking, Range, Runtime, System, TransactionConverter, UncheckedExtrinsic, WEEKS, + AccountId, AssetId, AssetManager, Assets, AuthorInherent, Balance, Balances, Call, + CrowdloanRewards, Ethereum, Event, Executive, FixedGasPrice, InflationInfo, ParachainStaking, + Range, Runtime, System, TransactionConverter, UncheckedExtrinsic, WEEKS, }; use nimbus_primitives::{NimbusId, NIMBUS_ENGINE_ID}; use pallet_evm::GenesisAccount; @@ -300,7 +301,7 @@ impl ExtBuilder { // If any xcm assets specified, we register them here for xcm_asset_initialization in xcm_assets { let asset_id: AssetId = xcm_asset_initialization.asset_type.clone().into(); - AssetManager::register_asset( + AssetManager::register_foreign_asset( root_origin(), xcm_asset_initialization.asset_type, xcm_asset_initialization.metadata, diff --git a/runtime/moonbeam/tests/integration_test.rs b/runtime/moonbeam/tests/integration_test.rs index d1b2445868..6ad431248a 100644 --- a/runtime/moonbeam/tests/integration_test.rs +++ b/runtime/moonbeam/tests/integration_test.rs @@ -32,7 +32,7 @@ use frame_support::{ use moonbeam_runtime::{ currency::GLMR, xcm_config::CurrencyId, AccountId, Balances, BaseFee, BlockWeights, Call, CrowdloanRewards, Event, ParachainStaking, PolkadotXcm, Precompiles, Runtime, System, XTokens, - XcmTransactor, + XcmTransactor, ASSET_PRECOMPILE_ADDRESS_PREFIX, }; use nimbus_primitives::NimbusId; use pallet_evm::PrecompileSet; @@ -1285,7 +1285,7 @@ fn root_can_change_default_xcm_vers() { assert_noop!( XTokens::transfer( origin_of(AccountId::from(ALICE)), - CurrencyId::OtherReserve(source_id), + CurrencyId::ForeignAsset(source_id), 100_000_000_000_000, Box::new(xcm::VersionedMultiLocation::V1(dest.clone())), 4000000000 @@ -1302,7 +1302,7 @@ fn root_can_change_default_xcm_vers() { // Now transferring does not fail assert_ok!(XTokens::transfer( origin_of(AccountId::from(ALICE)), - CurrencyId::OtherReserve(source_id), + CurrencyId::ForeignAsset(source_id), 100_000_000_000_000, Box::new(xcm::VersionedMultiLocation::V1(dest)), 4000000000 @@ -1321,7 +1321,7 @@ fn asset_can_be_registered() { decimals: 12, is_frozen: false, }; - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( moonbeam_runtime::Origin::root(), source_location, asset_metadata, @@ -1342,7 +1342,8 @@ fn asset_erc20_precompiles_supply_and_balance() { assert_eq!(Assets::total_supply(0u128), 1_000 * GLMR); // Convert the assetId to its corresponding precompile address - let asset_precompile_address = Runtime::asset_id_to_account(0u128).into(); + let asset_precompile_address = + Runtime::asset_id_to_account(ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); // The expected result for both total supply and balance of is the same, as only Alice // holds balance @@ -1399,7 +1400,8 @@ fn asset_erc20_precompiles_transfer() { ]) .build() .execute_with(|| { - let asset_precompile_address = Runtime::asset_id_to_account(0u128).into(); + let asset_precompile_address = + Runtime::asset_id_to_account(ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); // Expected result for a transfer let expected_result = Some(Ok(PrecompileOutput { @@ -1473,7 +1475,8 @@ fn asset_erc20_precompiles_approve() { ]) .build() .execute_with(|| { - let asset_precompile_address = Runtime::asset_id_to_account(0u128).into(); + let asset_precompile_address = + Runtime::asset_id_to_account(ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); // Expected result for approve let expected_result = Some(Ok(PrecompileOutput { @@ -1600,7 +1603,9 @@ fn xtokens_precompiles_transfer() { AssetType::Xcm(MultiLocation::parent()).into(); // Its address is - let asset_precompile_address = Runtime::asset_id_to_account(relay_asset_id).into(); + let asset_precompile_address = + Runtime::asset_id_to_account(ASSET_PRECOMPILE_ADDRESS_PREFIX, relay_asset_id) + .into(); // Alice has 1000 tokens. She should be able to send through precompile let destination = MultiLocation::new( @@ -1870,7 +1875,7 @@ fn transactor_cannot_use_more_than_max_weight() { origin_of(AccountId::from(ALICE)), moonbeam_runtime::xcm_config::Transactors::Relay, 0, - CurrencyId::OtherReserve(source_id), + CurrencyId::ForeignAsset(source_id), // 20000 is the max 17000, vec![], @@ -1916,7 +1921,7 @@ fn call_xtokens_with_fee() { // We are able to transfer with fee assert_ok!(XTokens::transfer_with_fee( origin_of(AccountId::from(ALICE)), - CurrencyId::OtherReserve(source_id), + CurrencyId::ForeignAsset(source_id), 100_000_000_000_000, 100, Box::new(xcm::VersionedMultiLocation::V1(dest.clone())), diff --git a/runtime/moonbeam/tests/xcm_mock/parachain.rs b/runtime/moonbeam/tests/xcm_mock/parachain.rs index c374b3612b..be45768d29 100644 --- a/runtime/moonbeam/tests/xcm_mock/parachain.rs +++ b/runtime/moonbeam/tests/xcm_mock/parachain.rs @@ -19,7 +19,7 @@ use frame_support::{ construct_runtime, parameter_types, traits::{Everything, Get, Nothing, PalletInfoAccess}, - weights::Weight, + weights::{GetDispatchInfo, Weight}, PalletId, }; @@ -277,7 +277,7 @@ impl cumulus_pallet_xcm::Config for Runtime { #[derive(Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] pub enum CurrencyId { SelfReserve, - OtherReserve(AssetId), + ForeignAsset(AssetId), } // How to convert from CurrencyId to MultiLocation @@ -293,7 +293,7 @@ where let multi: MultiLocation = SelfReserve::get(); Some(multi) } - CurrencyId::OtherReserve(asset) => AssetXConverter::reverse_ref(asset).ok(), + CurrencyId::ForeignAsset(asset) => AssetXConverter::reverse_ref(asset).ok(), } } } @@ -637,7 +637,7 @@ impl From for AssetId { pub struct AssetRegistrar; use frame_support::pallet_prelude::DispatchResult; impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { - fn create_asset( + fn create_foreign_asset( asset: AssetId, min_balance: Balance, metadata: AssetMetadata, @@ -660,6 +660,26 @@ impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { false, ) } + fn destroy_foreign_asset( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> DispatchResult { + // First destroy the asset + Assets::destroy(Origin::root(), asset, asset_destroy_witness).map_err(|info| info.error)?; + + Ok(()) + } + + fn destroy_asset_dispatch_info_weight( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> Weight { + let call = Call::Assets(pallet_assets::Call::::destroy { + id: asset, + witness: asset_destroy_witness, + }); + call.get_dispatch_info().weight + } } #[derive(Clone, Default, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] @@ -669,14 +689,32 @@ pub struct AssetMetadata { pub decimals: u8, } +pub struct LocalAssetIdCreator; +impl pallet_asset_manager::LocalAssetIdCreator for LocalAssetIdCreator { + fn create_asset_id_from_metadata(local_asset_counter: u128) -> AssetId { + // Our means of converting a local asset counter to an assetId + // We basically hash (local asset counter) + let mut result: [u8; 16] = [0u8; 16]; + let to_hash = local_asset_counter.encode(); + let hash: H256 = to_hash.using_encoded(::Hashing::hash); + result.copy_from_slice(&hash.as_fixed_bytes()[0..16]); + u128::from_le_bytes(result) + } +} + impl pallet_asset_manager::Config for Runtime { type Event = Event; type Balance = Balance; type AssetId = AssetId; type AssetRegistrarMetadata = AssetMetadata; - type AssetType = AssetType; + type ForeignAssetType = AssetType; type AssetRegistrar = AssetRegistrar; - type AssetModifierOrigin = EnsureRoot; + type ForeignAssetModifierOrigin = EnsureRoot; + type LocalAssetModifierOrigin = EnsureRoot; + type LocalAssetIdCreator = LocalAssetIdCreator; + type AssetDestroyWitness = pallet_assets::DestroyWitness; + type Currency = Balances; + type LocalAssetDeposit = AssetDeposit; type WeightInfo = (); } @@ -797,7 +835,7 @@ construct_runtime!( XcmVersioner: mock_version_changer::{Pallet, Storage, Event}, PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, - Assets: pallet_assets::{Pallet, Storage, Event}, + Assets: pallet_assets::{Pallet, Call, Storage, Event}, CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin}, XTokens: orml_xtokens::{Pallet, Call, Storage, Event}, AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Event}, diff --git a/runtime/moonbeam/tests/xcm_tests.rs b/runtime/moonbeam/tests/xcm_tests.rs index 3870663c16..893d81fffc 100644 --- a/runtime/moonbeam/tests/xcm_tests.rs +++ b/runtime/moonbeam/tests/xcm_tests.rs @@ -51,7 +51,7 @@ fn receive_relay_asset_from_relay() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -105,7 +105,7 @@ fn send_relay_asset_to_relay() { // First send relay chain asset to Parachain like in previous test ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -157,7 +157,7 @@ fn send_relay_asset_to_relay() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 123, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -189,7 +189,7 @@ fn send_relay_asset_to_para_b() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), @@ -205,7 +205,7 @@ fn send_relay_asset_to_para_b() { }); ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -255,7 +255,7 @@ fn send_relay_asset_to_para_b() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -288,7 +288,7 @@ fn send_para_a_asset_to_para_b() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -356,7 +356,7 @@ fn send_para_a_asset_from_para_b_to_para_c() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), @@ -372,7 +372,7 @@ fn send_para_a_asset_from_para_b_to_para_c() { }); ParaC::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -440,7 +440,7 @@ fn send_para_a_asset_from_para_b_to_para_c() { assert_noop!( XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 80 @@ -470,7 +470,7 @@ fn send_para_a_asset_to_para_b_and_back_to_para_a() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -537,7 +537,7 @@ fn send_para_a_asset_to_para_b_and_back_to_para_a() { assert_noop!( XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 80 @@ -572,7 +572,7 @@ fn receive_relay_asset_with_trader() { // we know later we will divide by 1e12 // Lets put 1e6 as units per second ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -638,7 +638,7 @@ fn error_when_not_paying_enough() { // we know later we will divide by 1e12 // Lets put 1e6 as units per second ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -686,7 +686,7 @@ fn transact_through_derivative_multilocation() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -758,7 +758,7 @@ fn transact_through_derivative_multilocation() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -829,7 +829,7 @@ fn transact_through_sovereign() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -896,7 +896,7 @@ fn transact_through_sovereign() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -978,7 +978,7 @@ fn test_automatic_versioning_on_runtime_upgrade_with_relay() { // register relay asset in parachain A and set XCM version to 1 ParaA::execute_with(|| { parachain::XcmVersioner::set_version(1); - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1110,7 +1110,7 @@ fn receive_asset_with_no_sufficients_not_possible_if_non_existent_account() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1188,7 +1188,7 @@ fn receive_assets_with_sufficients_true_allows_non_funded_account_to_receive_ass }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1248,7 +1248,7 @@ fn evm_account_receiving_assets_should_handle_sufficients_ref_count() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1311,7 +1311,7 @@ fn empty_account_should_not_be_reset() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1419,7 +1419,7 @@ fn test_statemint_like() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), @@ -1490,7 +1490,7 @@ fn test_statemint_like() { assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 123, Box::new(VersionedMultiLocation::V1(dest)), 8000 @@ -1528,7 +1528,7 @@ fn test_statemint_like_prefix_change() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), diff --git a/runtime/moonriver/src/asset_config.rs b/runtime/moonriver/src/asset_config.rs new file mode 100644 index 0000000000..2d8cd5de30 --- /dev/null +++ b/runtime/moonriver/src/asset_config.rs @@ -0,0 +1,293 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! Asset configuration for Moonbase. +//! + +use super::{ + currency, xcm_config, AccountId, AssetId, AssetManager, Assets, Balance, Balances, Call, + CouncilInstance, Event, LocalAssets, Origin, Runtime, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, +}; + +use pallet_evm_precompile_assets_erc20::AccountIdAssetIdConversion; +use sp_runtime::traits::Hash as THash; + +use frame_support::{ + parameter_types, + traits::{ConstU128, EnsureOneOf}, + weights::{GetDispatchInfo, Weight}, +}; + +use frame_system::EnsureRoot; +use sp_core::{H160, H256}; + +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; + +use sp_std::{ + convert::{From, Into}, + prelude::*, +}; +type ForeignAssetInstance = pallet_assets::Instance1; +type LocalAssetInstance = pallet_assets::Instance2; + +// For foreign assets, these parameters dont matter much +// as this will only be called by root with the forced arguments +// No deposit is substracted with those methods +// For local assets, they do matter. We use similar parameters +// to those in statemine (except for approval) +parameter_types! { + pub const AssetDeposit: Balance = 100 * currency::MOVR * currency::SUPPLY_FACTOR; + pub const ApprovalDeposit: Balance = 0; + pub const AssetsStringLimit: u32 = 50; + pub const MetadataDepositBase: Balance = currency::deposit(1,68); + pub const MetadataDepositPerByte: Balance = currency::deposit(0, 1); +} + +/// We allow root and Chain council to execute privileged asset operations. +pub type AssetsForceOrigin = EnsureOneOf< + EnsureRoot, + pallet_collective::EnsureProportionMoreThan, +>; + +// Foreign assets +impl pallet_assets::Config for Runtime { + type Event = Event; + type Balance = Balance; + type AssetId = AssetId; + type Currency = Balances; + type ForceOrigin = AssetsForceOrigin; + type AssetDeposit = AssetDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type AssetAccountDeposit = ConstU128<{ currency::deposit(1, 18) }>; + type WeightInfo = pallet_assets::weights::SubstrateWeight; +} + +// Local assets +impl pallet_assets::Config for Runtime { + type Event = Event; + type Balance = Balance; + type AssetId = AssetId; + type Currency = Balances; + type ForceOrigin = AssetsForceOrigin; + type AssetDeposit = AssetDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type AssetAccountDeposit = ConstU128<{ currency::deposit(1, 18) }>; + type WeightInfo = pallet_assets::weights::SubstrateWeight; +} + +// We instruct how to register the Assets +// In this case, we tell it to Create an Asset in pallet-assets +pub struct AssetRegistrar; +use frame_support::{pallet_prelude::DispatchResult, transactional}; + +impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { + #[transactional] + fn create_foreign_asset( + asset: AssetId, + min_balance: Balance, + metadata: AssetRegistrarMetadata, + is_sufficient: bool, + ) -> DispatchResult { + Assets::force_create( + Origin::root(), + asset, + AssetManager::account_id(), + is_sufficient, + min_balance, + )?; + + // TODO uncomment when we feel comfortable + /* + // The asset has been created. Let's put the revert code in the precompile address + let precompile_address = Runtime::asset_id_to_account(ASSET_PRECOMPILE_ADDRESS_PREFIX, asset); + pallet_evm::AccountCodes::::insert( + precompile_address, + vec![0x60, 0x00, 0x60, 0x00, 0xfd], + );*/ + + // Lastly, the metadata + Assets::force_set_metadata( + Origin::root(), + asset, + metadata.name, + metadata.symbol, + metadata.decimals, + metadata.is_frozen, + ) + } + + #[transactional] + fn create_local_asset( + asset: AssetId, + _creator: AccountId, + min_balance: Balance, + is_sufficient: bool, + owner: AccountId, + ) -> DispatchResult { + // We create with root, because we need to decide whether we want to create the asset + // as sufficient. Take into account this does not hold any reserved amount + // in pallet-assets + LocalAssets::force_create(Origin::root(), asset, owner, is_sufficient, min_balance)?; + + // No metadata needs to be set, as this can be set through regular calls + + // TODO: should we put the revert code? + // The asset has been created. Let's put the revert code in the precompile address + let precompile_address: H160 = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, asset).into(); + pallet_evm::AccountCodes::::insert( + precompile_address, + vec![0x60, 0x00, 0x60, 0x00, 0xfd], + ); + Ok(()) + } + + #[transactional] + fn destroy_foreign_asset( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> DispatchResult { + // First destroy the asset + Assets::destroy(Origin::root(), asset, asset_destroy_witness).map_err(|info| info.error)?; + + // We remove the EVM revert code + // This does not panick even if there is no code in the address + let precompile_address: H160 = + Runtime::asset_id_to_account(FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, asset).into(); + pallet_evm::AccountCodes::::remove(precompile_address); + Ok(()) + } + + #[transactional] + fn destroy_local_asset( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> DispatchResult { + // First destroy the asset + LocalAssets::destroy(Origin::root(), asset, asset_destroy_witness) + .map_err(|info| info.error)?; + + // We remove the EVM revert code + // This does not panick even if there is no code in the address + let precompile_address: H160 = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, asset).into(); + pallet_evm::AccountCodes::::remove(precompile_address); + Ok(()) + } + + fn destroy_asset_dispatch_info_weight( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> Weight { + // For us both of them (Foreign and Local) have the same annotated weight for a given + // witness + // We need to take the dispatch info from the destroy call, which is already annotated in + // the assets pallet + // Additionally, we need to add a DB write for removing the precompile revert code in the + // EVM + + // This is the dispatch info of destroy + let call = Call::Assets( + pallet_assets::Call::::destroy { + id: asset, + witness: asset_destroy_witness, + }, + ); + + // This is the db write + call.get_dispatch_info() + .weight + .saturating_add(::DbWeight::get().writes(1 as Weight)) + } +} + +pub struct LocalAssetIdCreator; +impl pallet_asset_manager::LocalAssetIdCreator for LocalAssetIdCreator { + fn create_asset_id_from_metadata(local_asset_counter: u128) -> AssetId { + // Our means of converting a local asset counter to an assetId + // We basically hash (local asset counter) + let mut result: [u8; 16] = [0u8; 16]; + let to_hash = local_asset_counter.encode(); + let hash: H256 = to_hash.using_encoded(::Hashing::hash); + result.copy_from_slice(&hash.as_fixed_bytes()[0..16]); + u128::from_le_bytes(result) + } +} + +#[derive(Clone, Default, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] +pub struct AssetRegistrarMetadata { + pub name: Vec, + pub symbol: Vec, + pub decimals: u8, + pub is_frozen: bool, +} + +impl pallet_asset_manager::Config for Runtime { + type Event = Event; + type Balance = Balance; + type AssetId = AssetId; + type AssetRegistrarMetadata = AssetRegistrarMetadata; + type ForeignAssetType = xcm_config::AssetType; + type AssetRegistrar = AssetRegistrar; + type ForeignAssetModifierOrigin = EnsureRoot; + type LocalAssetModifierOrigin = EnsureRoot; + type LocalAssetIdCreator = LocalAssetIdCreator; + type AssetDestroyWitness = pallet_assets::DestroyWitness; + type Currency = Balances; + type LocalAssetDeposit = AssetDeposit; + type WeightInfo = pallet_asset_manager::weights::SubstrateWeight; +} + +// Instruct how to go from an H160 to an AssetID +// We just take the lowest 128 bits +impl AccountIdAssetIdConversion for Runtime { + /// The way to convert an account to assetId is by ensuring that the prefix is 0XFFFFFFFF + /// and by taking the lowest 128 bits as the assetId + fn account_to_asset_id(account: AccountId) -> Option<(Vec, AssetId)> { + let h160_account: H160 = account.into(); + let mut data = [0u8; 16]; + let (prefix_part, id_part) = h160_account.as_fixed_bytes().split_at(4); + if prefix_part == FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX + || prefix_part == LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX + { + data.copy_from_slice(id_part); + let asset_id: AssetId = u128::from_be_bytes(data).into(); + Some((prefix_part.to_vec(), asset_id)) + } else { + None + } + } + + // The opposite conversion + fn asset_id_to_account(prefix: &[u8], asset_id: AssetId) -> AccountId { + let mut data = [0u8; 20]; + data[0..4].copy_from_slice(prefix); + data[4..20].copy_from_slice(&asset_id.to_be_bytes()); + AccountId::from(data) + } +} diff --git a/runtime/moonriver/src/lib.rs b/runtime/moonriver/src/lib.rs index 61774b324b..c29405690d 100644 --- a/runtime/moonriver/src/lib.rs +++ b/runtime/moonriver/src/lib.rs @@ -35,7 +35,9 @@ use fp_rpc::TransactionStatus; // Re-export required by get! macro. pub use frame_support::traits::Get; use frame_support::{ - construct_runtime, parameter_types, + construct_runtime, + pallet_prelude::DispatchResult, + parameter_types, traits::{ ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Contains, EnsureOneOf, EqualPrivilegeOnly, Imbalance, InstanceFilter, OffchainWorker, OnFinalize, OnIdle, @@ -63,7 +65,6 @@ use pallet_evm::{ Account as EVMAccount, EnsureAddressNever, EnsureAddressRoot, FeeCalculator, GasWeightMapping, Runner, }; -use pallet_evm_precompile_assets_erc20::AccountIdAssetIdConversion; use pallet_transaction_payment::{CurrencyAdapter, Multiplier, TargetedFeeAdjustment}; pub use parachain_staking::{InflationInfo, Range}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; @@ -86,18 +87,21 @@ use smallvec::smallvec; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use xcm::latest::prelude::*; use nimbus_primitives::{CanAuthor, NimbusId}; mod precompiles; -use precompiles::{MoonriverPrecompiles, ASSET_PRECOMPILE_ADDRESS_PREFIX}; +pub use precompiles::{ + MoonriverPrecompiles, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, +}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; pub type Precompiles = MoonriverPrecompiles; +pub mod asset_config; pub mod xcm_config; /// MOVR, the native token, uses 18 decimals of precision. @@ -863,129 +867,13 @@ impl pallet_migrations::Config for Runtime { ); } -// These parameters dont matter much as this will only be called by root with the forced arguments -// No deposit is substracted with those methods -parameter_types! { - pub const ExecutiveBody: BodyId = BodyId::Executive; -} - -/// We allow root and Chain council to execute privileged asset operations. -pub type AssetsForceOrigin = EnsureOneOf< - EnsureRoot, - pallet_collective::EnsureProportionMoreThan, ->; - -impl pallet_assets::Config for Runtime { - type Event = Event; - type Balance = Balance; - type AssetId = AssetId; - type Currency = Balances; - type ForceOrigin = AssetsForceOrigin; - type AssetDeposit = ConstU128<0>; - type MetadataDepositBase = ConstU128<0>; - type MetadataDepositPerByte = ConstU128<0>; - type ApprovalDeposit = ConstU128<0>; - type StringLimit = ConstU32<50>; - type Freezer = (); - type Extra = (); - type AssetAccountDeposit = ConstU128<{ currency::deposit(1, 18) }>; - type WeightInfo = pallet_assets::weights::SubstrateWeight; -} - -// We instruct how to register the Assets -// In this case, we tell it to Create an Asset in pallet-assets -pub struct AssetRegistrar; -use frame_support::{pallet_prelude::DispatchResult, transactional}; - -impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { - #[transactional] - fn create_asset( - asset: AssetId, - min_balance: Balance, - metadata: AssetRegistrarMetadata, - is_sufficient: bool, - ) -> DispatchResult { - Assets::force_create( - Origin::root(), - asset, - AssetManager::account_id(), - is_sufficient, - min_balance, - )?; - - // TODO uncomment when we feel comfortable - /* - // The asset has been created. Let's put the revert code in the precompile address - let precompile_address = Runtime::asset_id_to_account(asset); - pallet_evm::AccountCodes::::insert( - precompile_address, - vec![0x60, 0x00, 0x60, 0x00, 0xfd], - );*/ - - // Lastly, the metadata - Assets::force_set_metadata( - Origin::root(), - asset, - metadata.name, - metadata.symbol, - metadata.decimals, - metadata.is_frozen, - ) - } -} - -#[derive(Clone, Default, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] -pub struct AssetRegistrarMetadata { - pub name: Vec, - pub symbol: Vec, - pub decimals: u8, - pub is_frozen: bool, -} - -impl pallet_asset_manager::Config for Runtime { - type Event = Event; - type Balance = Balance; - type AssetId = AssetId; - type AssetRegistrarMetadata = AssetRegistrarMetadata; - type AssetType = xcm_config::AssetType; - type AssetRegistrar = AssetRegistrar; - type AssetModifierOrigin = EnsureRoot; - type WeightInfo = pallet_asset_manager::weights::SubstrateWeight; -} - -// Instruct how to go from an H160 to an AssetID -// We just take the lowest 128 bits -impl AccountIdAssetIdConversion for Runtime { - /// The way to convert an account to assetId is by ensuring that the prefix is 0XFFFFFFFF - /// and by taking the lowest 128 bits as the assetId - fn account_to_asset_id(account: AccountId) -> Option { - let h160_account: H160 = account.into(); - let mut data = [0u8; 16]; - let (prefix_part, id_part) = h160_account.as_fixed_bytes().split_at(4); - if prefix_part == ASSET_PRECOMPILE_ADDRESS_PREFIX { - data.copy_from_slice(id_part); - let asset_id: AssetId = u128::from_be_bytes(data).into(); - Some(asset_id) - } else { - None - } - } - - // The opposite conversion - fn asset_id_to_account(asset_id: AssetId) -> AccountId { - let mut data = [0u8; 20]; - data[0..4].copy_from_slice(ASSET_PRECOMPILE_ADDRESS_PREFIX); - data[4..20].copy_from_slice(&asset_id.to_be_bytes()); - AccountId::from(data) - } -} - /// Maintenance mode Call filter pub struct MaintenanceFilter; impl Contains for MaintenanceFilter { fn contains(c: &Call) -> bool { match c { Call::Assets(_) => false, + Call::LocalAssets(_) => false, Call::Balances(_) => false, Call::CrowdloanRewards(_) => false, Call::Ethereum(_) => false, @@ -1018,6 +906,16 @@ impl Contains for NormalFilter { pallet_assets::Call::cancel_approval { .. } => true, _ => false, }, + // We want to disable create, as we dont want users to be choosing the + // assetId of their choice + // We also disable destroy, as we want to route destroy through the + // asset-manager, which guarantees the removal both at the EVM and + // substrate side of things + Call::LocalAssets(method) => match method { + pallet_assets::Call::create { .. } => false, + pallet_assets::Call::destroy { .. } => false, + _ => true, + }, // We just want to enable this in case of live chains, since the default version // is populated at genesis Call::PolkadotXcm(method) => match method { @@ -1178,10 +1076,11 @@ construct_runtime! { CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 101, DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 102, PolkadotXcm: pallet_xcm::{Pallet, Storage, Call, Event, Origin, Config} = 103, - Assets: pallet_assets::{Pallet, Call, Storage, Event} = 104, + Assets: pallet_assets::::{Pallet, Call, Storage, Event} = 104, AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Event} = 105, XTokens: orml_xtokens::{Pallet, Call, Storage, Event} = 106, XcmTransactor: xcm_transactor::{Pallet, Call, Storage, Event} = 107, + LocalAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 108, } } diff --git a/runtime/moonriver/src/precompiles.rs b/runtime/moonriver/src/precompiles.rs index a9e1ee66cd..0a2c6c15d1 100644 --- a/runtime/moonriver/src/precompiles.rs +++ b/runtime/moonriver/src/precompiles.rs @@ -20,7 +20,7 @@ use moonbeam_relay_encoder::kusama::KusamaEncoder; use pallet_author_mapping_precompiles::AuthorMappingWrapper; use pallet_democracy_precompiles::DemocracyWrapper; use pallet_evm::{AddressMapping, Precompile, PrecompileResult, PrecompileSet}; -use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; +use pallet_evm_precompile_assets_erc20::{Erc20AssetsPrecompileSet, IsForeign, IsLocal}; use pallet_evm_precompile_balances_erc20::{Erc20BalancesPrecompile, Erc20Metadata}; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; @@ -64,7 +64,8 @@ impl Erc20Metadata for NativeErc20Metadata { /// The asset precompile address prefix. Addresses that match against this prefix will be routed /// to Erc20AssetsPrecompileSet -pub const ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8; 4]; +pub const FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8; 4]; +pub const LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX: &[u8] = &[255u8, 255u8, 255u8, 254u8]; /// The PrecompileSet installed in the Moonriver runtime. /// We include the nine Istanbul precompiles @@ -102,7 +103,8 @@ where ParachainStakingWrapper: Precompile, CrowdloanRewardsWrapper: Precompile, Erc20BalancesPrecompile: Precompile, - Erc20AssetsPrecompileSet: PrecompileSet, + Erc20AssetsPrecompileSet: PrecompileSet, + Erc20AssetsPrecompileSet: PrecompileSet, XtokensWrapper: Precompile, RelayEncoderWrapper: Precompile, XcmTransactorWrapper: Precompile, @@ -167,8 +169,13 @@ where input, target_gas, context, is_static, )), // If the address matches asset prefix, the we route through the asset precompile set - a if &a.to_fixed_bytes()[0..4] == ASSET_PRECOMPILE_ADDRESS_PREFIX => { - Erc20AssetsPrecompileSet::::new() + a if &a.to_fixed_bytes()[0..4] == FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX => { + Erc20AssetsPrecompileSet::::new() + .execute(address, input, target_gas, context, is_static) + } + // If the address matches asset prefix, the we route through the asset precompile set + a if &a.to_fixed_bytes()[0..4] == LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX => { + Erc20AssetsPrecompileSet::::new() .execute(address, input, target_gas, context, is_static) } _ => None, @@ -176,7 +183,10 @@ where } fn is_precompile(&self, address: H160) -> bool { Self::used_addresses().any(|x| x == R::AddressMapping::into_account_id(address)) - || Erc20AssetsPrecompileSet::::new().is_precompile(address) + || Erc20AssetsPrecompileSet::::new() + .is_precompile(address) + || Erc20AssetsPrecompileSet::::new() + .is_precompile(address) } } diff --git a/runtime/moonriver/src/xcm_config.rs b/runtime/moonriver/src/xcm_config.rs index 2c8d03d735..d5349d299c 100644 --- a/runtime/moonriver/src/xcm_config.rs +++ b/runtime/moonriver/src/xcm_config.rs @@ -18,9 +18,9 @@ //! use super::{ - AccountId, AssetId, AssetManager, Assets, Balance, Balances, Call, DealWithFees, Event, Origin, - ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, Treasury, WeightToFee, XcmpQueue, - MAXIMUM_BLOCK_WEIGHT, + AccountId, AssetId, AssetManager, Assets, Balance, Balances, Call, DealWithFees, Event, + LocalAssets, Origin, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, Treasury, + WeightToFee, XcmpQueue, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, MAXIMUM_BLOCK_WEIGHT, }; use pallet_evm_precompile_assets_erc20::AccountIdAssetIdConversion; @@ -37,7 +37,7 @@ use sp_core::{H160, H256}; use xcm_builder::{ AccountKey20Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, - AllowTopLevelPaidExecutionFrom, ConvertedConcreteAssetId, + AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex, ConvertedConcreteAssetId, CurrencyAdapter as XcmCurrencyAdapter, EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, LocationInverter, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountKey20AsNative, SovereignSignedViaLocation, @@ -97,6 +97,31 @@ parameter_types! { OldAnchoringSelfReserve::get(), NewAnchoringSelfReserve::get() ]; + + // Old reanchor logic location for pallet assets + // We need to support both in case we talk to a chain not in 0.9.16 + // Or until we import https://github.com/open-web3-stack/open-runtime-module-library/pull/708 + // We will be able to remove this once we import the aforementioned change + // Indentified by thix prefix + generalIndex(assetId) + pub LocalAssetsPalletLocationOldReanchor: MultiLocation = MultiLocation { + parents:1, + interior: Junctions::X2( + Parachain(ParachainInfo::parachain_id().into()), + PalletInstance(::index() as u8) + ) + }; + + // New reanchor logic location for pallet assets + // This is the relative view of our local assets. This is the representation that will + // be considered canonical after we import + // https://github.com/open-web3-stack/open-runtime-module-library/pull/708 + // Indentified by thix prefix + generalIndex(assetId) + pub LocalAssetsPalletLocationNewReanchor: MultiLocation = MultiLocation { + parents:0, + interior: Junctions::X1( + PalletInstance(::index() as u8) + ) + }; } /// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used @@ -113,7 +138,7 @@ pub type LocationToAccountId = ( // The non-reserve fungible transactor type // It will use pallet-assets, and the Id will be matched against AsAssetType -pub type FungiblesTransactor = FungiblesAdapter< +pub type ForeignFungiblesTransactor = FungiblesAdapter< // Use this fungibles implementation: Assets, // Use this currency when it is a fungible asset matching the given location or name: @@ -135,6 +160,7 @@ pub type FungiblesTransactor = FungiblesAdapter< (), >; +/// The transactor for our own chain currency. pub type LocalAssetTransactor = XcmCurrencyAdapter< // Use this currency: Balances, @@ -149,8 +175,70 @@ pub type LocalAssetTransactor = XcmCurrencyAdapter< (), >; +/// Means for transacting local assets that are not the native currency +/// This transactor uses the old reanchor logic +/// Remove once we import https://github.com/open-web3-stack/open-runtime-module-library/pull/708 +pub type LocalFungiblesTransactorOldReanchor = FungiblesAdapter< + // Use this fungibles implementation: + LocalAssets, + ( + ConvertedConcreteAssetId< + AssetId, + Balance, + // This just tells to convert an assetId into a GeneralIndex junction prepended + // by LocalAssetsPalletLocationOldReanchor + AsPrefixedGeneralIndex, + JustTry, + >, + ), + // Convert an XCM MultiLocation into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We dont want to allow teleporting assets + Nothing, + // The account to use for tracking teleports. + (), +>; + +/// Means for transacting local assets besides the native currency on this chain. +pub type LocalFungiblesTransactorNewReanchor = FungiblesAdapter< + // Use this fungibles implementation: + LocalAssets, + // Use this currency when it is a fungible asset matching the given location or name: + ( + ConvertedConcreteAssetId< + AssetId, + Balance, + // This just tells to convert an assetId into a GeneralIndex junction prepended + // by LocalAssetsPalletLocationNewReanchor + AsPrefixedGeneralIndex, + JustTry, + >, + ), + // Convert an XCM MultiLocation into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We dont want to allow teleporting assets + Nothing, + // The account to use for tracking teleports. + (), +>; + // We use all transactors -pub type AssetTransactors = (LocalAssetTransactor, FungiblesTransactor); +// These correspond to +// SelfReserve asset, both pre and post 0.9.16 +// Foreign assets +// Local assets, both pre and post 0.9.16 +// We can remove the Old reanchor once +// we import https://github.com/open-web3-stack/open-runtime-module-library/pull/708 +pub type AssetTransactors = ( + LocalAssetTransactor, + ForeignFungiblesTransactor, + LocalFungiblesTransactorOldReanchor, + LocalFungiblesTransactorNewReanchor, +); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, /// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can @@ -379,8 +467,12 @@ impl From for AssetId { // Our currencyId. We distinguish for now between SelfReserve, and Others, defined by their Id. #[derive(Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] pub enum CurrencyId { + // Our native token SelfReserve, - OtherReserve(AssetId), + // Assets representing other chains native tokens + ForeignAsset(AssetId), + // Our local assets + LocalAssetReserve(AssetId), } impl AccountIdToCurrencyId for Runtime { @@ -389,13 +481,18 @@ impl AccountIdToCurrencyId for Runtime { // the self-reserve currency is identified by the pallet-balances address a if a == H160::from_low_u64_be(2050).into() => Some(CurrencyId::SelfReserve), // the rest of the currencies, by their corresponding erc20 address - _ => Runtime::account_to_asset_id(account) - .map(|asset_id| CurrencyId::OtherReserve(asset_id)), + _ => Runtime::account_to_asset_id(account).map(|(prefix, asset_id)| { + if prefix == FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX.to_vec() { + CurrencyId::ForeignAsset(asset_id) + } else { + CurrencyId::LocalAssetReserve(asset_id) + } + }), } } } - // How to convert from CurrencyId to MultiLocation + pub struct CurrencyIdtoMultiLocation(sp_std::marker::PhantomData); impl sp_runtime::traits::Convert> for CurrencyIdtoMultiLocation @@ -413,7 +510,12 @@ where let multi: MultiLocation = OldAnchoringSelfReserve::get(); Some(multi) } - CurrencyId::OtherReserve(asset) => AssetXConverter::reverse_ref(asset).ok(), + CurrencyId::ForeignAsset(asset) => AssetXConverter::reverse_ref(asset).ok(), + CurrencyId::LocalAssetReserve(asset) => { + let mut location = LocalAssetsPalletLocationOldReanchor::get(); + location.push_interior(Junction::GeneralIndex(asset)).ok(); + Some(location) + } } } } diff --git a/runtime/moonriver/tests/common/mod.rs b/runtime/moonriver/tests/common/mod.rs index c839aded8e..b872f041d2 100644 --- a/runtime/moonriver/tests/common/mod.rs +++ b/runtime/moonriver/tests/common/mod.rs @@ -23,10 +23,11 @@ use frame_support::{ traits::{GenesisBuild, OnFinalize, OnInitialize}, }; pub use moonriver_runtime::{ + asset_config::AssetRegistrarMetadata, currency::{GIGAWEI, MOVR, SUPPLY_FACTOR, WEI}, xcm_config::AssetType, - AccountId, AssetId, AssetManager, AssetRegistrarMetadata, Assets, AuthorInherent, Balance, - Balances, Call, CrowdloanRewards, Ethereum, Event, Executive, FixedGasPrice, InflationInfo, + AccountId, AssetId, AssetManager, Assets, AuthorInherent, Balance, Balances, Call, + CrowdloanRewards, Ethereum, Event, Executive, FixedGasPrice, InflationInfo, LocalAssets, ParachainStaking, Range, Runtime, System, TransactionConverter, UncheckedExtrinsic, WEEKS, }; use nimbus_primitives::{NimbusId, NIMBUS_ENGINE_ID}; @@ -108,8 +109,8 @@ pub struct XcmAssetInitialization { } pub struct ExtBuilder { - // [asset, Vec] - assets: Vec<(AssetId, Vec<(AccountId, Balance)>)>, + // [asset, Vec, owner] + local_assets: Vec<(AssetId, Vec<(AccountId, Balance)>, AccountId)>, // endowed accounts with balances balances: Vec<(AccountId, Balance)>, // [collator, amount] @@ -134,7 +135,7 @@ pub struct ExtBuilder { impl Default for ExtBuilder { fn default() -> ExtBuilder { ExtBuilder { - assets: vec![], + local_assets: vec![], balances: vec![], delegations: vec![], collators: vec![], @@ -204,8 +205,11 @@ impl ExtBuilder { self } - pub fn with_assets(mut self, assets: Vec<(AssetId, Vec<(AccountId, Balance)>)>) -> Self { - self.assets = assets; + pub fn with_local_assets( + mut self, + local_assets: Vec<(AssetId, Vec<(AccountId, Balance)>, AccountId)>, + ) -> Self { + self.local_assets = local_assets; self } @@ -287,20 +291,20 @@ impl ExtBuilder { .unwrap(); let mut ext = sp_io::TestExternalities::new(t); - let assets = self.assets.clone(); + let local_assets = self.local_assets.clone(); let xcm_assets = self.xcm_assets.clone(); ext.execute_with(|| { - // If any assets specified, we create them here - for (asset_id, balances) in assets.clone() { - Assets::force_create(root_origin(), asset_id, ALICE.into(), true, 1).unwrap(); + // If any local assets specified, we create them here + for (asset_id, balances, owner) in local_assets.clone() { + LocalAssets::force_create(root_origin(), asset_id, owner, true, 1).unwrap(); for (account, balance) in balances { - Assets::mint(origin_of(ALICE.into()), asset_id, account, balance).unwrap(); + LocalAssets::mint(origin_of(owner.into()), asset_id, account, balance).unwrap(); } } // If any xcm assets specified, we register them here for xcm_asset_initialization in xcm_assets { let asset_id: AssetId = xcm_asset_initialization.asset_type.clone().into(); - AssetManager::register_asset( + AssetManager::register_foreign_asset( root_origin(), xcm_asset_initialization.asset_type, xcm_asset_initialization.metadata, diff --git a/runtime/moonriver/tests/integration_test.rs b/runtime/moonriver/tests/integration_test.rs index 8dc4086a28..d8cf5f68c4 100644 --- a/runtime/moonriver/tests/integration_test.rs +++ b/runtime/moonriver/tests/integration_test.rs @@ -25,12 +25,17 @@ use fp_evm::{Context, ExitSucceed, PrecompileOutput}; use frame_support::{ assert_noop, assert_ok, dispatch::Dispatchable, - traits::{fungible::Inspect, EnsureOrigin, PalletInfo, StorageInfo, StorageInfoTrait}, + traits::{ + fungible::Inspect, fungibles::Inspect as FungiblesInspect, EnsureOrigin, PalletInfo, + StorageInfo, StorageInfoTrait, + }, weights::{DispatchClass, Weight}, StorageHasher, Twox128, }; use moonriver_runtime::{ - xcm_config::CurrencyId, BaseFee, BlockWeights, PolkadotXcm, Precompiles, XTokens, XcmTransactor, + xcm_config::CurrencyId, AssetId, BaseFee, BlockWeights, LocalAssets, PolkadotXcm, Precompiles, + XTokens, XcmTransactor, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, }; use nimbus_primitives::NimbusId; use pallet_evm::PrecompileSet; @@ -44,7 +49,7 @@ use sha3::{Digest, Keccak256}; use sp_core::{ByteArray, Pair, H160, U256}; use sp_runtime::{ traits::{Convert, One}, - DispatchError, ModuleError, + DispatchError, ModuleError, TokenError, }; use xcm::latest::prelude::*; use xcm::{VersionedMultiAssets, VersionedMultiLocation}; @@ -1272,7 +1277,7 @@ fn root_can_change_default_xcm_vers() { assert_noop!( XTokens::transfer( origin_of(AccountId::from(ALICE)), - CurrencyId::OtherReserve(source_id), + CurrencyId::ForeignAsset(source_id), 100_000_000_000_000, Box::new(xcm::VersionedMultiLocation::V1(dest.clone())), 4000000000 @@ -1289,7 +1294,7 @@ fn root_can_change_default_xcm_vers() { // Now transferring does not fail assert_ok!(XTokens::transfer( origin_of(AccountId::from(ALICE)), - CurrencyId::OtherReserve(source_id), + CurrencyId::ForeignAsset(source_id), 100_000_000_000_000, Box::new(xcm::VersionedMultiLocation::V1(dest)), 4000000000 @@ -1308,7 +1313,7 @@ fn asset_can_be_registered() { decimals: 12, is_frozen: false, }; - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( moonriver_runtime::Origin::root(), source_location, asset_metadata, @@ -1322,14 +1327,669 @@ fn asset_can_be_registered() { #[test] fn asset_erc20_precompiles_supply_and_balance() { ExtBuilder::default() - .with_assets(vec![(0u128, vec![(AccountId::from(ALICE), 1_000 * MOVR)])]) + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * MOVR)], + AccountId::from(ALICE), + )]) + .build() + .execute_with(|| { + // Assert the asset has been created with the correct supply + assert_eq!(LocalAssets::total_supply(0u128), 1_000 * MOVR); + + // Convert the assetId to its corresponding precompile address + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // The expected result for both total supply and balance of is the same, as only Alice + // holds balance + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(U256::from(1000 * MOVR)).build(), + cost: 1000, + logs: Default::default(), + })); + + // Access totalSupply through precompile. Important that the context is correct + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::TotalSupply).build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Access balanceOf through precompile + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::BalanceOf) + .write(EvmAddress(ALICE.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + }); +} + +#[test] +fn asset_erc20_precompiles_transfer() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * MOVR)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * MOVR), + (AccountId::from(BOB), 1_000 * MOVR), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for a transfer + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 23516u64, + logs: LogsBuilder::new(asset_precompile_address) + .log3( + SELECTOR_LOG_TRANSFER, + H160::from(ALICE), + H160::from(BOB), + EvmDataWriter::new().write(U256::from(400 * MOVR)).build(), + ) + .build(), + })); + + // Transfer tokens from Aice to Bob, 400 MOVR. + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Transfer) + .write(EvmAddress(BOB.into())) + .write(U256::from(400 * MOVR)) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Expected result for balanceOf BOB + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(U256::from(400 * MOVR)).build(), + cost: 1000, + logs: Default::default(), + })); + + // Make sure BOB has 400 MOVR + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::BalanceOf) + .write(EvmAddress(BOB.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: BOB.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + }); +} + +#[test] +fn asset_erc20_precompiles_approve() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * MOVR)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * MOVR), + (AccountId::from(BOB), 1_000 * MOVR), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 13989u64, + logs: LogsBuilder::new(asset_precompile_address) + .log3( + SELECTOR_LOG_APPROVAL, + H160::from(ALICE), + H160::from(BOB), + EvmDataWriter::new().write(U256::from(400 * MOVR)).build(), + ) + .build(), + })); + + // Aprove Bob for spending 400 MOVR from Alice + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Approve) + .write(EvmAddress(BOB.into())) + .write(U256::from(400 * MOVR)) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Expected result for transfer_from + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 29006u64, + logs: LogsBuilder::new(asset_precompile_address) + .log3( + SELECTOR_LOG_TRANSFER, + H160::from(ALICE), + H160::from(CHARLIE), + EvmDataWriter::new().write(U256::from(400 * MOVR)).build(), + ) + .build(), + })); + + // Transfer tokens from Alice to Charlie by using BOB as origin + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::TransferFrom) + .write(EvmAddress(ALICE.into())) + .write(EvmAddress(CHARLIE.into())) + .write(U256::from(400 * MOVR)) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: BOB.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Expected result for balance of CHARLIE + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(U256::from(400 * MOVR)).build(), + cost: 1000, + logs: Default::default(), + })); + + // Make sure CHARLIE has 400 MOVR + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::BalanceOf) + .write(EvmAddress(CHARLIE.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: CHARLIE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + }); +} + +#[test] +fn asset_erc20_precompiles_mint_burn() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * MOVR)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * MOVR), + (AccountId::from(BOB), 1_000 * MOVR), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 12821u64, + logs: LogsBuilder::new(asset_precompile_address) + .log3( + SELECTOR_LOG_TRANSFER, + H160::default(), + H160::from(BOB), + EvmDataWriter::new().write(U256::from(1000 * MOVR)).build(), + ) + .build(), + })); + + // Mint 1000 MOVRS to BOB + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Mint) + .write(EvmAddress(BOB.into())) + .write(U256::from(1000 * MOVR)) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert the asset has been minted + assert_eq!(LocalAssets::total_supply(0u128), 2_000 * MOVR); + assert_eq!( + LocalAssets::balance(0u128, AccountId::from(BOB)), + 1_000 * MOVR + ); + + // Expected result for burn + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 12957u64, + logs: LogsBuilder::new(asset_precompile_address) + .log3( + SELECTOR_LOG_TRANSFER, + H160::from(BOB), + H160::default(), + EvmDataWriter::new().write(U256::from(500 * MOVR)).build(), + ) + .build(), + })); + + // Transfer tokens from Alice to Charlie by using BOB as origin + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Burn) + .write(EvmAddress(BOB.into())) + .write(U256::from(500 * MOVR)) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert the asset has been burnt + assert_eq!(LocalAssets::total_supply(0u128), 1_500 * MOVR); + assert_eq!( + LocalAssets::balance(0u128, AccountId::from(BOB)), + 500 * MOVR + ); + }); +} + +#[test] +fn asset_erc20_precompiles_freeze_thaw_account() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * MOVR)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * MOVR), + (AccountId::from(BOB), 1_000 * MOVR), + ]) .build() .execute_with(|| { - // Assert the asset has been created with the correct supply - assert_eq!(Assets::total_supply(0u128), 1_000 * MOVR); + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); - // Convert the assetId to its corresponding precompile address - let asset_precompile_address = Runtime::asset_id_to_account(0u128).into(); + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 6732u64, + logs: Default::default(), + })); + + // Freeze Account + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Freeze) + .write(EvmAddress(ALICE.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert account is frozen + assert_eq!( + LocalAssets::can_withdraw(0u128, &AccountId::from(ALICE), 1).into_result(), + Err(TokenError::Frozen.into()) + ); + + // Expected result for burn + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 6731u64, + logs: Default::default(), + })); + + // Thaw Account + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::Thaw) + .write(EvmAddress(ALICE.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert account is not frozen + assert!(LocalAssets::can_withdraw(0u128, &AccountId::from(ALICE), 1) + .into_result() + .is_ok()); + }); +} + +#[test] +fn asset_erc20_precompiles_freeze_thaw_asset() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * MOVR)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * MOVR), + (AccountId::from(BOB), 1_000 * MOVR), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 5589u64, + logs: Default::default(), + })); + + // Freeze Asset + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::FreezeAsset).build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert account is frozen + assert_eq!( + LocalAssets::can_withdraw(0u128, &AccountId::from(ALICE), 1).into_result(), + Err(TokenError::Frozen.into()) + ); + + // Expected result for burn + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 5593u64, + logs: Default::default(), + })); + + // Thaw Asset + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::ThawAsset).build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Assert account is not frozen + assert!(LocalAssets::can_withdraw(0u128, &AccountId::from(ALICE), 1) + .into_result() + .is_ok()); + }); +} + +#[test] +fn asset_erc20_precompiles_freeze_transfer_ownership() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * MOVR)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * MOVR), + (AccountId::from(BOB), 1_000 * MOVR), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 6666u64, + logs: Default::default(), + })); + + // Transfer ownerhsip of an asset + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::TransferOwnership) + .write(EvmAddress(BOB.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // No clear way of testing BOB is new owner, other than doing a priviledged function + // e.g., transfer_ownership again + assert_ok!(LocalAssets::transfer_ownership( + origin_of(AccountId::from(BOB)), + 0u128, + AccountId::from(ALICE) + )); + }); +} + +#[test] +fn asset_erc20_precompiles_freeze_set_team() { + ExtBuilder::default() + .with_local_assets(vec![( + 0u128, + vec![(AccountId::from(ALICE), 1_000 * MOVR)], + AccountId::from(ALICE), + )]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * MOVR), + (AccountId::from(BOB), 1_000 * MOVR), + ]) + .build() + .execute_with(|| { + let asset_precompile_address = + Runtime::asset_id_to_account(LOCAL_ASSET_PRECOMPILE_ADDRESS_PREFIX, 0u128).into(); + + // Expected result for approve + let expected_result = Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: EvmDataWriter::new().write(true).build(), + cost: 5614u64, + logs: Default::default(), + })); + + // Set Bob as issuer, admin and freezer + assert_eq!( + Precompiles::new().execute( + asset_precompile_address, + &EvmDataWriter::new_with_selector(AssetAction::SetTeam) + .write(EvmAddress(BOB.into())) + .write(EvmAddress(BOB.into())) + .write(EvmAddress(BOB.into())) + .build(), + None, + &Context { + address: asset_precompile_address, + caller: ALICE.into(), + apparent_value: From::from(0), + }, + false, + ), + expected_result + ); + + // Bob should be able to mint, freeze, and thaw + assert_ok!(LocalAssets::mint( + origin_of(AccountId::from(BOB)), + 0u128, + AccountId::from(BOB), + 1_000 * MOVR + )); + assert_ok!(LocalAssets::freeze( + origin_of(AccountId::from(BOB)), + 0u128, + AccountId::from(ALICE) + )); + assert_ok!(LocalAssets::thaw( + origin_of(AccountId::from(BOB)), + 0u128, + AccountId::from(ALICE) + )); + }); +} + +#[test] +fn xcm_asset_erc20_precompiles_supply_and_balance() { + ExtBuilder::default() + .with_xcm_assets(vec![XcmAssetInitialization { + asset_type: AssetType::Xcm(MultiLocation::parent()), + metadata: AssetRegistrarMetadata { + name: b"RelayToken".to_vec(), + symbol: b"Relay".to_vec(), + decimals: 12, + is_frozen: false, + }, + balances: vec![(AccountId::from(ALICE), 1_000 * MOVR)], + is_sufficient: true, + }]) + .with_balances(vec![ + (AccountId::from(ALICE), 2_000 * MOVR), + (AccountId::from(BOB), 1_000 * MOVR), + ]) + .build() + .execute_with(|| { + // We have the assetId that corresponds to the relay chain registered + let relay_asset_id: AssetId = AssetType::Xcm(MultiLocation::parent()).into(); + + // Its address is + let asset_precompile_address = Runtime::asset_id_to_account( + FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + relay_asset_id, + ) + .into(); + + // Assert the asset has been created with the correct supply + assert_eq!(Assets::total_supply(relay_asset_id), 1_000 * MOVR); // The expected result for both total supply and balance of is the same, as only Alice // holds balance @@ -1377,16 +2037,34 @@ fn asset_erc20_precompiles_supply_and_balance() { } #[test] -fn asset_erc20_precompiles_transfer() { +fn xcm_asset_erc20_precompiles_transfer() { ExtBuilder::default() - .with_assets(vec![(0u128, vec![(AccountId::from(ALICE), 1_000 * MOVR)])]) + .with_xcm_assets(vec![XcmAssetInitialization { + asset_type: AssetType::Xcm(MultiLocation::parent()), + metadata: AssetRegistrarMetadata { + name: b"RelayToken".to_vec(), + symbol: b"Relay".to_vec(), + decimals: 12, + is_frozen: false, + }, + balances: vec![(AccountId::from(ALICE), 1_000 * MOVR)], + is_sufficient: true, + }]) .with_balances(vec![ (AccountId::from(ALICE), 2_000 * MOVR), (AccountId::from(BOB), 1_000 * MOVR), ]) .build() .execute_with(|| { - let asset_precompile_address = Runtime::asset_id_to_account(0u128).into(); + // We have the assetId that corresponds to the relay chain registered + let relay_asset_id: AssetId = AssetType::Xcm(MultiLocation::parent()).into(); + + // Its address is + let asset_precompile_address = Runtime::asset_id_to_account( + FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + relay_asset_id, + ) + .into(); // Expected result for a transfer let expected_result = Some(Ok(PrecompileOutput { @@ -1451,16 +2129,34 @@ fn asset_erc20_precompiles_transfer() { } #[test] -fn asset_erc20_precompiles_approve() { +fn xcm_asset_erc20_precompiles_approve() { ExtBuilder::default() - .with_assets(vec![(0u128, vec![(AccountId::from(ALICE), 1_000 * MOVR)])]) + .with_xcm_assets(vec![XcmAssetInitialization { + asset_type: AssetType::Xcm(MultiLocation::parent()), + metadata: AssetRegistrarMetadata { + name: b"RelayToken".to_vec(), + symbol: b"Relay".to_vec(), + decimals: 12, + is_frozen: false, + }, + balances: vec![(AccountId::from(ALICE), 1_000 * MOVR)], + is_sufficient: true, + }]) .with_balances(vec![ (AccountId::from(ALICE), 2_000 * MOVR), (AccountId::from(BOB), 1_000 * MOVR), ]) .build() .execute_with(|| { - let asset_precompile_address = Runtime::asset_id_to_account(0u128).into(); + // We have the assetId that corresponds to the relay chain registered + let relay_asset_id: AssetId = AssetType::Xcm(MultiLocation::parent()).into(); + + // Its address is + let asset_precompile_address = Runtime::asset_id_to_account( + FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + relay_asset_id, + ) + .into(); // Expected result for approve let expected_result = Some(Ok(PrecompileOutput { @@ -1587,7 +2283,11 @@ fn xtokens_precompiles_transfer() { AssetType::Xcm(MultiLocation::parent()).into(); // Its address is - let asset_precompile_address = Runtime::asset_id_to_account(relay_asset_id).into(); + let asset_precompile_address = Runtime::asset_id_to_account( + FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, + relay_asset_id, + ) + .into(); // Alice has 1000 tokens. She should be able to send through precompile let destination = MultiLocation::new( @@ -1785,7 +2485,7 @@ fn transactor_cannot_use_more_than_max_weight() { origin_of(AccountId::from(ALICE)), moonriver_runtime::xcm_config::Transactors::Relay, 0, - moonriver_runtime::xcm_config::CurrencyId::OtherReserve(source_id), + moonriver_runtime::xcm_config::CurrencyId::ForeignAsset(source_id), // 20000 is the max 17000, vec![], @@ -1831,7 +2531,7 @@ fn call_xtokens_with_fee() { // We are able to transfer with fee assert_ok!(XTokens::transfer_with_fee( origin_of(AccountId::from(ALICE)), - CurrencyId::OtherReserve(source_id), + CurrencyId::ForeignAsset(source_id), 100_000_000_000_000, 100, Box::new(xcm::VersionedMultiLocation::V1(dest.clone())), diff --git a/runtime/moonriver/tests/xcm_mock/mod.rs b/runtime/moonriver/tests/xcm_mock/mod.rs index ab83e0b296..b2f3db2131 100644 --- a/runtime/moonriver/tests/xcm_mock/mod.rs +++ b/runtime/moonriver/tests/xcm_mock/mod.rs @@ -186,11 +186,14 @@ pub type StatemineBalances = pallet_balances::Pallet; pub type StatemineChainPalletXcm = pallet_xcm::Pallet; pub type StatemineAssets = pallet_assets::Pallet; -pub type Assets = pallet_assets::Pallet; +pub type ParachainPalletXcm = pallet_xcm::Pallet; +pub type Assets = pallet_assets::Pallet; +pub type LocalAssets = pallet_assets::Pallet; + +pub type Balances = pallet_balances::Pallet; pub type Treasury = pallet_treasury::Pallet; pub type AssetManager = pallet_asset_manager::Pallet; pub type XTokens = orml_xtokens::Pallet; pub type RelayBalances = pallet_balances::Pallet; pub type ParaBalances = pallet_balances::Pallet; pub type XcmTransactor = xcm_transactor::Pallet; -pub type ParachainPalletXcm = pallet_xcm::Pallet; diff --git a/runtime/moonriver/tests/xcm_mock/parachain.rs b/runtime/moonriver/tests/xcm_mock/parachain.rs index 70f54f7a8f..984b03ad6f 100644 --- a/runtime/moonriver/tests/xcm_mock/parachain.rs +++ b/runtime/moonriver/tests/xcm_mock/parachain.rs @@ -19,7 +19,7 @@ use frame_support::{ construct_runtime, parameter_types, traits::{Everything, Get, Nothing, PalletInfo as PalletInfoTrait, PalletInfoAccess}, - weights::Weight, + weights::{GetDispatchInfo, Weight}, PalletId, }; @@ -44,7 +44,7 @@ use xcm::latest::{ }; use xcm_builder::{ AccountKey20Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, - AllowTopLevelPaidExecutionFrom, ConvertedConcreteAssetId, + AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex, ConvertedConcreteAssetId, CurrencyAdapter as XcmCurrencyAdapter, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, FungiblesAdapter, LocationInverter, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountKey20AsNative, @@ -111,8 +111,11 @@ impl pallet_balances::Config for Runtime { type ReserveIdentifier = [u8; 8]; } +pub type ForeignAssetInstance = pallet_assets::Instance1; +pub type LocalAssetInstance = pallet_assets::Instance2; + parameter_types! { - pub const AssetDeposit: Balance = 0; // Does not really matter as this will be only called by root + pub const AssetDeposit: Balance = 1; // Does not really matter as this will be only called by root pub const ApprovalDeposit: Balance = 0; pub const AssetsStringLimit: u32 = 50; pub const MetadataDepositBase: Balance = 0; @@ -121,7 +124,24 @@ parameter_types! { pub const AssetAccountDeposit: Balance = 0; } -impl pallet_assets::Config for Runtime { +impl pallet_assets::Config for Runtime { + type Event = Event; + type Balance = Balance; + type AssetId = AssetId; + type Currency = Balances; + type ForceOrigin = EnsureRoot; + type AssetDeposit = AssetDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type AssetAccountDeposit = AssetAccountDeposit; + type WeightInfo = pallet_assets::weights::SubstrateWeight; +} + +impl pallet_assets::Config for Runtime { type Event = Event; type Balance = Balance; type AssetId = AssetId; @@ -177,7 +197,7 @@ parameter_types! { } // Instructing how incoming xcm assets will be handled -pub type FungiblesTransactor = FungiblesAdapter< +pub type ForeignFungiblesTransactor = FungiblesAdapter< // Use this fungibles implementation: Assets, // Use this currency when it is a fungible asset matching the given location or name: @@ -213,8 +233,60 @@ pub type LocalAssetTransactor = XcmCurrencyAdapter< (), >; -// These will be our transactors -pub type AssetTransactors = (LocalAssetTransactor, FungiblesTransactor); +/// Means for transacting local assets besides the native currency on this chain. +pub type LocalFungiblesTransactorOldReanchor = FungiblesAdapter< + // Use this fungibles implementation: + LocalAssets, + // Use this currency when it is a fungible asset matching the given location or name: + ( + ConvertedConcreteAssetId< + AssetId, + Balance, + AsPrefixedGeneralIndex, + JustTry, + >, + ), + // Convert an XCM MultiLocation into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We dont want to allow teleporting assets + Nothing, + // The account to use for tracking teleports. + (), +>; + +/// Means for transacting local assets besides the native currency on this chain. +pub type LocalFungiblesTransactorNewReanchor = FungiblesAdapter< + // Use this fungibles implementation: + LocalAssets, + // Use this currency when it is a fungible asset matching the given location or name: + ( + ConvertedConcreteAssetId< + AssetId, + Balance, + AsPrefixedGeneralIndex, + JustTry, + >, + ), + // Convert an XCM MultiLocation into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We dont want to allow teleporting assets + Nothing, + // The account to use for tracking teleports. + (), +>; + +// We use both transactors +pub type AssetTransactors = ( + LocalAssetTransactor, + ForeignFungiblesTransactor, + LocalFungiblesTransactorOldReanchor, + LocalFungiblesTransactorNewReanchor, +); + pub type XcmRouter = super::ParachainXcmRouter; pub type Barrier = ( @@ -288,6 +360,21 @@ parameter_types! { ) ) }; + pub LocalAssetsPalletLocationOldReanchor: MultiLocation = MultiLocation { + parents:1, + interior: Junctions::X2( + Parachain(MsgQueue::parachain_id().into()), + PalletInstance(::index() as u8) + ) + }; + + pub LocalAssetsPalletLocationNewReanchor: MultiLocation = MultiLocation { + parents:0, + interior: Junctions::X1( + PalletInstance(::index() as u8) + ) + }; + // The Locations we accept to refer to our own currency. We need to support both pre and // post 0.9.16 versions, hence the reason for this being a Vec pub SelfReserveRepresentations: Vec = vec![ @@ -331,7 +418,8 @@ impl cumulus_pallet_xcm::Config for Runtime { #[derive(Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] pub enum CurrencyId { SelfReserve, - OtherReserve(AssetId), + ForeignAsset(AssetId), + LocalAssetReserve(AssetId), } // How to convert from CurrencyId to MultiLocation @@ -352,7 +440,12 @@ where let multi: MultiLocation = OldAnchoringSelfReserve::get(); Some(multi) } - CurrencyId::OtherReserve(asset) => AssetXConverter::reverse_ref(asset).ok(), + CurrencyId::ForeignAsset(asset) => AssetXConverter::reverse_ref(asset).ok(), + CurrencyId::LocalAssetReserve(asset) => { + let mut location = LocalAssetsPalletLocationOldReanchor::get(); + location.push_interior(Junction::GeneralIndex(asset)).ok(); + Some(location) + } } } } @@ -696,7 +789,7 @@ impl From for AssetId { pub struct AssetRegistrar; use frame_support::pallet_prelude::DispatchResult; impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { - fn create_asset( + fn create_foreign_asset( asset: AssetId, min_balance: Balance, metadata: AssetMetadata, @@ -719,6 +812,59 @@ impl pallet_asset_manager::AssetRegistrar for AssetRegistrar { false, ) } + + fn create_local_asset( + asset: AssetId, + _creator: AccountId, + min_balance: Balance, + is_sufficient: bool, + owner: AccountId, + ) -> DispatchResult { + LocalAssets::force_create(Origin::root(), asset, owner, is_sufficient, min_balance)?; + + // TODO uncomment when we feel comfortable + /* + // The asset has been created. Let's put the revert code in the precompile address + let precompile_address = Runtime::asset_id_to_account(ASSET_PRECOMPILE_ADDRESS_PREFIX, asset); + pallet_evm::AccountCodes::::insert( + precompile_address, + vec![0x60, 0x00, 0x60, 0x00, 0xfd], + );*/ + Ok(()) + } + fn destroy_foreign_asset( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> DispatchResult { + // First destroy the asset + Assets::destroy(Origin::root(), asset, asset_destroy_witness).map_err(|info| info.error)?; + + Ok(()) + } + + fn destroy_local_asset( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> DispatchResult { + // First destroy the asset + LocalAssets::destroy(Origin::root(), asset, asset_destroy_witness) + .map_err(|info| info.error)?; + + Ok(()) + } + + fn destroy_asset_dispatch_info_weight( + asset: AssetId, + asset_destroy_witness: pallet_assets::DestroyWitness, + ) -> Weight { + let call = Call::Assets( + pallet_assets::Call::::destroy { + id: asset, + witness: asset_destroy_witness, + }, + ); + call.get_dispatch_info().weight + } } #[derive(Clone, Default, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] @@ -727,15 +873,32 @@ pub struct AssetMetadata { pub symbol: Vec, pub decimals: u8, } +pub struct LocalAssetIdCreator; +impl pallet_asset_manager::LocalAssetIdCreator for LocalAssetIdCreator { + fn create_asset_id_from_metadata(local_asset_counter: u128) -> AssetId { + // Our means of converting a creator to an assetId + // We basically hash (local asset counter) + let mut result: [u8; 16] = [0u8; 16]; + let to_hash = local_asset_counter.encode(); + let hash: H256 = to_hash.using_encoded(::Hashing::hash); + result.copy_from_slice(&hash.as_fixed_bytes()[0..16]); + u128::from_le_bytes(result) + } +} impl pallet_asset_manager::Config for Runtime { type Event = Event; type Balance = Balance; type AssetId = AssetId; type AssetRegistrarMetadata = AssetMetadata; - type AssetType = AssetType; + type ForeignAssetType = AssetType; type AssetRegistrar = AssetRegistrar; - type AssetModifierOrigin = EnsureRoot; + type ForeignAssetModifierOrigin = EnsureRoot; + type LocalAssetModifierOrigin = EnsureRoot; + type LocalAssetIdCreator = LocalAssetIdCreator; + type AssetDestroyWitness = pallet_assets::DestroyWitness; + type Currency = Balances; + type LocalAssetDeposit = AssetDeposit; type WeightInfo = (); } @@ -856,12 +1019,13 @@ construct_runtime!( XcmVersioner: mock_version_changer::{Pallet, Storage, Event}, PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, - Assets: pallet_assets::{Pallet, Storage, Event}, + Assets: pallet_assets::::{Pallet, Call, Storage, Event}, CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin}, XTokens: orml_xtokens::{Pallet, Call, Storage, Event}, AssetManager: pallet_asset_manager::{Pallet, Call, Storage, Event}, XcmTransactor: xcm_transactor::{Pallet, Call, Storage, Event}, Treasury: pallet_treasury::{Pallet, Storage, Config, Event, Call}, + LocalAssets: pallet_assets::::{Pallet, Call, Storage, Event}, Timestamp: pallet_timestamp::{Pallet, Call, Storage}, EVM: pallet_evm::{Pallet, Call, Storage, Config, Event}, diff --git a/runtime/moonriver/tests/xcm_tests.rs b/runtime/moonriver/tests/xcm_tests.rs index 22b0ca31ba..0494c68f3b 100644 --- a/runtime/moonriver/tests/xcm_tests.rs +++ b/runtime/moonriver/tests/xcm_tests.rs @@ -22,6 +22,7 @@ use frame_support::{ traits::{PalletInfo, PalletInfoAccess}, weights::constants::WEIGHT_PER_SECOND, }; +use pallet_asset_manager::LocalAssetIdCreator; use xcm::latest::prelude::*; use xcm::{VersionedMultiLocation, WrapVersion}; use xcm_executor::traits::Convert; @@ -30,6 +31,8 @@ use xcm_mock::relay_chain; use xcm_mock::*; use xcm_primitives::UtilityEncodeCall; use xcm_simulator::TestExt; +mod common; +use common::ExtBuilder; // Send a relay asset (like DOT) to a parachain A #[test] @@ -45,7 +48,7 @@ fn receive_relay_asset_from_relay() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -99,7 +102,7 @@ fn send_relay_asset_to_relay() { // First send relay chain asset to Parachain like in previous test ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -151,7 +154,7 @@ fn send_relay_asset_to_relay() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 123, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -183,7 +186,7 @@ fn send_relay_asset_to_para_b() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), @@ -199,7 +202,7 @@ fn send_relay_asset_to_para_b() { }); ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -249,7 +252,7 @@ fn send_relay_asset_to_para_b() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -282,7 +285,7 @@ fn send_para_a_asset_to_para_b() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -347,7 +350,7 @@ fn send_para_a_asset_from_para_b_to_para_c() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), @@ -363,7 +366,7 @@ fn send_para_a_asset_from_para_b_to_para_c() { }); ParaC::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -425,7 +428,7 @@ fn send_para_a_asset_from_para_b_to_para_c() { ParaB::execute_with(|| { assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 80 @@ -454,7 +457,7 @@ fn send_para_a_asset_to_para_b_and_back_to_para_a() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -515,7 +518,7 @@ fn send_para_a_asset_to_para_b_and_back_to_para_a() { ParaB::execute_with(|| { assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 80 @@ -547,7 +550,7 @@ fn send_para_a_asset_to_para_b_and_back_to_para_a_with_new_reanchoring() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -635,6 +638,50 @@ fn send_para_a_asset_to_para_b_and_back_to_para_a_with_new_reanchoring() { )); }); + ParaB::execute_with(|| { + // free execution, full amount received + assert_eq!(Assets::balance(source_id, &PARAALICE.into()), 100); + }); + + // This time we will force the new reanchoring by manually sending the + // Message through polkadotXCM pallet + + let dest = MultiLocation { + parents: 1, + interior: X1(Parachain(1)), + }; + + let reanchored_para_a_balances = MultiLocation::new(0, X1(PalletInstance(1u8))); + + let message = xcm::VersionedXcm::<()>::V2(Xcm(vec![ + WithdrawAsset((reanchored_para_a_balances.clone(), 100).into()), + ClearOrigin, + BuyExecution { + fees: (reanchored_para_a_balances, 100).into(), + weight_limit: Limited(80), + }, + DepositAsset { + assets: All.into(), + max_assets: 1, + beneficiary: MultiLocation::new( + 0, + X1(AccountKey20 { + network: Any, + key: PARAALICE, + }), + ), + }, + ])); + ParaB::execute_with(|| { + // Send a message to the sovereign account in ParaA to withdraw + // and deposit asset + assert_ok!(ParachainPalletXcm::send( + parachain::Origin::root(), + Box::new(dest.into()), + Box::new(message), + )); + }); + ParaA::execute_with(|| { // Weight used is 4 assert_eq!( @@ -661,7 +708,7 @@ fn receive_relay_asset_with_trader() { // we know later we will divide by 1e12 // Lets put 1e6 as units per second ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -720,7 +767,7 @@ fn send_para_a_asset_to_para_b_with_trader() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -794,7 +841,7 @@ fn send_para_a_asset_to_para_b_with_trader_and_fee() { }; ParaB::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -869,7 +916,7 @@ fn error_when_not_paying_enough() { // we know later we will divide by 1e12 // Lets put 1e6 as units per second ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -917,7 +964,7 @@ fn transact_through_derivative_multilocation() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -989,7 +1036,7 @@ fn transact_through_derivative_multilocation() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -1060,7 +1107,7 @@ fn transact_through_sovereign() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1127,7 +1174,7 @@ fn transact_through_sovereign() { // free execution, full amount received assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 100, Box::new(VersionedMultiLocation::V1(dest)), 40000 @@ -1209,7 +1256,7 @@ fn test_automatic_versioning_on_runtime_upgrade_with_relay() { // register relay asset in parachain A and set XCM version to 1 ParaA::execute_with(|| { parachain::XcmVersioner::set_version(1); - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1359,7 +1406,7 @@ fn test_automatic_versioning_on_runtime_upgrade_with_para_b() { // Let's try with v0 parachain::XcmVersioner::set_version(0); - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1492,7 +1539,7 @@ fn receive_asset_with_no_sufficients_not_possible_if_non_existent_account() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1570,7 +1617,7 @@ fn receive_assets_with_sufficients_true_allows_non_funded_account_to_receive_ass }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1630,7 +1677,7 @@ fn evm_account_receiving_assets_should_handle_sufficients_ref_count() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1693,7 +1740,7 @@ fn empty_account_should_not_be_reset() { }; // register relay asset in parachain A ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata, @@ -1800,7 +1847,7 @@ fn test_statemine_like() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), @@ -1871,7 +1918,7 @@ fn test_statemine_like() { assert_ok!(XTokens::transfer( parachain::Origin::signed(PARAALICE.into()), - parachain::CurrencyId::OtherReserve(source_id), + parachain::CurrencyId::ForeignAsset(source_id), 123, Box::new(VersionedMultiLocation::V1(dest)), 8000 @@ -1909,7 +1956,7 @@ fn test_statemine_like_prefix_change() { }; ParaA::execute_with(|| { - assert_ok!(AssetManager::register_asset( + assert_ok!(AssetManager::register_foreign_asset( parachain::Origin::root(), source_location.clone(), asset_metadata.clone(), @@ -2008,6 +2055,246 @@ fn test_statemine_like_prefix_change() { }); } +#[test] +fn send_para_a_local_asset_to_para_b() { + ExtBuilder::default().build().execute_with(|| { + MockNet::reset(); + + let asset_id = parachain::LocalAssetIdCreator::create_asset_id_from_metadata(0); + let para_a_local_asset = MultiLocation::new( + 1, + X3(Parachain(1), PalletInstance(11u8), GeneralIndex(asset_id)), + ); + let source_location = parachain::AssetType::Xcm(para_a_local_asset); + let source_id: parachain::AssetId = source_location.clone().into(); + + let asset_metadata = parachain::AssetMetadata { + name: b"ParaALocalAsset".to_vec(), + symbol: b"ParaALocalAsset".to_vec(), + decimals: 12, + }; + + ParaA::execute_with(|| { + assert_ok!(AssetManager::register_local_asset( + parachain::Origin::root(), + PARAALICE.into(), + PARAALICE.into(), + true, + 1 + )); + + assert_ok!(LocalAssets::mint( + parachain::Origin::signed(PARAALICE.into()), + asset_id, + PARAALICE.into(), + 300000000000000 + )); + }); + + ParaB::execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( + parachain::Origin::root(), + source_location.clone(), + asset_metadata, + 1u128, + true + )); + assert_ok!(AssetManager::set_asset_units_per_second( + parachain::Origin::root(), + source_location, + 0u128, + 0 + )); + }); + + let dest = MultiLocation { + parents: 1, + interior: X2( + Parachain(2), + AccountKey20 { + network: NetworkId::Any, + key: PARAALICE.into(), + }, + ), + }; + + ParaA::execute_with(|| { + // free execution, full amount received + assert_ok!(XTokens::transfer( + parachain::Origin::signed(PARAALICE.into()), + parachain::CurrencyId::LocalAssetReserve(asset_id), + 100, + Box::new(VersionedMultiLocation::V1(dest)), + 800000 + )); + }); + + ParaB::execute_with(|| { + // free execution, full amount received + assert_eq!(Assets::balance(source_id, &PARAALICE.into()), 100); + }); + }); +} + +#[test] +fn send_para_a_local_asset_to_para_b_and_send_it_back_together_with_some_dev() { + ExtBuilder::default().build().execute_with(|| { + MockNet::reset(); + + let asset_id = parachain::LocalAssetIdCreator::create_asset_id_from_metadata(0); + let para_a_local_asset = MultiLocation::new( + 1, + X3(Parachain(1), PalletInstance(11u8), GeneralIndex(asset_id)), + ); + let source_location_local_asset = parachain::AssetType::Xcm(para_a_local_asset); + let source_id_local_asset: parachain::AssetId = source_location_local_asset.clone().into(); + + let asset_metadata_local_asset = parachain::AssetMetadata { + name: b"ParaALocalAsset".to_vec(), + symbol: b"ParaALocalAsset".to_vec(), + decimals: 12, + }; + + let para_a_balances = MultiLocation::new(1, X2(Parachain(1), PalletInstance(1u8))); + let source_location_balances = parachain::AssetType::Xcm(para_a_balances); + let source_id_balances: parachain::AssetId = source_location_balances.clone().into(); + + let asset_metadata_balances = parachain::AssetMetadata { + name: b"ParaAToken".to_vec(), + symbol: b"ParaA".to_vec(), + decimals: 18, + }; + + ParaB::execute_with(|| { + assert_ok!(AssetManager::register_foreign_asset( + parachain::Origin::root(), + source_location_local_asset.clone(), + asset_metadata_local_asset, + 1u128, + true + )); + assert_ok!(AssetManager::set_asset_units_per_second( + parachain::Origin::root(), + source_location_local_asset, + 0u128, + 0 + )); + + assert_ok!(AssetManager::register_foreign_asset( + parachain::Origin::root(), + source_location_balances.clone(), + asset_metadata_balances, + 1u128, + true + )); + assert_ok!(AssetManager::set_asset_units_per_second( + parachain::Origin::root(), + source_location_balances, + 0u128, + 1 + )); + }); + + ParaA::execute_with(|| { + assert_ok!(AssetManager::register_local_asset( + parachain::Origin::root(), + PARAALICE.into(), + PARAALICE.into(), + true, + 1 + )); + + assert_ok!(LocalAssets::mint( + parachain::Origin::signed(PARAALICE.into()), + asset_id, + PARAALICE.into(), + 300000000000000 + )); + }); + + let dest = MultiLocation { + parents: 1, + interior: X2( + Parachain(2), + AccountKey20 { + network: NetworkId::Any, + key: PARAALICE.into(), + }, + ), + }; + + ParaA::execute_with(|| { + // free execution, full amount received + assert_ok!(XTokens::transfer_multicurrencies( + parachain::Origin::signed(PARAALICE.into()), + vec![ + (parachain::CurrencyId::LocalAssetReserve(asset_id), 100), + (parachain::CurrencyId::SelfReserve, 1000000) + ], + 0, + Box::new(VersionedMultiLocation::V1(dest)), + 800000 + )); + }); + + let mut alith_balance_asset_before = 0; + let mut alith_balance_native_token_before = 0; + + ParaA::execute_with(|| { + alith_balance_asset_before = LocalAssets::balance(asset_id, &PARAALICE.into()); + alith_balance_native_token_before = Balances::free_balance(&PARAALICE.into()); + }); + + let new_dest = MultiLocation { + parents: 1, + interior: X2( + Parachain(1), + AccountKey20 { + network: NetworkId::Any, + key: PARAALICE.into(), + }, + ), + }; + + ParaB::execute_with(|| { + // free execution, full amount received + assert_eq!( + Assets::balance(source_id_local_asset, &PARAALICE.into()), + 100 + ); + assert_eq!( + Assets::balance(source_id_balances, &PARAALICE.into()), + 1000000 + ); + + // free execution, full amount received + assert_ok!(XTokens::transfer_multicurrencies( + parachain::Origin::signed(PARAALICE.into()), + vec![ + (parachain::CurrencyId::ForeignAsset(source_id_balances), 4), + ( + parachain::CurrencyId::ForeignAsset(source_id_local_asset), + 50 + ) + ], + 0, + Box::new(VersionedMultiLocation::V1(new_dest)), + 4 + )); + }); + + ParaA::execute_with(|| { + let alith_balance_asset_after = LocalAssets::balance(asset_id, &PARAALICE.into()); + let alith_balance_native_token_after = Balances::free_balance(&PARAALICE.into()); + assert_eq!(alith_balance_asset_after, alith_balance_asset_before + 50); + assert_eq!( + alith_balance_native_token_before, + alith_balance_native_token_after + ); + }); + }); +} + use parity_scale_codec::{Decode, Encode}; use sp_io::hashing::blake2_256; diff --git a/tests/contracts/compiled/LocalAssetExtendedErc20Instance.json b/tests/contracts/compiled/LocalAssetExtendedErc20Instance.json new file mode 100644 index 0000000000..d69ba569ec --- /dev/null +++ b/tests/contracts/compiled/LocalAssetExtendedErc20Instance.json @@ -0,0 +1,27747 @@ +{ + "byteCode": "0x608060405273fffffffede9001a6f7f4798ccb76ef1e7f6647016000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073fffffffede9001a6f7f4798ccb76ef1e7f664701600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156100b957600080fd5b5061205c806100c96000396000f3fe60806040526004361061016a5760003560e01c806384810219116100d1578063a9059cbb1161008a578063ee5dc1e411610064578063ee5dc1e4146105c1578063f0350c04146105fe578063f5bfbd8a1461063b578063f8bf8e951461067857610171565b8063a9059cbb1461051c578063d3ba4b9e14610559578063dd62ed3e1461058457610171565b806384810219146103e65780638d1fdf2f1461040f57806395d89b411461044c5780639b5067e7146104775780639dc29fac146104a2578063a887c981146104df57610171565b8063313ce56711610123578063313ce5671461029c57806340c10f19146102c75780635ea20216146103045780636b8751c11461034157806370a082311461036c5780637eea1205146103a957610171565b80630131222f1461017657806306fdde03146101a1578063095ea7b3146101cc57806318160ddd146102095780631cddec191461023457806323b872dd1461025f57610171565b3661017157005b600080fd5b34801561018257600080fd5b5061018b6106b5565b6040516101989190611766565b60405180910390f35b3480156101ad57600080fd5b506101b66106df565b6040516101c3919061181a565b60405180910390f35b3480156101d857600080fd5b506101f360048036038101906101ee91906118b2565b61077a565b604051610200919061190d565b60405180910390f35b34801561021557600080fd5b5061021e610823565b60405161022b9190611937565b60405180910390f35b34801561024057600080fd5b506102496108ba565b604051610256919061190d565b60405180910390f35b34801561026b57600080fd5b5061028660048036038101906102819190611952565b610953565b604051610293919061190d565b60405180910390f35b3480156102a857600080fd5b506102b16109ff565b6040516102be91906119c1565b60405180910390f35b3480156102d357600080fd5b506102ee60048036038101906102e991906118b2565b610a96565b6040516102fb919061190d565b60405180910390f35b34801561031057600080fd5b5061032b600480360381019061032691906119dc565b610b3f565b604051610338919061190d565b60405180910390f35b34801561034d57600080fd5b50610356610be5565b604051610363919061190d565b60405180910390f35b34801561037857600080fd5b50610393600480360381019061038e91906119dc565b610c7e565b6040516103a09190611937565b60405180910390f35b3480156103b557600080fd5b506103d060048036038101906103cb9190611952565b610d22565b6040516103dd919061190d565b60405180910390f35b3480156103f257600080fd5b5061040d600480360381019061040891906119dc565b610e50565b005b34801561041b57600080fd5b50610436600480360381019061043191906119dc565b610ed4565b604051610443919061190d565b60405180910390f35b34801561045857600080fd5b50610461610f7a565b60405161046e919061181a565b60405180910390f35b34801561048357600080fd5b5061048c611015565b6040516104999190611a68565b60405180910390f35b3480156104ae57600080fd5b506104c960048036038101906104c491906118b2565b611039565b6040516104d6919061190d565b60405180910390f35b3480156104eb57600080fd5b50610506600480360381019061050191906118b2565b6110e2565b604051610513919061190d565b60405180910390f35b34801561052857600080fd5b50610543600480360381019061053e91906118b2565b61120d565b604051610550919061190d565b60405180910390f35b34801561056557600080fd5b5061056e6112b6565b60405161057b919061190d565b60405180910390f35b34801561059057600080fd5b506105ab60048036038101906105a69190611a83565b61134f565b6040516105b89190611937565b60405180910390f35b3480156105cd57600080fd5b506105e860048036038101906105e39190611b54565b6113f6565b6040516105f5919061190d565b60405180910390f35b34801561060a57600080fd5b50610625600480360381019061062091906119dc565b6114a8565b604051610632919061190d565b60405180910390f35b34801561064757600080fd5b50610662600480360381019061065d91906118b2565b61154e565b60405161066f919061190d565b60405180910390f35b34801561068457600080fd5b5061069f600480360381019061069a9190611be9565b611679565b6040516106ac919061190d565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801561074c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906107759190611d5d565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b384846040518363ffffffff1660e01b81526004016107d8929190611da6565b6020604051808303816000875af11580156107f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081b9190611dfb565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610891573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b59190611e3d565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631cddec196040518163ffffffff1660e01b81526004016020604051808303816000875af115801561092a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094e9190611dfb565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8585856040518463ffffffff1660e01b81526004016109b393929190611e6a565b6020604051808303816000875af11580156109d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f69190611dfb565b90509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a919190611eb6565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1984846040518363ffffffff1660e01b8152600401610af4929190611da6565b6020604051808303816000875af1158015610b13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b379190611dfb565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ea20216836040518263ffffffff1660e01b8152600401610b9b9190611766565b6020604051808303816000875af1158015610bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bde9190611dfb565b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636b8751c16040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c799190611dfb565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401610cda9190611766565b602060405180830381865afa158015610cf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1b9190611e3d565b9050919050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16868686604051602401610d7593929190611e6a565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610dff9190611f2a565b600060405180830381855af49150503d8060008114610e3a576040519150601f19603f3d011682016040523d82523d6000602084013e610e3f565b606091505b509150915081925050509392505050565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d1fdf2f836040518263ffffffff1660e01b8152600401610f309190611766565b6020604051808303816000875af1158015610f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f739190611dfb565b9050919050565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610fe7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906110109190611d5d565b905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dc29fac84846040518363ffffffff1660e01b8152600401611097929190611da6565b6020604051808303816000875af11580156110b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110da9190611dfb565b905092915050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168585604051602401611133929190611da6565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516111bd9190611f2a565b600060405180830381855af49150503d80600081146111f8576040519150601f19603f3d011682016040523d82523d6000602084013e6111fd565b606091505b5091509150819250505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b815260040161126b929190611da6565b6020604051808303816000875af115801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae9190611dfb565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d3ba4b9e6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611326573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134a9190611dfb565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e84846040518363ffffffff1660e01b81526004016113ad929190611f41565b602060405180830381865afa1580156113ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ee9190611e3d565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee5dc1e487878787876040518663ffffffff1660e01b815260040161145a959493929190611fa6565b6020604051808303816000875af1158015611479573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149d9190611dfb565b905095945050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f0350c04836040518263ffffffff1660e01b81526004016115049190611766565b6020604051808303816000875af1158015611523573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115479190611dfb565b9050919050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16858560405160240161159f929190611da6565b6040516020818303038152906040527f095ea7b3000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516116299190611f2a565b600060405180830381855af49150503d8060008114611664576040519150601f19603f3d011682016040523d82523d6000602084013e611669565b606091505b5091509150819250505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8bf8e958585856040518463ffffffff1660e01b81526004016116d993929190611fef565b6020604051808303816000875af11580156116f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171c9190611dfb565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061175082611725565b9050919050565b61176081611745565b82525050565b600060208201905061177b6000830184611757565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156117bb5780820151818401526020810190506117a0565b838111156117ca576000848401525b50505050565b6000601f19601f8301169050919050565b60006117ec82611781565b6117f6818561178c565b935061180681856020860161179d565b61180f816117d0565b840191505092915050565b6000602082019050818103600083015261183481846117e1565b905092915050565b6000604051905090565b600080fd5b600080fd5b61185981611745565b811461186457600080fd5b50565b60008135905061187681611850565b92915050565b6000819050919050565b61188f8161187c565b811461189a57600080fd5b50565b6000813590506118ac81611886565b92915050565b600080604083850312156118c9576118c8611846565b5b60006118d785828601611867565b92505060206118e88582860161189d565b9150509250929050565b60008115159050919050565b611907816118f2565b82525050565b600060208201905061192260008301846118fe565b92915050565b6119318161187c565b82525050565b600060208201905061194c6000830184611928565b92915050565b60008060006060848603121561196b5761196a611846565b5b600061197986828701611867565b935050602061198a86828701611867565b925050604061199b8682870161189d565b9150509250925092565b600060ff82169050919050565b6119bb816119a5565b82525050565b60006020820190506119d660008301846119b2565b92915050565b6000602082840312156119f2576119f1611846565b5b6000611a0084828501611867565b91505092915050565b6000819050919050565b6000611a2e611a29611a2484611725565b611a09565b611725565b9050919050565b6000611a4082611a13565b9050919050565b6000611a5282611a35565b9050919050565b611a6281611a47565b82525050565b6000602082019050611a7d6000830184611a59565b92915050565b60008060408385031215611a9a57611a99611846565b5b6000611aa885828601611867565b9250506020611ab985828601611867565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112611ae857611ae7611ac3565b5b8235905067ffffffffffffffff811115611b0557611b04611ac8565b5b602083019150836001820283011115611b2157611b20611acd565b5b9250929050565b611b31816119a5565b8114611b3c57600080fd5b50565b600081359050611b4e81611b28565b92915050565b600080600080600060608688031215611b7057611b6f611846565b5b600086013567ffffffffffffffff811115611b8e57611b8d61184b565b5b611b9a88828901611ad2565b9550955050602086013567ffffffffffffffff811115611bbd57611bbc61184b565b5b611bc988828901611ad2565b93509350506040611bdc88828901611b3f565b9150509295509295909350565b600080600060608486031215611c0257611c01611846565b5b6000611c1086828701611867565b9350506020611c2186828701611867565b9250506040611c3286828701611867565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611c79826117d0565b810181811067ffffffffffffffff82111715611c9857611c97611c41565b5b80604052505050565b6000611cab61183c565b9050611cb78282611c70565b919050565b600067ffffffffffffffff821115611cd757611cd6611c41565b5b611ce0826117d0565b9050602081019050919050565b6000611d00611cfb84611cbc565b611ca1565b905082815260208101848484011115611d1c57611d1b611c3c565b5b611d2784828561179d565b509392505050565b600082601f830112611d4457611d43611ac3565b5b8151611d54848260208601611ced565b91505092915050565b600060208284031215611d7357611d72611846565b5b600082015167ffffffffffffffff811115611d9157611d9061184b565b5b611d9d84828501611d2f565b91505092915050565b6000604082019050611dbb6000830185611757565b611dc86020830184611928565b9392505050565b611dd8816118f2565b8114611de357600080fd5b50565b600081519050611df581611dcf565b92915050565b600060208284031215611e1157611e10611846565b5b6000611e1f84828501611de6565b91505092915050565b600081519050611e3781611886565b92915050565b600060208284031215611e5357611e52611846565b5b6000611e6184828501611e28565b91505092915050565b6000606082019050611e7f6000830186611757565b611e8c6020830185611757565b611e996040830184611928565b949350505050565b600081519050611eb081611b28565b92915050565b600060208284031215611ecc57611ecb611846565b5b6000611eda84828501611ea1565b91505092915050565b600081519050919050565b600081905092915050565b6000611f0482611ee3565b611f0e8185611eee565b9350611f1e81856020860161179d565b80840191505092915050565b6000611f368284611ef9565b915081905092915050565b6000604082019050611f566000830185611757565b611f636020830184611757565b9392505050565b82818337600083830152505050565b6000611f85838561178c565b9350611f92838584611f6a565b611f9b836117d0565b840190509392505050565b60006060820190508181036000830152611fc1818789611f79565b90508181036020830152611fd6818587611f79565b9050611fe560408301846119b2565b9695505050505050565b60006060820190506120046000830186611757565b6120116020830185611757565b61201e6040830184611757565b94935050505056fea2646970667358221220bb130f9250effb623338d0a0c315a1bcd08d8c15c5754a8191f2673314da04c464736f6c634300080b0033", + "contract": { + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "approve_delegate", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "who", "type": "address" } + ], + "name": "balanceOf", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "burn", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "clear_metadata", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "freeze", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "freeze_asset", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "get_address", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "localasseterc20", + "outputs": [ + { + "internalType": "contract LocalAssetExtendedErc20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "mint", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "instance_address", + "type": "address" + } + ], + "name": "set_address_interface", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "string", "name": "symbol", "type": "string" }, + { "internalType": "uint8", "name": "decimals", "type": "uint8" } + ], + "name": "set_metadata", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "issuer", "type": "address" }, + { "internalType": "address", "name": "admin", "type": "address" }, + { "internalType": "address", "name": "freezer", "type": "address" } + ], + "name": "set_team", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "thaw", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "thaw_asset", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "transferFrom_delegate", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "transfer_delegate", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "transfer_ownership", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { "stateMutability": "payable", "type": "receive" } + ], + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "Function to check the amount of tokens that an owner allowed to a spender. Selector: dd62ed3e", + "params": { + "owner": "address The address which owns the funds.", + "spender": "address The address which will spend the funds." + }, + "returns": { + "_0": "A uint256 specifying the amount of tokens still available for the spender." + } + }, + "approve(address,uint256)": { + "details": "Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Selector: 095ea7b3", + "params": { + "spender": "The address which will spend the funds.", + "value": "The amount of tokens to be spent." + } + }, + "balanceOf(address)": { + "details": "Gets the balance of the specified address. Selector: 70a08231", + "params": { "who": "The address to query the balance of." }, + "returns": { + "_0": "An uint256 representing the amount owned by the passed address." + } + }, + "burn(address,uint256)": { + "details": "Burn tokens from an address Selector: 23b872dd", + "params": { + "from": "address The address from which you want to burn tokens", + "value": "uint256 the amount of tokens to be burnt" + } + }, + "clear_metadata()": { + "details": "Clear the name, symbol and decimals of your asset Selector: 23b872dd" + }, + "decimals()": { + "details": "Returns the decimals places of the token. Selector: 313ce567" + }, + "freeze(address)": { + "details": "Freeze an account, preventing it from operating with the asset Selector: 23b872dd", + "params": { "account": "address The address that you want to freeze" } + }, + "freeze_asset()": { + "details": "Freeze the entire asset operations Selector: 23b872dd" + }, + "mint(address,uint256)": { + "details": "Mint tokens to an address Selector: 23b872dd", + "params": { + "to": "address The address to which you want to mint tokens", + "value": "uint256 the amount of tokens to be minted" + } + }, + "name()": { + "details": "Returns the name of the token. Selector: 06fdde03" + }, + "set_metadata(string,string,uint8)": { + "details": "Specify the name, symbol and decimals of your asset Selector: 23b872dd", + "params": { + "decimals": "uint8 The number of decimals of your asset", + "name": "string The name of the asset", + "symbol": "string The symbol of the asset" + } + }, + "set_team(address,address,address)": { + "details": "Specify the issuer, admin and freezer of an asset Selector: 23b872dd", + "params": { + "admin": "address The address capable of burning tokens and unfreezing accounts/assets", + "freezer": "address The address capable of freezing accounts/asset", + "issuer": "address The address capable of issuing tokens" + } + }, + "symbol()": { + "details": "Returns the symbol of the token. Selector: 95d89b41" + }, + "thaw(address)": { + "details": "Unfreeze an account, letting it from operating againt with the asset Selector: 23b872dd", + "params": { + "account": "address The address that you want to unfreeze" + } + }, + "thaw_asset()": { + "details": "Unfreeze the entire asset operations Selector: 23b872dd" + }, + "totalSupply()": { + "details": "Total number of tokens in existence Selector: 18160ddd" + }, + "transfer(address,uint256)": { + "details": "Transfer token for a specified address Selector: a9059cbb", + "params": { + "to": "The address to transfer to.", + "value": "The amount to be transferred." + } + }, + "transferFrom(address,address,uint256)": { + "details": "Transfer tokens from one address to another Selector: 23b872dd", + "params": { + "from": "address The address which you want to send tokens from", + "to": "address The address which you want to transfer to", + "value": "uint256 the amount of tokens to be transferred" + } + }, + "transfer_ownership(address)": { + "details": "Transfer the ownership of an asset to a new account Selector: 23b872dd", + "params": { "owner": "address The address of the new owner" } + } + }, + "version": 1 + }, + "evm": { + "assembly": " /* \"main.sol\":6591:12064 contract LocalAssetExtendedErc20Instance is LocalAssetExtendedErc20 {... */\n mstore(0x40, 0x80)\n /* \"main.sol\":6800:6842 0xffFfFffEDe9001a6f7F4798cCb76ef1E7f664701 */\n 0xfffffffede9001a6f7f4798ccb76ef1e7f664701\n /* \"main.sol\":6727:6843 LocalAssetExtendedErc20 public localasseterc20 = LocalAssetExtendedErc20(0xffFfFffEDe9001a6f7F4798cCb76ef1E7f664701) */\n 0x00\n dup1\n 0x0100\n exp\n dup2\n sload\n dup2\n 0xffffffffffffffffffffffffffffffffffffffff\n mul\n not\n and\n swap1\n dup4\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n mul\n or\n swap1\n sstore\n pop\n /* \"main.sol\":6886:6928 0xffFfFffEDe9001a6f7F4798cCb76ef1E7f664701 */\n 0xfffffffede9001a6f7f4798ccb76ef1e7f664701\n /* \"main.sol\":6853:6928 address localasseterc20address = 0xffFfFffEDe9001a6f7F4798cCb76ef1E7f664701 */\n 0x01\n exp(0x0100, 0x00)\n dup2\n sload\n dup2\n 0xffffffffffffffffffffffffffffffffffffffff\n mul\n not\n and\n swap1\n dup4\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n mul\n or\n swap1\n sstore\n pop\n /* \"main.sol\":6591:12064 contract LocalAssetExtendedErc20Instance is LocalAssetExtendedErc20 {... */\n callvalue\n dup1\n iszero\n tag_1\n jumpi\n 0x00\n dup1\n revert\ntag_1:\n pop\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n /* \"main.sol\":6591:12064 contract LocalAssetExtendedErc20Instance is LocalAssetExtendedErc20 {... */\n mstore(0x40, 0x80)\n jumpi(tag_1, lt(calldatasize, 0x04))\n shr(0xe0, calldataload(0x00))\n dup1\n 0x84810219\n gt\n tag_28\n jumpi\n dup1\n 0xa9059cbb\n gt\n tag_29\n jumpi\n dup1\n 0xee5dc1e4\n gt\n tag_30\n jumpi\n dup1\n 0xee5dc1e4\n eq\n tag_24\n jumpi\n dup1\n 0xf0350c04\n eq\n tag_25\n jumpi\n dup1\n 0xf5bfbd8a\n eq\n tag_26\n jumpi\n dup1\n 0xf8bf8e95\n eq\n tag_27\n jumpi\n jump(tag_2)\n tag_30:\n dup1\n 0xa9059cbb\n eq\n tag_21\n jumpi\n dup1\n 0xd3ba4b9e\n eq\n tag_22\n jumpi\n dup1\n 0xdd62ed3e\n eq\n tag_23\n jumpi\n jump(tag_2)\n tag_29:\n dup1\n 0x84810219\n eq\n tag_15\n jumpi\n dup1\n 0x8d1fdf2f\n eq\n tag_16\n jumpi\n dup1\n 0x95d89b41\n eq\n tag_17\n jumpi\n dup1\n 0x9b5067e7\n eq\n tag_18\n jumpi\n dup1\n 0x9dc29fac\n eq\n tag_19\n jumpi\n dup1\n 0xa887c981\n eq\n tag_20\n jumpi\n jump(tag_2)\n tag_28:\n dup1\n 0x313ce567\n gt\n tag_31\n jumpi\n dup1\n 0x313ce567\n eq\n tag_9\n jumpi\n dup1\n 0x40c10f19\n eq\n tag_10\n jumpi\n dup1\n 0x5ea20216\n eq\n tag_11\n jumpi\n dup1\n 0x6b8751c1\n eq\n tag_12\n jumpi\n dup1\n 0x70a08231\n eq\n tag_13\n jumpi\n dup1\n 0x7eea1205\n eq\n tag_14\n jumpi\n jump(tag_2)\n tag_31:\n dup1\n 0x0131222f\n eq\n tag_3\n jumpi\n dup1\n 0x06fdde03\n eq\n tag_4\n jumpi\n dup1\n 0x095ea7b3\n eq\n tag_5\n jumpi\n dup1\n 0x18160ddd\n eq\n tag_6\n jumpi\n dup1\n 0x1cddec19\n eq\n tag_7\n jumpi\n dup1\n 0x23b872dd\n eq\n tag_8\n jumpi\n jump(tag_2)\n tag_1:\n jumpi(tag_2, calldatasize)\n stop\n tag_2:\n 0x00\n dup1\n revert\n /* \"main.sol\":7268:7382 function get_address() public view returns(address) {... */\n tag_3:\n callvalue\n dup1\n iszero\n tag_34\n jumpi\n 0x00\n dup1\n revert\n tag_34:\n pop\n tag_35\n tag_36\n jump\t// in\n tag_35:\n mload(0x40)\n tag_37\n swap2\n swap1\n tag_38\n jump\t// in\n tag_37:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":7396:7601 function name() override external view returns (string memory) {... */\n tag_4:\n callvalue\n dup1\n iszero\n tag_39\n jumpi\n 0x00\n dup1\n revert\n tag_39:\n pop\n tag_40\n tag_41\n jump\t// in\n tag_40:\n mload(0x40)\n tag_42\n swap2\n swap1\n tag_43\n jump\t// in\n tag_42:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":10928:11085 function approve(address spender, uint256 value) override external returns (bool) {... */\n tag_5:\n callvalue\n dup1\n iszero\n tag_44\n jumpi\n 0x00\n dup1\n revert\n tag_44:\n pop\n tag_45\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_46\n swap2\n swap1\n tag_47\n jump\t// in\n tag_46:\n tag_48\n jump\t// in\n tag_45:\n mload(0x40)\n tag_49\n swap2\n swap1\n tag_50\n jump\t// in\n tag_49:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":8081:8293 function totalSupply() override external view returns (uint256){... */\n tag_6:\n callvalue\n dup1\n iszero\n tag_51\n jumpi\n 0x00\n dup1\n revert\n tag_51:\n pop\n tag_52\n tag_53\n jump\t// in\n tag_52:\n mload(0x40)\n tag_54\n swap2\n swap1\n tag_55\n jump\t// in\n tag_54:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":9727:9850 function thaw_asset() override external returns (bool) {... */\n tag_7:\n callvalue\n dup1\n iszero\n tag_56\n jumpi\n 0x00\n dup1\n revert\n tag_56:\n pop\n tag_57\n tag_58\n jump\t// in\n tag_57:\n mload(0x40)\n tag_59\n swap2\n swap1\n tag_50\n jump\t// in\n tag_59:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":11419:11661 function transferFrom(... */\n tag_8:\n callvalue\n dup1\n iszero\n tag_60\n jumpi\n 0x00\n dup1\n revert\n tag_60:\n pop\n tag_61\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_62\n swap2\n swap1\n tag_63\n jump\t// in\n tag_62:\n tag_64\n jump\t// in\n tag_61:\n mload(0x40)\n tag_65\n swap2\n swap1\n tag_50\n jump\t// in\n tag_65:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":7862:8067 function decimals() override external view returns (uint8) {... */\n tag_9:\n callvalue\n dup1\n iszero\n tag_66\n jumpi\n 0x00\n dup1\n revert\n tag_66:\n pop\n tag_67\n tag_68\n jump\t// in\n tag_67:\n mload(0x40)\n tag_69\n swap2\n swap1\n tag_70\n jump\t// in\n tag_69:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":8966:9111 function mint(address to, uint256 value) override external returns (bool) {... */\n tag_10:\n callvalue\n dup1\n iszero\n tag_71\n jumpi\n 0x00\n dup1\n revert\n tag_71:\n pop\n tag_72\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_73\n swap2\n swap1\n tag_47\n jump\t// in\n tag_73:\n tag_74\n jump\t// in\n tag_72:\n mload(0x40)\n tag_75\n swap2\n swap1\n tag_50\n jump\t// in\n tag_75:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":9439:9572 function thaw(address account) override external returns (bool) {... */\n tag_11:\n callvalue\n dup1\n iszero\n tag_76\n jumpi\n 0x00\n dup1\n revert\n tag_76:\n pop\n tag_77\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_78\n swap2\n swap1\n tag_79\n jump\t// in\n tag_78:\n tag_80\n jump\t// in\n tag_77:\n mload(0x40)\n tag_81\n swap2\n swap1\n tag_50\n jump\t// in\n tag_81:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":9586:9713 function freeze_asset() override external returns (bool) {... */\n tag_12:\n callvalue\n dup1\n iszero\n tag_82\n jumpi\n 0x00\n dup1\n revert\n tag_82:\n pop\n tag_83\n tag_84\n jump\t// in\n tag_83:\n mload(0x40)\n tag_85\n swap2\n swap1\n tag_50\n jump\t// in\n tag_85:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":8319:8541 function balanceOf(address who) override external view returns (uint256){... */\n tag_13:\n callvalue\n dup1\n iszero\n tag_86\n jumpi\n 0x00\n dup1\n revert\n tag_86:\n pop\n tag_87\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_88\n swap2\n swap1\n tag_79\n jump\t// in\n tag_88:\n tag_89\n jump\t// in\n tag_87:\n mload(0x40)\n tag_90\n swap2\n swap1\n tag_55\n jump\t// in\n tag_90:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":11687:12058 function transferFrom_delegate(... */\n tag_14:\n callvalue\n dup1\n iszero\n tag_91\n jumpi\n 0x00\n dup1\n revert\n tag_91:\n pop\n tag_92\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_93\n swap2\n swap1\n tag_63\n jump\t// in\n tag_93:\n tag_94\n jump\t// in\n tag_92:\n mload(0x40)\n tag_95\n swap2\n swap1\n tag_50\n jump\t// in\n tag_95:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":7039:7254 function set_address_interface(address instance_address) public {... */\n tag_15:\n callvalue\n dup1\n iszero\n tag_96\n jumpi\n 0x00\n dup1\n revert\n tag_96:\n pop\n tag_97\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_98\n swap2\n swap1\n tag_79\n jump\t// in\n tag_98:\n tag_99\n jump\t// in\n tag_97:\n stop\n /* \"main.sol\":9288:9425 function freeze(address account) override external returns (bool) {... */\n tag_16:\n callvalue\n dup1\n iszero\n tag_100\n jumpi\n 0x00\n dup1\n revert\n tag_100:\n pop\n tag_101\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_102\n swap2\n swap1\n tag_79\n jump\t// in\n tag_102:\n tag_103\n jump\t// in\n tag_101:\n mload(0x40)\n tag_104\n swap2\n swap1\n tag_50\n jump\t// in\n tag_104:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":7627:7836 function symbol() override external view returns (string memory) {... */\n tag_17:\n callvalue\n dup1\n iszero\n tag_105\n jumpi\n 0x00\n dup1\n revert\n tag_105:\n pop\n tag_106\n tag_107\n jump\t// in\n tag_106:\n mload(0x40)\n tag_108\n swap2\n swap1\n tag_43\n jump\t// in\n tag_108:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":6727:6843 LocalAssetExtendedErc20 public localasseterc20 = LocalAssetExtendedErc20(0xffFfFffEDe9001a6f7F4798cCb76ef1E7f664701) */\n tag_18:\n callvalue\n dup1\n iszero\n tag_109\n jumpi\n 0x00\n dup1\n revert\n tag_109:\n pop\n tag_110\n tag_111\n jump\t// in\n tag_110:\n mload(0x40)\n tag_112\n swap2\n swap1\n tag_113\n jump\t// in\n tag_112:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":9125:9274 function burn(address from, uint256 value) override external returns (bool) {... */\n tag_19:\n callvalue\n dup1\n iszero\n tag_114\n jumpi\n 0x00\n dup1\n revert\n tag_114:\n pop\n tag_115\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_116\n swap2\n swap1\n tag_47\n jump\t// in\n tag_116:\n tag_117\n jump\t// in\n tag_115:\n mload(0x40)\n tag_118\n swap2\n swap1\n tag_50\n jump\t// in\n tag_118:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":10616:10902 function transfer_delegate(address to, uint256 value) external returns (bool) {... */\n tag_20:\n callvalue\n dup1\n iszero\n tag_119\n jumpi\n 0x00\n dup1\n revert\n tag_119:\n pop\n tag_120\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_121\n swap2\n swap1\n tag_47\n jump\t// in\n tag_121:\n tag_122\n jump\t// in\n tag_120:\n mload(0x40)\n tag_123\n swap2\n swap1\n tag_50\n jump\t// in\n tag_123:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":8799:8952 function transfer(address to, uint256 value) override external returns (bool) {... */\n tag_21:\n callvalue\n dup1\n iszero\n tag_124\n jumpi\n 0x00\n dup1\n revert\n tag_124:\n pop\n tag_125\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_126\n swap2\n swap1\n tag_47\n jump\t// in\n tag_126:\n tag_127\n jump\t// in\n tag_125:\n mload(0x40)\n tag_128\n swap2\n swap1\n tag_50\n jump\t// in\n tag_128:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":10459:10590 function clear_metadata() override external returns (bool) {... */\n tag_22:\n callvalue\n dup1\n iszero\n tag_129\n jumpi\n 0x00\n dup1\n revert\n tag_129:\n pop\n tag_130\n tag_131\n jump\t// in\n tag_130:\n mload(0x40)\n tag_132\n swap2\n swap1\n tag_50\n jump\t// in\n tag_132:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":8567:8785 function allowance(... */\n tag_23:\n callvalue\n dup1\n iszero\n tag_133\n jumpi\n 0x00\n dup1\n revert\n tag_133:\n pop\n tag_134\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_135\n swap2\n swap1\n tag_136\n jump\t// in\n tag_135:\n tag_137\n jump\t// in\n tag_134:\n mload(0x40)\n tag_138\n swap2\n swap1\n tag_55\n jump\t// in\n tag_138:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":10236:10445 function set_metadata(string calldata name, string calldata symbol, uint8 decimals) override external returns (bool) {... */\n tag_24:\n callvalue\n dup1\n iszero\n tag_139\n jumpi\n 0x00\n dup1\n revert\n tag_139:\n pop\n tag_140\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_141\n swap2\n swap1\n tag_142\n jump\t// in\n tag_141:\n tag_143\n jump\t// in\n tag_140:\n mload(0x40)\n tag_144\n swap2\n swap1\n tag_50\n jump\t// in\n tag_144:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":9864:10021 function transfer_ownership(address owner) override external returns (bool) {... */\n tag_25:\n callvalue\n dup1\n iszero\n tag_145\n jumpi\n 0x00\n dup1\n revert\n tag_145:\n pop\n tag_146\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_147\n swap2\n swap1\n tag_79\n jump\t// in\n tag_147:\n tag_148\n jump\t// in\n tag_146:\n mload(0x40)\n tag_149\n swap2\n swap1\n tag_50\n jump\t// in\n tag_149:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":11099:11393 function approve_delegate(address spender, uint256 value) external returns (bool) {... */\n tag_26:\n callvalue\n dup1\n iszero\n tag_150\n jumpi\n 0x00\n dup1\n revert\n tag_150:\n pop\n tag_151\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_152\n swap2\n swap1\n tag_47\n jump\t// in\n tag_152:\n tag_153\n jump\t// in\n tag_151:\n mload(0x40)\n tag_154\n swap2\n swap1\n tag_50\n jump\t// in\n tag_154:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":10035:10222 function set_team(address issuer, address admin, address freezer) override external returns (bool) {... */\n tag_27:\n callvalue\n dup1\n iszero\n tag_155\n jumpi\n 0x00\n dup1\n revert\n tag_155:\n pop\n tag_156\n 0x04\n dup1\n calldatasize\n sub\n dup2\n add\n swap1\n tag_157\n swap2\n swap1\n tag_158\n jump\t// in\n tag_157:\n tag_159\n jump\t// in\n tag_156:\n mload(0x40)\n tag_160\n swap2\n swap1\n tag_50\n jump\t// in\n tag_160:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"main.sol\":7268:7382 function get_address() public view returns(address) {... */\n tag_36:\n /* \"main.sol\":7311:7318 address */\n 0x00\n /* \"main.sol\":7345:7367 localasseterc20address */\n 0x01\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":7338:7367 return localasseterc20address */\n swap1\n pop\n /* \"main.sol\":7268:7382 function get_address() public view returns(address) {... */\n swap1\n jump\t// out\n /* \"main.sol\":7396:7601 function name() override external view returns (string memory) {... */\n tag_41:\n /* \"main.sol\":7444:7457 string memory */\n 0x60\n /* \"main.sol\":7564:7579 localasseterc20 */\n 0x00\n dup1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":7564:7584 localasseterc20.name */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x06fdde03\n /* \"main.sol\":7564:7586 localasseterc20.name() */\n mload(0x40)\n dup2\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n 0x00\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n dup7\n gas\n staticcall\n iszero\n dup1\n iszero\n tag_164\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_164:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n 0x00\n dup3\n returndatacopy\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_165\n swap2\n swap1\n tag_166\n jump\t// in\n tag_165:\n /* \"main.sol\":7557:7586 return localasseterc20.name() */\n swap1\n pop\n /* \"main.sol\":7396:7601 function name() override external view returns (string memory) {... */\n swap1\n jump\t// out\n /* \"main.sol\":10928:11085 function approve(address spender, uint256 value) override external returns (bool) {... */\n tag_48:\n /* \"main.sol\":11004:11008 bool */\n 0x00\n /* \"main.sol\":11031:11046 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":11031:11054 localasseterc20.approve */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x095ea7b3\n /* \"main.sol\":11055:11062 spender */\n dup5\n /* \"main.sol\":11064:11069 value */\n dup5\n /* \"main.sol\":11031:11070 localasseterc20.approve(spender, value) */\n mload(0x40)\n dup4\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_168\n swap3\n swap2\n swap1\n tag_169\n jump\t// in\n tag_168:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_171\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_171:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_172\n swap2\n swap1\n tag_173\n jump\t// in\n tag_172:\n /* \"main.sol\":11024:11070 return localasseterc20.approve(spender, value) */\n swap1\n pop\n /* \"main.sol\":10928:11085 function approve(address spender, uint256 value) override external returns (bool) {... */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"main.sol\":8081:8293 function totalSupply() override external view returns (uint256){... */\n tag_53:\n /* \"main.sol\":8136:8143 uint256 */\n 0x00\n /* \"main.sol\":8249:8264 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":8249:8276 localasseterc20.totalSupply */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x18160ddd\n /* \"main.sol\":8249:8278 localasseterc20.totalSupply() */\n mload(0x40)\n dup2\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n dup7\n gas\n staticcall\n iszero\n dup1\n iszero\n tag_176\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_176:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_177\n swap2\n swap1\n tag_178\n jump\t// in\n tag_177:\n /* \"main.sol\":8242:8278 return localasseterc20.totalSupply() */\n swap1\n pop\n /* \"main.sol\":8081:8293 function totalSupply() override external view returns (uint256){... */\n swap1\n jump\t// out\n /* \"main.sol\":9727:9850 function thaw_asset() override external returns (bool) {... */\n tag_58:\n /* \"main.sol\":9776:9780 bool */\n 0x00\n /* \"main.sol\":9807:9822 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":9807:9833 localasseterc20.thaw_asset */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x1cddec19\n /* \"main.sol\":9807:9835 localasseterc20.thaw_asset() */\n mload(0x40)\n dup2\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_181\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_181:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_182\n swap2\n swap1\n tag_173\n jump\t// in\n tag_182:\n /* \"main.sol\":9800:9835 return localasseterc20.thaw_asset() */\n swap1\n pop\n /* \"main.sol\":9727:9850 function thaw_asset() override external returns (bool) {... */\n swap1\n jump\t// out\n /* \"main.sol\":11419:11661 function transferFrom(... */\n tag_64:\n /* \"main.sol\":11570:11574 bool */\n 0x00\n /* \"main.sol\":11601:11616 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":11601:11629 localasseterc20.transferFrom */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x23b872dd\n /* \"main.sol\":11630:11634 from */\n dup6\n /* \"main.sol\":11636:11638 to */\n dup6\n /* \"main.sol\":11640:11645 value */\n dup6\n /* \"main.sol\":11601:11646 localasseterc20.transferFrom(from, to, value) */\n mload(0x40)\n dup5\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_184\n swap4\n swap3\n swap2\n swap1\n tag_185\n jump\t// in\n tag_184:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_187\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_187:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_188\n swap2\n swap1\n tag_173\n jump\t// in\n tag_188:\n /* \"main.sol\":11594:11646 return localasseterc20.transferFrom(from, to, value) */\n swap1\n pop\n /* \"main.sol\":11419:11661 function transferFrom(... */\n swap4\n swap3\n pop\n pop\n pop\n jump\t// out\n /* \"main.sol\":7862:8067 function decimals() override external view returns (uint8) {... */\n tag_68:\n /* \"main.sol\":7914:7919 uint8 */\n 0x00\n /* \"main.sol\":8026:8041 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":8026:8050 localasseterc20.decimals */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x313ce567\n /* \"main.sol\":8026:8052 localasseterc20.decimals() */\n mload(0x40)\n dup2\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n dup7\n gas\n staticcall\n iszero\n dup1\n iszero\n tag_191\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_191:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_192\n swap2\n swap1\n tag_193\n jump\t// in\n tag_192:\n /* \"main.sol\":8019:8052 return localasseterc20.decimals() */\n swap1\n pop\n /* \"main.sol\":7862:8067 function decimals() override external view returns (uint8) {... */\n swap1\n jump\t// out\n /* \"main.sol\":8966:9111 function mint(address to, uint256 value) override external returns (bool) {... */\n tag_74:\n /* \"main.sol\":9034:9038 bool */\n 0x00\n /* \"main.sol\":9065:9080 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":9065:9085 localasseterc20.mint */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x40c10f19\n /* \"main.sol\":9086:9088 to */\n dup5\n /* \"main.sol\":9090:9095 value */\n dup5\n /* \"main.sol\":9065:9096 localasseterc20.mint(to, value) */\n mload(0x40)\n dup4\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_195\n swap3\n swap2\n swap1\n tag_169\n jump\t// in\n tag_195:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_197\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_197:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_198\n swap2\n swap1\n tag_173\n jump\t// in\n tag_198:\n /* \"main.sol\":9058:9096 return localasseterc20.mint(to, value) */\n swap1\n pop\n /* \"main.sol\":8966:9111 function mint(address to, uint256 value) override external returns (bool) {... */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"main.sol\":9439:9572 function thaw(address account) override external returns (bool) {... */\n tag_80:\n /* \"main.sol\":9497:9501 bool */\n 0x00\n /* \"main.sol\":9528:9543 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":9528:9548 localasseterc20.thaw */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x5ea20216\n /* \"main.sol\":9549:9556 account */\n dup4\n /* \"main.sol\":9528:9557 localasseterc20.thaw(account) */\n mload(0x40)\n dup3\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_200\n swap2\n swap1\n tag_38\n jump\t// in\n tag_200:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_202\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_202:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_203\n swap2\n swap1\n tag_173\n jump\t// in\n tag_203:\n /* \"main.sol\":9521:9557 return localasseterc20.thaw(account) */\n swap1\n pop\n /* \"main.sol\":9439:9572 function thaw(address account) override external returns (bool) {... */\n swap2\n swap1\n pop\n jump\t// out\n /* \"main.sol\":9586:9713 function freeze_asset() override external returns (bool) {... */\n tag_84:\n /* \"main.sol\":9637:9641 bool */\n 0x00\n /* \"main.sol\":9668:9683 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":9668:9696 localasseterc20.freeze_asset */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x6b8751c1\n /* \"main.sol\":9668:9698 localasseterc20.freeze_asset() */\n mload(0x40)\n dup2\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_206\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_206:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_207\n swap2\n swap1\n tag_173\n jump\t// in\n tag_207:\n /* \"main.sol\":9661:9698 return localasseterc20.freeze_asset() */\n swap1\n pop\n /* \"main.sol\":9586:9713 function freeze_asset() override external returns (bool) {... */\n swap1\n jump\t// out\n /* \"main.sol\":8319:8541 function balanceOf(address who) override external view returns (uint256){... */\n tag_89:\n /* \"main.sol\":8383:8390 uint256 */\n 0x00\n /* \"main.sol\":8496:8511 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":8496:8521 localasseterc20.balanceOf */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x70a08231\n /* \"main.sol\":8522:8525 who */\n dup4\n /* \"main.sol\":8496:8526 localasseterc20.balanceOf(who) */\n mload(0x40)\n dup3\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_209\n swap2\n swap1\n tag_38\n jump\t// in\n tag_209:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n dup7\n gas\n staticcall\n iszero\n dup1\n iszero\n tag_211\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_211:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_212\n swap2\n swap1\n tag_178\n jump\t// in\n tag_212:\n /* \"main.sol\":8489:8526 return localasseterc20.balanceOf(who) */\n swap1\n pop\n /* \"main.sol\":8319:8541 function balanceOf(address who) override external view returns (uint256){... */\n swap2\n swap1\n pop\n jump\t// out\n /* \"main.sol\":11687:12058 function transferFrom_delegate(... */\n tag_94:\n /* \"main.sol\":11826:11830 bool */\n 0x00\n /* \"main.sol\":11847:11858 bool result */\n dup1\n /* \"main.sol\":11860:11877 bytes memory data */\n 0x00\n /* \"main.sol\":11881:11903 localasseterc20address */\n 0x01\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":11881:11916 localasseterc20address.delegatecall */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":11999:12003 from */\n dup7\n /* \"main.sol\":12005:12007 to */\n dup7\n /* \"main.sol\":12009:12014 value */\n dup7\n /* \"main.sol\":11934:12015 abi.encodeWithSignature(\"transferFrom(address,address,uint256)\", from, to, value) */\n add(0x24, mload(0x40))\n tag_214\n swap4\n swap3\n swap2\n swap1\n tag_185\n jump\t// in\n tag_214:\n mload(0x40)\n 0x20\n dup2\n dup4\n sub\n sub\n dup2\n mstore\n swap1\n 0x40\n mstore\n and(not(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x23b872dd00000000000000000000000000000000000000000000000000000000)\n 0x20\n dup3\n add\n dup1\n mload\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n dup4\n dup2\n dup4\n and\n or\n dup4\n mstore\n pop\n pop\n pop\n pop\n /* \"main.sol\":11881:12016 localasseterc20address.delegatecall(... */\n mload(0x40)\n tag_215\n swap2\n swap1\n tag_216\n jump\t// in\n tag_215:\n 0x00\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n dup6\n gas\n delegatecall\n swap2\n pop\n pop\n returndatasize\n dup1\n 0x00\n dup2\n eq\n tag_219\n jumpi\n mload(0x40)\n swap2\n pop\n and(add(returndatasize, 0x3f), not(0x1f))\n dup3\n add\n 0x40\n mstore\n returndatasize\n dup3\n mstore\n returndatasize\n 0x00\n 0x20\n dup5\n add\n returndatacopy\n jump(tag_218)\n tag_219:\n 0x60\n swap2\n pop\n tag_218:\n pop\n /* \"main.sol\":11846:12016 (bool result, bytes memory data) = localasseterc20address.delegatecall(... */\n swap2\n pop\n swap2\n pop\n /* \"main.sol\":12037:12043 result */\n dup2\n /* \"main.sol\":12030:12043 return result */\n swap3\n pop\n pop\n pop\n /* \"main.sol\":11687:12058 function transferFrom_delegate(... */\n swap4\n swap3\n pop\n pop\n pop\n jump\t// out\n /* \"main.sol\":7039:7254 function set_address_interface(address instance_address) public {... */\n tag_99:\n /* \"main.sol\":7163:7179 instance_address */\n dup1\n /* \"main.sol\":7121:7136 localasseterc20 */\n 0x00\n dup1\n /* \"main.sol\":7121:7180 localasseterc20 = LocalAssetExtendedErc20(instance_address) */\n 0x0100\n exp\n dup2\n sload\n dup2\n 0xffffffffffffffffffffffffffffffffffffffff\n mul\n not\n and\n swap1\n dup4\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n mul\n or\n swap1\n sstore\n pop\n /* \"main.sol\":7223:7239 instance_address */\n dup1\n /* \"main.sol\":7198:7220 localasseterc20address */\n 0x01\n 0x00\n /* \"main.sol\":7198:7239 localasseterc20address = instance_address */\n 0x0100\n exp\n dup2\n sload\n dup2\n 0xffffffffffffffffffffffffffffffffffffffff\n mul\n not\n and\n swap1\n dup4\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n mul\n or\n swap1\n sstore\n pop\n /* \"main.sol\":7039:7254 function set_address_interface(address instance_address) public {... */\n pop\n jump\t// out\n /* \"main.sol\":9288:9425 function freeze(address account) override external returns (bool) {... */\n tag_103:\n /* \"main.sol\":9348:9352 bool */\n 0x00\n /* \"main.sol\":9379:9394 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":9379:9401 localasseterc20.freeze */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x8d1fdf2f\n /* \"main.sol\":9402:9409 account */\n dup4\n /* \"main.sol\":9379:9410 localasseterc20.freeze(account) */\n mload(0x40)\n dup3\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_222\n swap2\n swap1\n tag_38\n jump\t// in\n tag_222:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_224\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_224:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_225\n swap2\n swap1\n tag_173\n jump\t// in\n tag_225:\n /* \"main.sol\":9372:9410 return localasseterc20.freeze(account) */\n swap1\n pop\n /* \"main.sol\":9288:9425 function freeze(address account) override external returns (bool) {... */\n swap2\n swap1\n pop\n jump\t// out\n /* \"main.sol\":7627:7836 function symbol() override external view returns (string memory) {... */\n tag_107:\n /* \"main.sol\":7677:7690 string memory */\n 0x60\n /* \"main.sol\":7797:7812 localasseterc20 */\n 0x00\n dup1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":7797:7819 localasseterc20.symbol */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x95d89b41\n /* \"main.sol\":7797:7821 localasseterc20.symbol() */\n mload(0x40)\n dup2\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n 0x00\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n dup7\n gas\n staticcall\n iszero\n dup1\n iszero\n tag_228\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_228:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n 0x00\n dup3\n returndatacopy\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_229\n swap2\n swap1\n tag_166\n jump\t// in\n tag_229:\n /* \"main.sol\":7790:7821 return localasseterc20.symbol() */\n swap1\n pop\n /* \"main.sol\":7627:7836 function symbol() override external view returns (string memory) {... */\n swap1\n jump\t// out\n /* \"main.sol\":6727:6843 LocalAssetExtendedErc20 public localasseterc20 = LocalAssetExtendedErc20(0xffFfFffEDe9001a6f7F4798cCb76ef1E7f664701) */\n tag_111:\n 0x00\n dup1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n dup2\n jump\t// out\n /* \"main.sol\":9125:9274 function burn(address from, uint256 value) override external returns (bool) {... */\n tag_117:\n /* \"main.sol\":9195:9199 bool */\n 0x00\n /* \"main.sol\":9226:9241 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":9226:9246 localasseterc20.burn */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0x9dc29fac\n /* \"main.sol\":9247:9251 from */\n dup5\n /* \"main.sol\":9253:9258 value */\n dup5\n /* \"main.sol\":9226:9259 localasseterc20.burn(from, value) */\n mload(0x40)\n dup4\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_231\n swap3\n swap2\n swap1\n tag_169\n jump\t// in\n tag_231:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_233\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_233:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_234\n swap2\n swap1\n tag_173\n jump\t// in\n tag_234:\n /* \"main.sol\":9219:9259 return localasseterc20.burn(from, value) */\n swap1\n pop\n /* \"main.sol\":9125:9274 function burn(address from, uint256 value) override external returns (bool) {... */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"main.sol\":10616:10902 function transfer_delegate(address to, uint256 value) external returns (bool) {... */\n tag_122:\n /* \"main.sol\":10688:10692 bool */\n 0x00\n /* \"main.sol\":10709:10720 bool result */\n dup1\n /* \"main.sol\":10722:10739 bytes memory data */\n 0x00\n /* \"main.sol\":10743:10765 localasseterc20address */\n 0x01\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":10743:10778 localasseterc20address.delegatecall */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":10849:10851 to */\n dup6\n /* \"main.sol\":10853:10858 value */\n dup6\n /* \"main.sol\":10796:10859 abi.encodeWithSignature(\"transfer(address,uint256)\", to, value) */\n add(0x24, mload(0x40))\n tag_236\n swap3\n swap2\n swap1\n tag_169\n jump\t// in\n tag_236:\n mload(0x40)\n 0x20\n dup2\n dup4\n sub\n sub\n dup2\n mstore\n swap1\n 0x40\n mstore\n and(not(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\n 0x20\n dup3\n add\n dup1\n mload\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n dup4\n dup2\n dup4\n and\n or\n dup4\n mstore\n pop\n pop\n pop\n pop\n /* \"main.sol\":10743:10860 localasseterc20address.delegatecall(... */\n mload(0x40)\n tag_237\n swap2\n swap1\n tag_216\n jump\t// in\n tag_237:\n 0x00\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n dup6\n gas\n delegatecall\n swap2\n pop\n pop\n returndatasize\n dup1\n 0x00\n dup2\n eq\n tag_240\n jumpi\n mload(0x40)\n swap2\n pop\n and(add(returndatasize, 0x3f), not(0x1f))\n dup3\n add\n 0x40\n mstore\n returndatasize\n dup3\n mstore\n returndatasize\n 0x00\n 0x20\n dup5\n add\n returndatacopy\n jump(tag_239)\n tag_240:\n 0x60\n swap2\n pop\n tag_239:\n pop\n /* \"main.sol\":10708:10860 (bool result, bytes memory data) = localasseterc20address.delegatecall(... */\n swap2\n pop\n swap2\n pop\n /* \"main.sol\":10881:10887 result */\n dup2\n /* \"main.sol\":10874:10887 return result */\n swap3\n pop\n pop\n pop\n /* \"main.sol\":10616:10902 function transfer_delegate(address to, uint256 value) external returns (bool) {... */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"main.sol\":8799:8952 function transfer(address to, uint256 value) override external returns (bool) {... */\n tag_127:\n /* \"main.sol\":8871:8875 bool */\n 0x00\n /* \"main.sol\":8902:8917 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":8902:8926 localasseterc20.transfer */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0xa9059cbb\n /* \"main.sol\":8927:8929 to */\n dup5\n /* \"main.sol\":8931:8936 value */\n dup5\n /* \"main.sol\":8902:8937 localasseterc20.transfer(to, value) */\n mload(0x40)\n dup4\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_242\n swap3\n swap2\n swap1\n tag_169\n jump\t// in\n tag_242:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_244\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_244:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_245\n swap2\n swap1\n tag_173\n jump\t// in\n tag_245:\n /* \"main.sol\":8895:8937 return localasseterc20.transfer(to, value) */\n swap1\n pop\n /* \"main.sol\":8799:8952 function transfer(address to, uint256 value) override external returns (bool) {... */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"main.sol\":10459:10590 function clear_metadata() override external returns (bool) {... */\n tag_131:\n /* \"main.sol\":10512:10516 bool */\n 0x00\n /* \"main.sol\":10543:10558 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":10543:10573 localasseterc20.clear_metadata */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0xd3ba4b9e\n /* \"main.sol\":10543:10575 localasseterc20.clear_metadata() */\n mload(0x40)\n dup2\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_248\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_248:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_249\n swap2\n swap1\n tag_173\n jump\t// in\n tag_249:\n /* \"main.sol\":10536:10575 return localasseterc20.clear_metadata() */\n swap1\n pop\n /* \"main.sol\":10459:10590 function clear_metadata() override external returns (bool) {... */\n swap1\n jump\t// out\n /* \"main.sol\":8567:8785 function allowance(... */\n tag_137:\n /* \"main.sol\":8696:8703 uint256 */\n 0x00\n /* \"main.sol\":8729:8744 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":8729:8754 localasseterc20.allowance */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0xdd62ed3e\n /* \"main.sol\":8755:8760 owner */\n dup5\n /* \"main.sol\":8762:8769 spender */\n dup5\n /* \"main.sol\":8729:8770 localasseterc20.allowance(owner, spender) */\n mload(0x40)\n dup4\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_251\n swap3\n swap2\n swap1\n tag_252\n jump\t// in\n tag_251:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n dup7\n gas\n staticcall\n iszero\n dup1\n iszero\n tag_254\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_254:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_255\n swap2\n swap1\n tag_178\n jump\t// in\n tag_255:\n /* \"main.sol\":8722:8770 return localasseterc20.allowance(owner, spender) */\n swap1\n pop\n /* \"main.sol\":8567:8785 function allowance(... */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"main.sol\":10236:10445 function set_metadata(string calldata name, string calldata symbol, uint8 decimals) override external returns (bool) {... */\n tag_143:\n /* \"main.sol\":10347:10351 bool */\n 0x00\n /* \"main.sol\":10378:10393 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":10378:10406 localasseterc20.set_metadata */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0xee5dc1e4\n /* \"main.sol\":10407:10411 name */\n dup8\n dup8\n /* \"main.sol\":10413:10419 symbol */\n dup8\n dup8\n /* \"main.sol\":10421:10429 decimals */\n dup8\n /* \"main.sol\":10378:10430 localasseterc20.set_metadata(name, symbol, decimals) */\n mload(0x40)\n dup7\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_257\n swap6\n swap5\n swap4\n swap3\n swap2\n swap1\n tag_258\n jump\t// in\n tag_257:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_260\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_260:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_261\n swap2\n swap1\n tag_173\n jump\t// in\n tag_261:\n /* \"main.sol\":10371:10430 return localasseterc20.set_metadata(name, symbol, decimals) */\n swap1\n pop\n /* \"main.sol\":10236:10445 function set_metadata(string calldata name, string calldata symbol, uint8 decimals) override external returns (bool) {... */\n swap6\n swap5\n pop\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"main.sol\":9864:10021 function transfer_ownership(address owner) override external returns (bool) {... */\n tag_148:\n /* \"main.sol\":9934:9938 bool */\n 0x00\n /* \"main.sol\":9965:9980 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":9965:9999 localasseterc20.transfer_ownership */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0xf0350c04\n /* \"main.sol\":10000:10005 owner */\n dup4\n /* \"main.sol\":9965:10006 localasseterc20.transfer_ownership(owner) */\n mload(0x40)\n dup3\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_263\n swap2\n swap1\n tag_38\n jump\t// in\n tag_263:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_265\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_265:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_266\n swap2\n swap1\n tag_173\n jump\t// in\n tag_266:\n /* \"main.sol\":9958:10006 return localasseterc20.transfer_ownership(owner) */\n swap1\n pop\n /* \"main.sol\":9864:10021 function transfer_ownership(address owner) override external returns (bool) {... */\n swap2\n swap1\n pop\n jump\t// out\n /* \"main.sol\":11099:11393 function approve_delegate(address spender, uint256 value) external returns (bool) {... */\n tag_153:\n /* \"main.sol\":11175:11179 bool */\n 0x00\n /* \"main.sol\":11196:11207 bool result */\n dup1\n /* \"main.sol\":11209:11226 bytes memory data */\n 0x00\n /* \"main.sol\":11230:11252 localasseterc20address */\n 0x01\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":11230:11265 localasseterc20address.delegatecall */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":11335:11342 spender */\n dup6\n /* \"main.sol\":11344:11349 value */\n dup6\n /* \"main.sol\":11283:11350 abi.encodeWithSignature(\"approve(address,uint256)\", spender, value) */\n add(0x24, mload(0x40))\n tag_268\n swap3\n swap2\n swap1\n tag_169\n jump\t// in\n tag_268:\n mload(0x40)\n 0x20\n dup2\n dup4\n sub\n sub\n dup2\n mstore\n swap1\n 0x40\n mstore\n and(not(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x095ea7b300000000000000000000000000000000000000000000000000000000)\n 0x20\n dup3\n add\n dup1\n mload\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n dup4\n dup2\n dup4\n and\n or\n dup4\n mstore\n pop\n pop\n pop\n pop\n /* \"main.sol\":11230:11351 localasseterc20address.delegatecall(... */\n mload(0x40)\n tag_269\n swap2\n swap1\n tag_216\n jump\t// in\n tag_269:\n 0x00\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n dup6\n gas\n delegatecall\n swap2\n pop\n pop\n returndatasize\n dup1\n 0x00\n dup2\n eq\n tag_272\n jumpi\n mload(0x40)\n swap2\n pop\n and(add(returndatasize, 0x3f), not(0x1f))\n dup3\n add\n 0x40\n mstore\n returndatasize\n dup3\n mstore\n returndatasize\n 0x00\n 0x20\n dup5\n add\n returndatacopy\n jump(tag_271)\n tag_272:\n 0x60\n swap2\n pop\n tag_271:\n pop\n /* \"main.sol\":11195:11351 (bool result, bytes memory data) = localasseterc20address.delegatecall(... */\n swap2\n pop\n swap2\n pop\n /* \"main.sol\":11372:11378 result */\n dup2\n /* \"main.sol\":11365:11378 return result */\n swap3\n pop\n pop\n pop\n /* \"main.sol\":11099:11393 function approve_delegate(address spender, uint256 value) external returns (bool) {... */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"main.sol\":10035:10222 function set_team(address issuer, address admin, address freezer) override external returns (bool) {... */\n tag_159:\n /* \"main.sol\":10128:10132 bool */\n 0x00\n /* \"main.sol\":10159:10174 localasseterc20 */\n dup1\n 0x00\n swap1\n sload\n swap1\n 0x0100\n exp\n swap1\n div\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"main.sol\":10159:10183 localasseterc20.set_team */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n 0xf8bf8e95\n /* \"main.sol\":10184:10190 issuer */\n dup6\n /* \"main.sol\":10192:10197 admin */\n dup6\n /* \"main.sol\":10199:10206 freezer */\n dup6\n /* \"main.sol\":10159:10207 localasseterc20.set_team(issuer, admin, freezer) */\n mload(0x40)\n dup5\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_274\n swap4\n swap3\n swap2\n swap1\n tag_275\n jump\t// in\n tag_274:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n 0x00\n dup8\n gas\n call\n iszero\n dup1\n iszero\n tag_277\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_277:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_278\n swap2\n swap1\n tag_173\n jump\t// in\n tag_278:\n /* \"main.sol\":10152:10207 return localasseterc20.set_team(issuer, admin, freezer) */\n swap1\n pop\n /* \"main.sol\":10035:10222 function set_team(address issuer, address admin, address freezer) override external returns (bool) {... */\n swap4\n swap3\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":7:133 */\n tag_279:\n /* \"#utility.yul\":44:51 */\n 0x00\n /* \"#utility.yul\":84:126 */\n 0xffffffffffffffffffffffffffffffffffffffff\n /* \"#utility.yul\":77:82 */\n dup3\n /* \"#utility.yul\":73:127 */\n and\n /* \"#utility.yul\":62:127 */\n swap1\n pop\n /* \"#utility.yul\":7:133 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":139:235 */\n tag_280:\n /* \"#utility.yul\":176:183 */\n 0x00\n /* \"#utility.yul\":205:229 */\n tag_330\n /* \"#utility.yul\":223:228 */\n dup3\n /* \"#utility.yul\":205:229 */\n tag_279\n jump\t// in\n tag_330:\n /* \"#utility.yul\":194:229 */\n swap1\n pop\n /* \"#utility.yul\":139:235 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":241:359 */\n tag_281:\n /* \"#utility.yul\":328:352 */\n tag_332\n /* \"#utility.yul\":346:351 */\n dup2\n /* \"#utility.yul\":328:352 */\n tag_280\n jump\t// in\n tag_332:\n /* \"#utility.yul\":323:326 */\n dup3\n /* \"#utility.yul\":316:353 */\n mstore\n /* \"#utility.yul\":241:359 */\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":365:587 */\n tag_38:\n /* \"#utility.yul\":458:462 */\n 0x00\n /* \"#utility.yul\":496:498 */\n 0x20\n /* \"#utility.yul\":485:494 */\n dup3\n /* \"#utility.yul\":481:499 */\n add\n /* \"#utility.yul\":473:499 */\n swap1\n pop\n /* \"#utility.yul\":509:580 */\n tag_334\n /* \"#utility.yul\":577:578 */\n 0x00\n /* \"#utility.yul\":566:575 */\n dup4\n /* \"#utility.yul\":562:579 */\n add\n /* \"#utility.yul\":553:559 */\n dup5\n /* \"#utility.yul\":509:580 */\n tag_281\n jump\t// in\n tag_334:\n /* \"#utility.yul\":365:587 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":593:692 */\n tag_282:\n /* \"#utility.yul\":645:651 */\n 0x00\n /* \"#utility.yul\":679:684 */\n dup2\n /* \"#utility.yul\":673:685 */\n mload\n /* \"#utility.yul\":663:685 */\n swap1\n pop\n /* \"#utility.yul\":593:692 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":698:867 */\n tag_283:\n /* \"#utility.yul\":782:793 */\n 0x00\n /* \"#utility.yul\":816:822 */\n dup3\n /* \"#utility.yul\":811:814 */\n dup3\n /* \"#utility.yul\":804:823 */\n mstore\n /* \"#utility.yul\":856:860 */\n 0x20\n /* \"#utility.yul\":851:854 */\n dup3\n /* \"#utility.yul\":847:861 */\n add\n /* \"#utility.yul\":832:861 */\n swap1\n pop\n /* \"#utility.yul\":698:867 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":873:1180 */\n tag_284:\n /* \"#utility.yul\":941:942 */\n 0x00\n /* \"#utility.yul\":951:1064 */\n tag_338:\n /* \"#utility.yul\":965:971 */\n dup4\n /* \"#utility.yul\":962:963 */\n dup2\n /* \"#utility.yul\":959:972 */\n lt\n /* \"#utility.yul\":951:1064 */\n iszero\n tag_340\n jumpi\n /* \"#utility.yul\":1050:1051 */\n dup1\n /* \"#utility.yul\":1045:1048 */\n dup3\n /* \"#utility.yul\":1041:1052 */\n add\n /* \"#utility.yul\":1035:1053 */\n mload\n /* \"#utility.yul\":1031:1032 */\n dup2\n /* \"#utility.yul\":1026:1029 */\n dup5\n /* \"#utility.yul\":1022:1033 */\n add\n /* \"#utility.yul\":1015:1054 */\n mstore\n /* \"#utility.yul\":987:989 */\n 0x20\n /* \"#utility.yul\":984:985 */\n dup2\n /* \"#utility.yul\":980:990 */\n add\n /* \"#utility.yul\":975:990 */\n swap1\n pop\n /* \"#utility.yul\":951:1064 */\n jump(tag_338)\n tag_340:\n /* \"#utility.yul\":1082:1088 */\n dup4\n /* \"#utility.yul\":1079:1080 */\n dup2\n /* \"#utility.yul\":1076:1089 */\n gt\n /* \"#utility.yul\":1073:1174 */\n iszero\n tag_341\n jumpi\n /* \"#utility.yul\":1162:1163 */\n 0x00\n /* \"#utility.yul\":1153:1159 */\n dup5\n /* \"#utility.yul\":1148:1151 */\n dup5\n /* \"#utility.yul\":1144:1160 */\n add\n /* \"#utility.yul\":1137:1164 */\n mstore\n /* \"#utility.yul\":1073:1174 */\n tag_341:\n /* \"#utility.yul\":922:1180 */\n pop\n /* \"#utility.yul\":873:1180 */\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":1186:1288 */\n tag_285:\n /* \"#utility.yul\":1227:1233 */\n 0x00\n /* \"#utility.yul\":1278:1280 */\n 0x1f\n /* \"#utility.yul\":1274:1281 */\n not\n /* \"#utility.yul\":1269:1271 */\n 0x1f\n /* \"#utility.yul\":1262:1267 */\n dup4\n /* \"#utility.yul\":1258:1272 */\n add\n /* \"#utility.yul\":1254:1282 */\n and\n /* \"#utility.yul\":1244:1282 */\n swap1\n pop\n /* \"#utility.yul\":1186:1288 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":1294:1658 */\n tag_286:\n /* \"#utility.yul\":1382:1385 */\n 0x00\n /* \"#utility.yul\":1410:1449 */\n tag_344\n /* \"#utility.yul\":1443:1448 */\n dup3\n /* \"#utility.yul\":1410:1449 */\n tag_282\n jump\t// in\n tag_344:\n /* \"#utility.yul\":1465:1536 */\n tag_345\n /* \"#utility.yul\":1529:1535 */\n dup2\n /* \"#utility.yul\":1524:1527 */\n dup6\n /* \"#utility.yul\":1465:1536 */\n tag_283\n jump\t// in\n tag_345:\n /* \"#utility.yul\":1458:1536 */\n swap4\n pop\n /* \"#utility.yul\":1545:1597 */\n tag_346\n /* \"#utility.yul\":1590:1596 */\n dup2\n /* \"#utility.yul\":1585:1588 */\n dup6\n /* \"#utility.yul\":1578:1582 */\n 0x20\n /* \"#utility.yul\":1571:1576 */\n dup7\n /* \"#utility.yul\":1567:1583 */\n add\n /* \"#utility.yul\":1545:1597 */\n tag_284\n jump\t// in\n tag_346:\n /* \"#utility.yul\":1622:1651 */\n tag_347\n /* \"#utility.yul\":1644:1650 */\n dup2\n /* \"#utility.yul\":1622:1651 */\n tag_285\n jump\t// in\n tag_347:\n /* \"#utility.yul\":1617:1620 */\n dup5\n /* \"#utility.yul\":1613:1652 */\n add\n /* \"#utility.yul\":1606:1652 */\n swap2\n pop\n /* \"#utility.yul\":1386:1658 */\n pop\n /* \"#utility.yul\":1294:1658 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":1664:1977 */\n tag_43:\n /* \"#utility.yul\":1777:1781 */\n 0x00\n /* \"#utility.yul\":1815:1817 */\n 0x20\n /* \"#utility.yul\":1804:1813 */\n dup3\n /* \"#utility.yul\":1800:1818 */\n add\n /* \"#utility.yul\":1792:1818 */\n swap1\n pop\n /* \"#utility.yul\":1864:1873 */\n dup2\n /* \"#utility.yul\":1858:1862 */\n dup2\n /* \"#utility.yul\":1854:1874 */\n sub\n /* \"#utility.yul\":1850:1851 */\n 0x00\n /* \"#utility.yul\":1839:1848 */\n dup4\n /* \"#utility.yul\":1835:1852 */\n add\n /* \"#utility.yul\":1828:1875 */\n mstore\n /* \"#utility.yul\":1892:1970 */\n tag_349\n /* \"#utility.yul\":1965:1969 */\n dup2\n /* \"#utility.yul\":1956:1962 */\n dup5\n /* \"#utility.yul\":1892:1970 */\n tag_286\n jump\t// in\n tag_349:\n /* \"#utility.yul\":1884:1970 */\n swap1\n pop\n /* \"#utility.yul\":1664:1977 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":1983:2058 */\n tag_287:\n /* \"#utility.yul\":2016:2022 */\n 0x00\n /* \"#utility.yul\":2049:2051 */\n 0x40\n /* \"#utility.yul\":2043:2052 */\n mload\n /* \"#utility.yul\":2033:2052 */\n swap1\n pop\n /* \"#utility.yul\":1983:2058 */\n swap1\n jump\t// out\n /* \"#utility.yul\":2064:2181 */\n tag_288:\n /* \"#utility.yul\":2173:2174 */\n 0x00\n /* \"#utility.yul\":2170:2171 */\n dup1\n /* \"#utility.yul\":2163:2175 */\n revert\n /* \"#utility.yul\":2187:2304 */\n tag_289:\n /* \"#utility.yul\":2296:2297 */\n 0x00\n /* \"#utility.yul\":2293:2294 */\n dup1\n /* \"#utility.yul\":2286:2298 */\n revert\n /* \"#utility.yul\":2310:2432 */\n tag_290:\n /* \"#utility.yul\":2383:2407 */\n tag_354\n /* \"#utility.yul\":2401:2406 */\n dup2\n /* \"#utility.yul\":2383:2407 */\n tag_280\n jump\t// in\n tag_354:\n /* \"#utility.yul\":2376:2381 */\n dup2\n /* \"#utility.yul\":2373:2408 */\n eq\n /* \"#utility.yul\":2363:2426 */\n tag_355\n jumpi\n /* \"#utility.yul\":2422:2423 */\n 0x00\n /* \"#utility.yul\":2419:2420 */\n dup1\n /* \"#utility.yul\":2412:2424 */\n revert\n /* \"#utility.yul\":2363:2426 */\n tag_355:\n /* \"#utility.yul\":2310:2432 */\n pop\n jump\t// out\n /* \"#utility.yul\":2438:2577 */\n tag_291:\n /* \"#utility.yul\":2484:2489 */\n 0x00\n /* \"#utility.yul\":2522:2528 */\n dup2\n /* \"#utility.yul\":2509:2529 */\n calldataload\n /* \"#utility.yul\":2500:2529 */\n swap1\n pop\n /* \"#utility.yul\":2538:2571 */\n tag_357\n /* \"#utility.yul\":2565:2570 */\n dup2\n /* \"#utility.yul\":2538:2571 */\n tag_290\n jump\t// in\n tag_357:\n /* \"#utility.yul\":2438:2577 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":2583:2660 */\n tag_292:\n /* \"#utility.yul\":2620:2627 */\n 0x00\n /* \"#utility.yul\":2649:2654 */\n dup2\n /* \"#utility.yul\":2638:2654 */\n swap1\n pop\n /* \"#utility.yul\":2583:2660 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":2666:2788 */\n tag_293:\n /* \"#utility.yul\":2739:2763 */\n tag_360\n /* \"#utility.yul\":2757:2762 */\n dup2\n /* \"#utility.yul\":2739:2763 */\n tag_292\n jump\t// in\n tag_360:\n /* \"#utility.yul\":2732:2737 */\n dup2\n /* \"#utility.yul\":2729:2764 */\n eq\n /* \"#utility.yul\":2719:2782 */\n tag_361\n jumpi\n /* \"#utility.yul\":2778:2779 */\n 0x00\n /* \"#utility.yul\":2775:2776 */\n dup1\n /* \"#utility.yul\":2768:2780 */\n revert\n /* \"#utility.yul\":2719:2782 */\n tag_361:\n /* \"#utility.yul\":2666:2788 */\n pop\n jump\t// out\n /* \"#utility.yul\":2794:2933 */\n tag_294:\n /* \"#utility.yul\":2840:2845 */\n 0x00\n /* \"#utility.yul\":2878:2884 */\n dup2\n /* \"#utility.yul\":2865:2885 */\n calldataload\n /* \"#utility.yul\":2856:2885 */\n swap1\n pop\n /* \"#utility.yul\":2894:2927 */\n tag_363\n /* \"#utility.yul\":2921:2926 */\n dup2\n /* \"#utility.yul\":2894:2927 */\n tag_293\n jump\t// in\n tag_363:\n /* \"#utility.yul\":2794:2933 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":2939:3413 */\n tag_47:\n /* \"#utility.yul\":3007:3013 */\n 0x00\n /* \"#utility.yul\":3015:3021 */\n dup1\n /* \"#utility.yul\":3064:3066 */\n 0x40\n /* \"#utility.yul\":3052:3061 */\n dup4\n /* \"#utility.yul\":3043:3050 */\n dup6\n /* \"#utility.yul\":3039:3062 */\n sub\n /* \"#utility.yul\":3035:3067 */\n slt\n /* \"#utility.yul\":3032:3151 */\n iszero\n tag_365\n jumpi\n /* \"#utility.yul\":3070:3149 */\n tag_366\n tag_288\n jump\t// in\n tag_366:\n /* \"#utility.yul\":3032:3151 */\n tag_365:\n /* \"#utility.yul\":3190:3191 */\n 0x00\n /* \"#utility.yul\":3215:3268 */\n tag_367\n /* \"#utility.yul\":3260:3267 */\n dup6\n /* \"#utility.yul\":3251:3257 */\n dup3\n /* \"#utility.yul\":3240:3249 */\n dup7\n /* \"#utility.yul\":3236:3258 */\n add\n /* \"#utility.yul\":3215:3268 */\n tag_291\n jump\t// in\n tag_367:\n /* \"#utility.yul\":3205:3268 */\n swap3\n pop\n /* \"#utility.yul\":3161:3278 */\n pop\n /* \"#utility.yul\":3317:3319 */\n 0x20\n /* \"#utility.yul\":3343:3396 */\n tag_368\n /* \"#utility.yul\":3388:3395 */\n dup6\n /* \"#utility.yul\":3379:3385 */\n dup3\n /* \"#utility.yul\":3368:3377 */\n dup7\n /* \"#utility.yul\":3364:3386 */\n add\n /* \"#utility.yul\":3343:3396 */\n tag_294\n jump\t// in\n tag_368:\n /* \"#utility.yul\":3333:3396 */\n swap2\n pop\n /* \"#utility.yul\":3288:3406 */\n pop\n /* \"#utility.yul\":2939:3413 */\n swap3\n pop\n swap3\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":3419:3509 */\n tag_295:\n /* \"#utility.yul\":3453:3460 */\n 0x00\n /* \"#utility.yul\":3496:3501 */\n dup2\n /* \"#utility.yul\":3489:3502 */\n iszero\n /* \"#utility.yul\":3482:3503 */\n iszero\n /* \"#utility.yul\":3471:3503 */\n swap1\n pop\n /* \"#utility.yul\":3419:3509 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":3515:3624 */\n tag_296:\n /* \"#utility.yul\":3596:3617 */\n tag_371\n /* \"#utility.yul\":3611:3616 */\n dup2\n /* \"#utility.yul\":3596:3617 */\n tag_295\n jump\t// in\n tag_371:\n /* \"#utility.yul\":3591:3594 */\n dup3\n /* \"#utility.yul\":3584:3618 */\n mstore\n /* \"#utility.yul\":3515:3624 */\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":3630:3840 */\n tag_50:\n /* \"#utility.yul\":3717:3721 */\n 0x00\n /* \"#utility.yul\":3755:3757 */\n 0x20\n /* \"#utility.yul\":3744:3753 */\n dup3\n /* \"#utility.yul\":3740:3758 */\n add\n /* \"#utility.yul\":3732:3758 */\n swap1\n pop\n /* \"#utility.yul\":3768:3833 */\n tag_373\n /* \"#utility.yul\":3830:3831 */\n 0x00\n /* \"#utility.yul\":3819:3828 */\n dup4\n /* \"#utility.yul\":3815:3832 */\n add\n /* \"#utility.yul\":3806:3812 */\n dup5\n /* \"#utility.yul\":3768:3833 */\n tag_296\n jump\t// in\n tag_373:\n /* \"#utility.yul\":3630:3840 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":3846:3964 */\n tag_297:\n /* \"#utility.yul\":3933:3957 */\n tag_375\n /* \"#utility.yul\":3951:3956 */\n dup2\n /* \"#utility.yul\":3933:3957 */\n tag_292\n jump\t// in\n tag_375:\n /* \"#utility.yul\":3928:3931 */\n dup3\n /* \"#utility.yul\":3921:3958 */\n mstore\n /* \"#utility.yul\":3846:3964 */\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":3970:4192 */\n tag_55:\n /* \"#utility.yul\":4063:4067 */\n 0x00\n /* \"#utility.yul\":4101:4103 */\n 0x20\n /* \"#utility.yul\":4090:4099 */\n dup3\n /* \"#utility.yul\":4086:4104 */\n add\n /* \"#utility.yul\":4078:4104 */\n swap1\n pop\n /* \"#utility.yul\":4114:4185 */\n tag_377\n /* \"#utility.yul\":4182:4183 */\n 0x00\n /* \"#utility.yul\":4171:4180 */\n dup4\n /* \"#utility.yul\":4167:4184 */\n add\n /* \"#utility.yul\":4158:4164 */\n dup5\n /* \"#utility.yul\":4114:4185 */\n tag_297\n jump\t// in\n tag_377:\n /* \"#utility.yul\":3970:4192 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":4198:4817 */\n tag_63:\n /* \"#utility.yul\":4275:4281 */\n 0x00\n /* \"#utility.yul\":4283:4289 */\n dup1\n /* \"#utility.yul\":4291:4297 */\n 0x00\n /* \"#utility.yul\":4340:4342 */\n 0x60\n /* \"#utility.yul\":4328:4337 */\n dup5\n /* \"#utility.yul\":4319:4326 */\n dup7\n /* \"#utility.yul\":4315:4338 */\n sub\n /* \"#utility.yul\":4311:4343 */\n slt\n /* \"#utility.yul\":4308:4427 */\n iszero\n tag_379\n jumpi\n /* \"#utility.yul\":4346:4425 */\n tag_380\n tag_288\n jump\t// in\n tag_380:\n /* \"#utility.yul\":4308:4427 */\n tag_379:\n /* \"#utility.yul\":4466:4467 */\n 0x00\n /* \"#utility.yul\":4491:4544 */\n tag_381\n /* \"#utility.yul\":4536:4543 */\n dup7\n /* \"#utility.yul\":4527:4533 */\n dup3\n /* \"#utility.yul\":4516:4525 */\n dup8\n /* \"#utility.yul\":4512:4534 */\n add\n /* \"#utility.yul\":4491:4544 */\n tag_291\n jump\t// in\n tag_381:\n /* \"#utility.yul\":4481:4544 */\n swap4\n pop\n /* \"#utility.yul\":4437:4554 */\n pop\n /* \"#utility.yul\":4593:4595 */\n 0x20\n /* \"#utility.yul\":4619:4672 */\n tag_382\n /* \"#utility.yul\":4664:4671 */\n dup7\n /* \"#utility.yul\":4655:4661 */\n dup3\n /* \"#utility.yul\":4644:4653 */\n dup8\n /* \"#utility.yul\":4640:4662 */\n add\n /* \"#utility.yul\":4619:4672 */\n tag_291\n jump\t// in\n tag_382:\n /* \"#utility.yul\":4609:4672 */\n swap3\n pop\n /* \"#utility.yul\":4564:4682 */\n pop\n /* \"#utility.yul\":4721:4723 */\n 0x40\n /* \"#utility.yul\":4747:4800 */\n tag_383\n /* \"#utility.yul\":4792:4799 */\n dup7\n /* \"#utility.yul\":4783:4789 */\n dup3\n /* \"#utility.yul\":4772:4781 */\n dup8\n /* \"#utility.yul\":4768:4790 */\n add\n /* \"#utility.yul\":4747:4800 */\n tag_294\n jump\t// in\n tag_383:\n /* \"#utility.yul\":4737:4800 */\n swap2\n pop\n /* \"#utility.yul\":4692:4810 */\n pop\n /* \"#utility.yul\":4198:4817 */\n swap3\n pop\n swap3\n pop\n swap3\n jump\t// out\n /* \"#utility.yul\":4823:4909 */\n tag_298:\n /* \"#utility.yul\":4858:4865 */\n 0x00\n /* \"#utility.yul\":4898:4902 */\n 0xff\n /* \"#utility.yul\":4891:4896 */\n dup3\n /* \"#utility.yul\":4887:4903 */\n and\n /* \"#utility.yul\":4876:4903 */\n swap1\n pop\n /* \"#utility.yul\":4823:4909 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":4915:5027 */\n tag_299:\n /* \"#utility.yul\":4998:5020 */\n tag_386\n /* \"#utility.yul\":5014:5019 */\n dup2\n /* \"#utility.yul\":4998:5020 */\n tag_298\n jump\t// in\n tag_386:\n /* \"#utility.yul\":4993:4996 */\n dup3\n /* \"#utility.yul\":4986:5021 */\n mstore\n /* \"#utility.yul\":4915:5027 */\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":5033:5247 */\n tag_70:\n /* \"#utility.yul\":5122:5126 */\n 0x00\n /* \"#utility.yul\":5160:5162 */\n 0x20\n /* \"#utility.yul\":5149:5158 */\n dup3\n /* \"#utility.yul\":5145:5163 */\n add\n /* \"#utility.yul\":5137:5163 */\n swap1\n pop\n /* \"#utility.yul\":5173:5240 */\n tag_388\n /* \"#utility.yul\":5237:5238 */\n 0x00\n /* \"#utility.yul\":5226:5235 */\n dup4\n /* \"#utility.yul\":5222:5239 */\n add\n /* \"#utility.yul\":5213:5219 */\n dup5\n /* \"#utility.yul\":5173:5240 */\n tag_299\n jump\t// in\n tag_388:\n /* \"#utility.yul\":5033:5247 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":5253:5582 */\n tag_79:\n /* \"#utility.yul\":5312:5318 */\n 0x00\n /* \"#utility.yul\":5361:5363 */\n 0x20\n /* \"#utility.yul\":5349:5358 */\n dup3\n /* \"#utility.yul\":5340:5347 */\n dup5\n /* \"#utility.yul\":5336:5359 */\n sub\n /* \"#utility.yul\":5332:5364 */\n slt\n /* \"#utility.yul\":5329:5448 */\n iszero\n tag_390\n jumpi\n /* \"#utility.yul\":5367:5446 */\n tag_391\n tag_288\n jump\t// in\n tag_391:\n /* \"#utility.yul\":5329:5448 */\n tag_390:\n /* \"#utility.yul\":5487:5488 */\n 0x00\n /* \"#utility.yul\":5512:5565 */\n tag_392\n /* \"#utility.yul\":5557:5564 */\n dup5\n /* \"#utility.yul\":5548:5554 */\n dup3\n /* \"#utility.yul\":5537:5546 */\n dup6\n /* \"#utility.yul\":5533:5555 */\n add\n /* \"#utility.yul\":5512:5565 */\n tag_291\n jump\t// in\n tag_392:\n /* \"#utility.yul\":5502:5565 */\n swap2\n pop\n /* \"#utility.yul\":5458:5575 */\n pop\n /* \"#utility.yul\":5253:5582 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":5588:5648 */\n tag_300:\n /* \"#utility.yul\":5616:5619 */\n 0x00\n /* \"#utility.yul\":5637:5642 */\n dup2\n /* \"#utility.yul\":5630:5642 */\n swap1\n pop\n /* \"#utility.yul\":5588:5648 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":5654:5796 */\n tag_301:\n /* \"#utility.yul\":5704:5713 */\n 0x00\n /* \"#utility.yul\":5737:5790 */\n tag_395\n /* \"#utility.yul\":5755:5789 */\n tag_396\n /* \"#utility.yul\":5764:5788 */\n tag_397\n /* \"#utility.yul\":5782:5787 */\n dup5\n /* \"#utility.yul\":5764:5788 */\n tag_279\n jump\t// in\n tag_397:\n /* \"#utility.yul\":5755:5789 */\n tag_300\n jump\t// in\n tag_396:\n /* \"#utility.yul\":5737:5790 */\n tag_279\n jump\t// in\n tag_395:\n /* \"#utility.yul\":5724:5790 */\n swap1\n pop\n /* \"#utility.yul\":5654:5796 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":5802:5928 */\n tag_302:\n /* \"#utility.yul\":5852:5861 */\n 0x00\n /* \"#utility.yul\":5885:5922 */\n tag_399\n /* \"#utility.yul\":5916:5921 */\n dup3\n /* \"#utility.yul\":5885:5922 */\n tag_301\n jump\t// in\n tag_399:\n /* \"#utility.yul\":5872:5922 */\n swap1\n pop\n /* \"#utility.yul\":5802:5928 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":5934:6091 */\n tag_303:\n /* \"#utility.yul\":6015:6024 */\n 0x00\n /* \"#utility.yul\":6048:6085 */\n tag_401\n /* \"#utility.yul\":6079:6084 */\n dup3\n /* \"#utility.yul\":6048:6085 */\n tag_302\n jump\t// in\n tag_401:\n /* \"#utility.yul\":6035:6085 */\n swap1\n pop\n /* \"#utility.yul\":5934:6091 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":6097:6290 */\n tag_304:\n /* \"#utility.yul\":6215:6283 */\n tag_403\n /* \"#utility.yul\":6277:6282 */\n dup2\n /* \"#utility.yul\":6215:6283 */\n tag_303\n jump\t// in\n tag_403:\n /* \"#utility.yul\":6210:6213 */\n dup3\n /* \"#utility.yul\":6203:6284 */\n mstore\n /* \"#utility.yul\":6097:6290 */\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":6296:6580 */\n tag_113:\n /* \"#utility.yul\":6420:6424 */\n 0x00\n /* \"#utility.yul\":6458:6460 */\n 0x20\n /* \"#utility.yul\":6447:6456 */\n dup3\n /* \"#utility.yul\":6443:6461 */\n add\n /* \"#utility.yul\":6435:6461 */\n swap1\n pop\n /* \"#utility.yul\":6471:6573 */\n tag_405\n /* \"#utility.yul\":6570:6571 */\n 0x00\n /* \"#utility.yul\":6559:6568 */\n dup4\n /* \"#utility.yul\":6555:6572 */\n add\n /* \"#utility.yul\":6546:6552 */\n dup5\n /* \"#utility.yul\":6471:6573 */\n tag_304\n jump\t// in\n tag_405:\n /* \"#utility.yul\":6296:6580 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":6586:7060 */\n tag_136:\n /* \"#utility.yul\":6654:6660 */\n 0x00\n /* \"#utility.yul\":6662:6668 */\n dup1\n /* \"#utility.yul\":6711:6713 */\n 0x40\n /* \"#utility.yul\":6699:6708 */\n dup4\n /* \"#utility.yul\":6690:6697 */\n dup6\n /* \"#utility.yul\":6686:6709 */\n sub\n /* \"#utility.yul\":6682:6714 */\n slt\n /* \"#utility.yul\":6679:6798 */\n iszero\n tag_407\n jumpi\n /* \"#utility.yul\":6717:6796 */\n tag_408\n tag_288\n jump\t// in\n tag_408:\n /* \"#utility.yul\":6679:6798 */\n tag_407:\n /* \"#utility.yul\":6837:6838 */\n 0x00\n /* \"#utility.yul\":6862:6915 */\n tag_409\n /* \"#utility.yul\":6907:6914 */\n dup6\n /* \"#utility.yul\":6898:6904 */\n dup3\n /* \"#utility.yul\":6887:6896 */\n dup7\n /* \"#utility.yul\":6883:6905 */\n add\n /* \"#utility.yul\":6862:6915 */\n tag_291\n jump\t// in\n tag_409:\n /* \"#utility.yul\":6852:6915 */\n swap3\n pop\n /* \"#utility.yul\":6808:6925 */\n pop\n /* \"#utility.yul\":6964:6966 */\n 0x20\n /* \"#utility.yul\":6990:7043 */\n tag_410\n /* \"#utility.yul\":7035:7042 */\n dup6\n /* \"#utility.yul\":7026:7032 */\n dup3\n /* \"#utility.yul\":7015:7024 */\n dup7\n /* \"#utility.yul\":7011:7033 */\n add\n /* \"#utility.yul\":6990:7043 */\n tag_291\n jump\t// in\n tag_410:\n /* \"#utility.yul\":6980:7043 */\n swap2\n pop\n /* \"#utility.yul\":6935:7053 */\n pop\n /* \"#utility.yul\":6586:7060 */\n swap3\n pop\n swap3\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":7066:7183 */\n tag_305:\n /* \"#utility.yul\":7175:7176 */\n 0x00\n /* \"#utility.yul\":7172:7173 */\n dup1\n /* \"#utility.yul\":7165:7177 */\n revert\n /* \"#utility.yul\":7189:7306 */\n tag_306:\n /* \"#utility.yul\":7298:7299 */\n 0x00\n /* \"#utility.yul\":7295:7296 */\n dup1\n /* \"#utility.yul\":7288:7300 */\n revert\n /* \"#utility.yul\":7312:7429 */\n tag_307:\n /* \"#utility.yul\":7421:7422 */\n 0x00\n /* \"#utility.yul\":7418:7419 */\n dup1\n /* \"#utility.yul\":7411:7423 */\n revert\n /* \"#utility.yul\":7449:8002 */\n tag_308:\n /* \"#utility.yul\":7507:7515 */\n 0x00\n /* \"#utility.yul\":7517:7523 */\n dup1\n /* \"#utility.yul\":7567:7570 */\n dup4\n /* \"#utility.yul\":7560:7564 */\n 0x1f\n /* \"#utility.yul\":7552:7558 */\n dup5\n /* \"#utility.yul\":7548:7565 */\n add\n /* \"#utility.yul\":7544:7571 */\n slt\n /* \"#utility.yul\":7534:7656 */\n tag_415\n jumpi\n /* \"#utility.yul\":7575:7654 */\n tag_416\n tag_305\n jump\t// in\n tag_416:\n /* \"#utility.yul\":7534:7656 */\n tag_415:\n /* \"#utility.yul\":7688:7694 */\n dup3\n /* \"#utility.yul\":7675:7695 */\n calldataload\n /* \"#utility.yul\":7665:7695 */\n swap1\n pop\n /* \"#utility.yul\":7718:7736 */\n 0xffffffffffffffff\n /* \"#utility.yul\":7710:7716 */\n dup2\n /* \"#utility.yul\":7707:7737 */\n gt\n /* \"#utility.yul\":7704:7821 */\n iszero\n tag_417\n jumpi\n /* \"#utility.yul\":7740:7819 */\n tag_418\n tag_306\n jump\t// in\n tag_418:\n /* \"#utility.yul\":7704:7821 */\n tag_417:\n /* \"#utility.yul\":7854:7858 */\n 0x20\n /* \"#utility.yul\":7846:7852 */\n dup4\n /* \"#utility.yul\":7842:7859 */\n add\n /* \"#utility.yul\":7830:7859 */\n swap2\n pop\n /* \"#utility.yul\":7908:7911 */\n dup4\n /* \"#utility.yul\":7900:7904 */\n 0x01\n /* \"#utility.yul\":7892:7898 */\n dup3\n /* \"#utility.yul\":7888:7905 */\n mul\n /* \"#utility.yul\":7878:7886 */\n dup4\n /* \"#utility.yul\":7874:7906 */\n add\n /* \"#utility.yul\":7871:7912 */\n gt\n /* \"#utility.yul\":7868:7996 */\n iszero\n tag_419\n jumpi\n /* \"#utility.yul\":7915:7994 */\n tag_420\n tag_307\n jump\t// in\n tag_420:\n /* \"#utility.yul\":7868:7996 */\n tag_419:\n /* \"#utility.yul\":7449:8002 */\n swap3\n pop\n swap3\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":8008:8126 */\n tag_309:\n /* \"#utility.yul\":8079:8101 */\n tag_422\n /* \"#utility.yul\":8095:8100 */\n dup2\n /* \"#utility.yul\":8079:8101 */\n tag_298\n jump\t// in\n tag_422:\n /* \"#utility.yul\":8072:8077 */\n dup2\n /* \"#utility.yul\":8069:8102 */\n eq\n /* \"#utility.yul\":8059:8120 */\n tag_423\n jumpi\n /* \"#utility.yul\":8116:8117 */\n 0x00\n /* \"#utility.yul\":8113:8114 */\n dup1\n /* \"#utility.yul\":8106:8118 */\n revert\n /* \"#utility.yul\":8059:8120 */\n tag_423:\n /* \"#utility.yul\":8008:8126 */\n pop\n jump\t// out\n /* \"#utility.yul\":8132:8267 */\n tag_310:\n /* \"#utility.yul\":8176:8181 */\n 0x00\n /* \"#utility.yul\":8214:8220 */\n dup2\n /* \"#utility.yul\":8201:8221 */\n calldataload\n /* \"#utility.yul\":8192:8221 */\n swap1\n pop\n /* \"#utility.yul\":8230:8261 */\n tag_425\n /* \"#utility.yul\":8255:8260 */\n dup2\n /* \"#utility.yul\":8230:8261 */\n tag_309\n jump\t// in\n tag_425:\n /* \"#utility.yul\":8132:8267 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":8273:9288 */\n tag_142:\n /* \"#utility.yul\":8372:8378 */\n 0x00\n /* \"#utility.yul\":8380:8386 */\n dup1\n /* \"#utility.yul\":8388:8394 */\n 0x00\n /* \"#utility.yul\":8396:8402 */\n dup1\n /* \"#utility.yul\":8404:8410 */\n 0x00\n /* \"#utility.yul\":8453:8455 */\n 0x60\n /* \"#utility.yul\":8441:8450 */\n dup7\n /* \"#utility.yul\":8432:8439 */\n dup9\n /* \"#utility.yul\":8428:8451 */\n sub\n /* \"#utility.yul\":8424:8456 */\n slt\n /* \"#utility.yul\":8421:8540 */\n iszero\n tag_427\n jumpi\n /* \"#utility.yul\":8459:8538 */\n tag_428\n tag_288\n jump\t// in\n tag_428:\n /* \"#utility.yul\":8421:8540 */\n tag_427:\n /* \"#utility.yul\":8607:8608 */\n 0x00\n /* \"#utility.yul\":8596:8605 */\n dup7\n /* \"#utility.yul\":8592:8609 */\n add\n /* \"#utility.yul\":8579:8610 */\n calldataload\n /* \"#utility.yul\":8637:8655 */\n 0xffffffffffffffff\n /* \"#utility.yul\":8629:8635 */\n dup2\n /* \"#utility.yul\":8626:8656 */\n gt\n /* \"#utility.yul\":8623:8740 */\n iszero\n tag_429\n jumpi\n /* \"#utility.yul\":8659:8738 */\n tag_430\n tag_289\n jump\t// in\n tag_430:\n /* \"#utility.yul\":8623:8740 */\n tag_429:\n /* \"#utility.yul\":8772:8837 */\n tag_431\n /* \"#utility.yul\":8829:8836 */\n dup9\n /* \"#utility.yul\":8820:8826 */\n dup3\n /* \"#utility.yul\":8809:8818 */\n dup10\n /* \"#utility.yul\":8805:8827 */\n add\n /* \"#utility.yul\":8772:8837 */\n tag_308\n jump\t// in\n tag_431:\n /* \"#utility.yul\":8754:8837 */\n swap6\n pop\n swap6\n pop\n /* \"#utility.yul\":8550:8847 */\n pop\n /* \"#utility.yul\":8914:8916 */\n 0x20\n /* \"#utility.yul\":8903:8912 */\n dup7\n /* \"#utility.yul\":8899:8917 */\n add\n /* \"#utility.yul\":8886:8918 */\n calldataload\n /* \"#utility.yul\":8945:8963 */\n 0xffffffffffffffff\n /* \"#utility.yul\":8937:8943 */\n dup2\n /* \"#utility.yul\":8934:8964 */\n gt\n /* \"#utility.yul\":8931:9048 */\n iszero\n tag_432\n jumpi\n /* \"#utility.yul\":8967:9046 */\n tag_433\n tag_289\n jump\t// in\n tag_433:\n /* \"#utility.yul\":8931:9048 */\n tag_432:\n /* \"#utility.yul\":9080:9145 */\n tag_434\n /* \"#utility.yul\":9137:9144 */\n dup9\n /* \"#utility.yul\":9128:9134 */\n dup3\n /* \"#utility.yul\":9117:9126 */\n dup10\n /* \"#utility.yul\":9113:9135 */\n add\n /* \"#utility.yul\":9080:9145 */\n tag_308\n jump\t// in\n tag_434:\n /* \"#utility.yul\":9062:9145 */\n swap4\n pop\n swap4\n pop\n /* \"#utility.yul\":8857:9155 */\n pop\n /* \"#utility.yul\":9194:9196 */\n 0x40\n /* \"#utility.yul\":9220:9271 */\n tag_435\n /* \"#utility.yul\":9263:9270 */\n dup9\n /* \"#utility.yul\":9254:9260 */\n dup3\n /* \"#utility.yul\":9243:9252 */\n dup10\n /* \"#utility.yul\":9239:9261 */\n add\n /* \"#utility.yul\":9220:9271 */\n tag_310\n jump\t// in\n tag_435:\n /* \"#utility.yul\":9210:9271 */\n swap2\n pop\n /* \"#utility.yul\":9165:9281 */\n pop\n /* \"#utility.yul\":8273:9288 */\n swap3\n swap6\n pop\n swap3\n swap6\n swap1\n swap4\n pop\n jump\t// out\n /* \"#utility.yul\":9294:9913 */\n tag_158:\n /* \"#utility.yul\":9371:9377 */\n 0x00\n /* \"#utility.yul\":9379:9385 */\n dup1\n /* \"#utility.yul\":9387:9393 */\n 0x00\n /* \"#utility.yul\":9436:9438 */\n 0x60\n /* \"#utility.yul\":9424:9433 */\n dup5\n /* \"#utility.yul\":9415:9422 */\n dup7\n /* \"#utility.yul\":9411:9434 */\n sub\n /* \"#utility.yul\":9407:9439 */\n slt\n /* \"#utility.yul\":9404:9523 */\n iszero\n tag_437\n jumpi\n /* \"#utility.yul\":9442:9521 */\n tag_438\n tag_288\n jump\t// in\n tag_438:\n /* \"#utility.yul\":9404:9523 */\n tag_437:\n /* \"#utility.yul\":9562:9563 */\n 0x00\n /* \"#utility.yul\":9587:9640 */\n tag_439\n /* \"#utility.yul\":9632:9639 */\n dup7\n /* \"#utility.yul\":9623:9629 */\n dup3\n /* \"#utility.yul\":9612:9621 */\n dup8\n /* \"#utility.yul\":9608:9630 */\n add\n /* \"#utility.yul\":9587:9640 */\n tag_291\n jump\t// in\n tag_439:\n /* \"#utility.yul\":9577:9640 */\n swap4\n pop\n /* \"#utility.yul\":9533:9650 */\n pop\n /* \"#utility.yul\":9689:9691 */\n 0x20\n /* \"#utility.yul\":9715:9768 */\n tag_440\n /* \"#utility.yul\":9760:9767 */\n dup7\n /* \"#utility.yul\":9751:9757 */\n dup3\n /* \"#utility.yul\":9740:9749 */\n dup8\n /* \"#utility.yul\":9736:9758 */\n add\n /* \"#utility.yul\":9715:9768 */\n tag_291\n jump\t// in\n tag_440:\n /* \"#utility.yul\":9705:9768 */\n swap3\n pop\n /* \"#utility.yul\":9660:9778 */\n pop\n /* \"#utility.yul\":9817:9819 */\n 0x40\n /* \"#utility.yul\":9843:9896 */\n tag_441\n /* \"#utility.yul\":9888:9895 */\n dup7\n /* \"#utility.yul\":9879:9885 */\n dup3\n /* \"#utility.yul\":9868:9877 */\n dup8\n /* \"#utility.yul\":9864:9886 */\n add\n /* \"#utility.yul\":9843:9896 */\n tag_291\n jump\t// in\n tag_441:\n /* \"#utility.yul\":9833:9896 */\n swap2\n pop\n /* \"#utility.yul\":9788:9906 */\n pop\n /* \"#utility.yul\":9294:9913 */\n swap3\n pop\n swap3\n pop\n swap3\n jump\t// out\n /* \"#utility.yul\":9919:10036 */\n tag_311:\n /* \"#utility.yul\":10028:10029 */\n 0x00\n /* \"#utility.yul\":10025:10026 */\n dup1\n /* \"#utility.yul\":10018:10030 */\n revert\n /* \"#utility.yul\":10042:10222 */\n tag_312:\n /* \"#utility.yul\":10090:10167 */\n 0x4e487b7100000000000000000000000000000000000000000000000000000000\n /* \"#utility.yul\":10087:10088 */\n 0x00\n /* \"#utility.yul\":10080:10168 */\n mstore\n /* \"#utility.yul\":10187:10191 */\n 0x41\n /* \"#utility.yul\":10184:10185 */\n 0x04\n /* \"#utility.yul\":10177:10192 */\n mstore\n /* \"#utility.yul\":10211:10215 */\n 0x24\n /* \"#utility.yul\":10208:10209 */\n 0x00\n /* \"#utility.yul\":10201:10216 */\n revert\n /* \"#utility.yul\":10228:10509 */\n tag_313:\n /* \"#utility.yul\":10311:10338 */\n tag_445\n /* \"#utility.yul\":10333:10337 */\n dup3\n /* \"#utility.yul\":10311:10338 */\n tag_285\n jump\t// in\n tag_445:\n /* \"#utility.yul\":10303:10309 */\n dup2\n /* \"#utility.yul\":10299:10339 */\n add\n /* \"#utility.yul\":10441:10447 */\n dup2\n /* \"#utility.yul\":10429:10439 */\n dup2\n /* \"#utility.yul\":10426:10448 */\n lt\n /* \"#utility.yul\":10405:10423 */\n 0xffffffffffffffff\n /* \"#utility.yul\":10393:10403 */\n dup3\n /* \"#utility.yul\":10390:10424 */\n gt\n /* \"#utility.yul\":10387:10449 */\n or\n /* \"#utility.yul\":10384:10472 */\n iszero\n tag_446\n jumpi\n /* \"#utility.yul\":10452:10470 */\n tag_447\n tag_312\n jump\t// in\n tag_447:\n /* \"#utility.yul\":10384:10472 */\n tag_446:\n /* \"#utility.yul\":10492:10502 */\n dup1\n /* \"#utility.yul\":10488:10490 */\n 0x40\n /* \"#utility.yul\":10481:10503 */\n mstore\n /* \"#utility.yul\":10271:10509 */\n pop\n /* \"#utility.yul\":10228:10509 */\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":10515:10644 */\n tag_314:\n /* \"#utility.yul\":10549:10555 */\n 0x00\n /* \"#utility.yul\":10576:10596 */\n tag_449\n tag_287\n jump\t// in\n tag_449:\n /* \"#utility.yul\":10566:10596 */\n swap1\n pop\n /* \"#utility.yul\":10605:10638 */\n tag_450\n /* \"#utility.yul\":10633:10637 */\n dup3\n /* \"#utility.yul\":10625:10631 */\n dup3\n /* \"#utility.yul\":10605:10638 */\n tag_313\n jump\t// in\n tag_450:\n /* \"#utility.yul\":10515:10644 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":10650:10958 */\n tag_315:\n /* \"#utility.yul\":10712:10716 */\n 0x00\n /* \"#utility.yul\":10802:10820 */\n 0xffffffffffffffff\n /* \"#utility.yul\":10794:10800 */\n dup3\n /* \"#utility.yul\":10791:10821 */\n gt\n /* \"#utility.yul\":10788:10844 */\n iszero\n tag_452\n jumpi\n /* \"#utility.yul\":10824:10842 */\n tag_453\n tag_312\n jump\t// in\n tag_453:\n /* \"#utility.yul\":10788:10844 */\n tag_452:\n /* \"#utility.yul\":10862:10891 */\n tag_454\n /* \"#utility.yul\":10884:10890 */\n dup3\n /* \"#utility.yul\":10862:10891 */\n tag_285\n jump\t// in\n tag_454:\n /* \"#utility.yul\":10854:10891 */\n swap1\n pop\n /* \"#utility.yul\":10946:10950 */\n 0x20\n /* \"#utility.yul\":10940:10944 */\n dup2\n /* \"#utility.yul\":10936:10951 */\n add\n /* \"#utility.yul\":10928:10951 */\n swap1\n pop\n /* \"#utility.yul\":10650:10958 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":10964:11385 */\n tag_316:\n /* \"#utility.yul\":11053:11058 */\n 0x00\n /* \"#utility.yul\":11078:11144 */\n tag_456\n /* \"#utility.yul\":11094:11143 */\n tag_457\n /* \"#utility.yul\":11136:11142 */\n dup5\n /* \"#utility.yul\":11094:11143 */\n tag_315\n jump\t// in\n tag_457:\n /* \"#utility.yul\":11078:11144 */\n tag_314\n jump\t// in\n tag_456:\n /* \"#utility.yul\":11069:11144 */\n swap1\n pop\n /* \"#utility.yul\":11167:11173 */\n dup3\n /* \"#utility.yul\":11160:11165 */\n dup2\n /* \"#utility.yul\":11153:11174 */\n mstore\n /* \"#utility.yul\":11205:11209 */\n 0x20\n /* \"#utility.yul\":11198:11203 */\n dup2\n /* \"#utility.yul\":11194:11210 */\n add\n /* \"#utility.yul\":11243:11246 */\n dup5\n /* \"#utility.yul\":11234:11240 */\n dup5\n /* \"#utility.yul\":11229:11232 */\n dup5\n /* \"#utility.yul\":11225:11241 */\n add\n /* \"#utility.yul\":11222:11247 */\n gt\n /* \"#utility.yul\":11219:11331 */\n iszero\n tag_458\n jumpi\n /* \"#utility.yul\":11250:11329 */\n tag_459\n tag_311\n jump\t// in\n tag_459:\n /* \"#utility.yul\":11219:11331 */\n tag_458:\n /* \"#utility.yul\":11340:11379 */\n tag_460\n /* \"#utility.yul\":11372:11378 */\n dup5\n /* \"#utility.yul\":11367:11370 */\n dup3\n /* \"#utility.yul\":11362:11365 */\n dup6\n /* \"#utility.yul\":11340:11379 */\n tag_284\n jump\t// in\n tag_460:\n /* \"#utility.yul\":11059:11385 */\n pop\n /* \"#utility.yul\":10964:11385 */\n swap4\n swap3\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":11405:11760 */\n tag_317:\n /* \"#utility.yul\":11472:11477 */\n 0x00\n /* \"#utility.yul\":11521:11524 */\n dup3\n /* \"#utility.yul\":11514:11518 */\n 0x1f\n /* \"#utility.yul\":11506:11512 */\n dup4\n /* \"#utility.yul\":11502:11519 */\n add\n /* \"#utility.yul\":11498:11525 */\n slt\n /* \"#utility.yul\":11488:11610 */\n tag_462\n jumpi\n /* \"#utility.yul\":11529:11608 */\n tag_463\n tag_305\n jump\t// in\n tag_463:\n /* \"#utility.yul\":11488:11610 */\n tag_462:\n /* \"#utility.yul\":11639:11645 */\n dup2\n /* \"#utility.yul\":11633:11646 */\n mload\n /* \"#utility.yul\":11664:11754 */\n tag_464\n /* \"#utility.yul\":11750:11753 */\n dup5\n /* \"#utility.yul\":11742:11748 */\n dup3\n /* \"#utility.yul\":11735:11739 */\n 0x20\n /* \"#utility.yul\":11727:11733 */\n dup7\n /* \"#utility.yul\":11723:11740 */\n add\n /* \"#utility.yul\":11664:11754 */\n tag_316\n jump\t// in\n tag_464:\n /* \"#utility.yul\":11655:11754 */\n swap2\n pop\n /* \"#utility.yul\":11478:11760 */\n pop\n /* \"#utility.yul\":11405:11760 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":11766:12290 */\n tag_166:\n /* \"#utility.yul\":11846:11852 */\n 0x00\n /* \"#utility.yul\":11895:11897 */\n 0x20\n /* \"#utility.yul\":11883:11892 */\n dup3\n /* \"#utility.yul\":11874:11881 */\n dup5\n /* \"#utility.yul\":11870:11893 */\n sub\n /* \"#utility.yul\":11866:11898 */\n slt\n /* \"#utility.yul\":11863:11982 */\n iszero\n tag_466\n jumpi\n /* \"#utility.yul\":11901:11980 */\n tag_467\n tag_288\n jump\t// in\n tag_467:\n /* \"#utility.yul\":11863:11982 */\n tag_466:\n /* \"#utility.yul\":12042:12043 */\n 0x00\n /* \"#utility.yul\":12031:12040 */\n dup3\n /* \"#utility.yul\":12027:12044 */\n add\n /* \"#utility.yul\":12021:12045 */\n mload\n /* \"#utility.yul\":12072:12090 */\n 0xffffffffffffffff\n /* \"#utility.yul\":12064:12070 */\n dup2\n /* \"#utility.yul\":12061:12091 */\n gt\n /* \"#utility.yul\":12058:12175 */\n iszero\n tag_468\n jumpi\n /* \"#utility.yul\":12094:12173 */\n tag_469\n tag_289\n jump\t// in\n tag_469:\n /* \"#utility.yul\":12058:12175 */\n tag_468:\n /* \"#utility.yul\":12199:12273 */\n tag_470\n /* \"#utility.yul\":12265:12272 */\n dup5\n /* \"#utility.yul\":12256:12262 */\n dup3\n /* \"#utility.yul\":12245:12254 */\n dup6\n /* \"#utility.yul\":12241:12263 */\n add\n /* \"#utility.yul\":12199:12273 */\n tag_317\n jump\t// in\n tag_470:\n /* \"#utility.yul\":12189:12273 */\n swap2\n pop\n /* \"#utility.yul\":11992:12283 */\n pop\n /* \"#utility.yul\":11766:12290 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":12296:12628 */\n tag_169:\n /* \"#utility.yul\":12417:12421 */\n 0x00\n /* \"#utility.yul\":12455:12457 */\n 0x40\n /* \"#utility.yul\":12444:12453 */\n dup3\n /* \"#utility.yul\":12440:12458 */\n add\n /* \"#utility.yul\":12432:12458 */\n swap1\n pop\n /* \"#utility.yul\":12468:12539 */\n tag_472\n /* \"#utility.yul\":12536:12537 */\n 0x00\n /* \"#utility.yul\":12525:12534 */\n dup4\n /* \"#utility.yul\":12521:12538 */\n add\n /* \"#utility.yul\":12512:12518 */\n dup6\n /* \"#utility.yul\":12468:12539 */\n tag_281\n jump\t// in\n tag_472:\n /* \"#utility.yul\":12549:12621 */\n tag_473\n /* \"#utility.yul\":12617:12619 */\n 0x20\n /* \"#utility.yul\":12606:12615 */\n dup4\n /* \"#utility.yul\":12602:12620 */\n add\n /* \"#utility.yul\":12593:12599 */\n dup5\n /* \"#utility.yul\":12549:12621 */\n tag_297\n jump\t// in\n tag_473:\n /* \"#utility.yul\":12296:12628 */\n swap4\n swap3\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":12634:12750 */\n tag_318:\n /* \"#utility.yul\":12704:12725 */\n tag_475\n /* \"#utility.yul\":12719:12724 */\n dup2\n /* \"#utility.yul\":12704:12725 */\n tag_295\n jump\t// in\n tag_475:\n /* \"#utility.yul\":12697:12702 */\n dup2\n /* \"#utility.yul\":12694:12726 */\n eq\n /* \"#utility.yul\":12684:12744 */\n tag_476\n jumpi\n /* \"#utility.yul\":12740:12741 */\n 0x00\n /* \"#utility.yul\":12737:12738 */\n dup1\n /* \"#utility.yul\":12730:12742 */\n revert\n /* \"#utility.yul\":12684:12744 */\n tag_476:\n /* \"#utility.yul\":12634:12750 */\n pop\n jump\t// out\n /* \"#utility.yul\":12756:12893 */\n tag_319:\n /* \"#utility.yul\":12810:12815 */\n 0x00\n /* \"#utility.yul\":12841:12847 */\n dup2\n /* \"#utility.yul\":12835:12848 */\n mload\n /* \"#utility.yul\":12826:12848 */\n swap1\n pop\n /* \"#utility.yul\":12857:12887 */\n tag_478\n /* \"#utility.yul\":12881:12886 */\n dup2\n /* \"#utility.yul\":12857:12887 */\n tag_318\n jump\t// in\n tag_478:\n /* \"#utility.yul\":12756:12893 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":12899:13244 */\n tag_173:\n /* \"#utility.yul\":12966:12972 */\n 0x00\n /* \"#utility.yul\":13015:13017 */\n 0x20\n /* \"#utility.yul\":13003:13012 */\n dup3\n /* \"#utility.yul\":12994:13001 */\n dup5\n /* \"#utility.yul\":12990:13013 */\n sub\n /* \"#utility.yul\":12986:13018 */\n slt\n /* \"#utility.yul\":12983:13102 */\n iszero\n tag_480\n jumpi\n /* \"#utility.yul\":13021:13100 */\n tag_481\n tag_288\n jump\t// in\n tag_481:\n /* \"#utility.yul\":12983:13102 */\n tag_480:\n /* \"#utility.yul\":13141:13142 */\n 0x00\n /* \"#utility.yul\":13166:13227 */\n tag_482\n /* \"#utility.yul\":13219:13226 */\n dup5\n /* \"#utility.yul\":13210:13216 */\n dup3\n /* \"#utility.yul\":13199:13208 */\n dup6\n /* \"#utility.yul\":13195:13217 */\n add\n /* \"#utility.yul\":13166:13227 */\n tag_319\n jump\t// in\n tag_482:\n /* \"#utility.yul\":13156:13227 */\n swap2\n pop\n /* \"#utility.yul\":13112:13237 */\n pop\n /* \"#utility.yul\":12899:13244 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":13250:13393 */\n tag_320:\n /* \"#utility.yul\":13307:13312 */\n 0x00\n /* \"#utility.yul\":13338:13344 */\n dup2\n /* \"#utility.yul\":13332:13345 */\n mload\n /* \"#utility.yul\":13323:13345 */\n swap1\n pop\n /* \"#utility.yul\":13354:13387 */\n tag_484\n /* \"#utility.yul\":13381:13386 */\n dup2\n /* \"#utility.yul\":13354:13387 */\n tag_293\n jump\t// in\n tag_484:\n /* \"#utility.yul\":13250:13393 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":13399:13750 */\n tag_178:\n /* \"#utility.yul\":13469:13475 */\n 0x00\n /* \"#utility.yul\":13518:13520 */\n 0x20\n /* \"#utility.yul\":13506:13515 */\n dup3\n /* \"#utility.yul\":13497:13504 */\n dup5\n /* \"#utility.yul\":13493:13516 */\n sub\n /* \"#utility.yul\":13489:13521 */\n slt\n /* \"#utility.yul\":13486:13605 */\n iszero\n tag_486\n jumpi\n /* \"#utility.yul\":13524:13603 */\n tag_487\n tag_288\n jump\t// in\n tag_487:\n /* \"#utility.yul\":13486:13605 */\n tag_486:\n /* \"#utility.yul\":13644:13645 */\n 0x00\n /* \"#utility.yul\":13669:13733 */\n tag_488\n /* \"#utility.yul\":13725:13732 */\n dup5\n /* \"#utility.yul\":13716:13722 */\n dup3\n /* \"#utility.yul\":13705:13714 */\n dup6\n /* \"#utility.yul\":13701:13723 */\n add\n /* \"#utility.yul\":13669:13733 */\n tag_320\n jump\t// in\n tag_488:\n /* \"#utility.yul\":13659:13733 */\n swap2\n pop\n /* \"#utility.yul\":13615:13743 */\n pop\n /* \"#utility.yul\":13399:13750 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":13756:14198 */\n tag_185:\n /* \"#utility.yul\":13905:13909 */\n 0x00\n /* \"#utility.yul\":13943:13945 */\n 0x60\n /* \"#utility.yul\":13932:13941 */\n dup3\n /* \"#utility.yul\":13928:13946 */\n add\n /* \"#utility.yul\":13920:13946 */\n swap1\n pop\n /* \"#utility.yul\":13956:14027 */\n tag_490\n /* \"#utility.yul\":14024:14025 */\n 0x00\n /* \"#utility.yul\":14013:14022 */\n dup4\n /* \"#utility.yul\":14009:14026 */\n add\n /* \"#utility.yul\":14000:14006 */\n dup7\n /* \"#utility.yul\":13956:14027 */\n tag_281\n jump\t// in\n tag_490:\n /* \"#utility.yul\":14037:14109 */\n tag_491\n /* \"#utility.yul\":14105:14107 */\n 0x20\n /* \"#utility.yul\":14094:14103 */\n dup4\n /* \"#utility.yul\":14090:14108 */\n add\n /* \"#utility.yul\":14081:14087 */\n dup6\n /* \"#utility.yul\":14037:14109 */\n tag_281\n jump\t// in\n tag_491:\n /* \"#utility.yul\":14119:14191 */\n tag_492\n /* \"#utility.yul\":14187:14189 */\n 0x40\n /* \"#utility.yul\":14176:14185 */\n dup4\n /* \"#utility.yul\":14172:14190 */\n add\n /* \"#utility.yul\":14163:14169 */\n dup5\n /* \"#utility.yul\":14119:14191 */\n tag_297\n jump\t// in\n tag_492:\n /* \"#utility.yul\":13756:14198 */\n swap5\n swap4\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":14204:14343 */\n tag_321:\n /* \"#utility.yul\":14259:14264 */\n 0x00\n /* \"#utility.yul\":14290:14296 */\n dup2\n /* \"#utility.yul\":14284:14297 */\n mload\n /* \"#utility.yul\":14275:14297 */\n swap1\n pop\n /* \"#utility.yul\":14306:14337 */\n tag_494\n /* \"#utility.yul\":14331:14336 */\n dup2\n /* \"#utility.yul\":14306:14337 */\n tag_309\n jump\t// in\n tag_494:\n /* \"#utility.yul\":14204:14343 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":14349:14696 */\n tag_193:\n /* \"#utility.yul\":14417:14423 */\n 0x00\n /* \"#utility.yul\":14466:14468 */\n 0x20\n /* \"#utility.yul\":14454:14463 */\n dup3\n /* \"#utility.yul\":14445:14452 */\n dup5\n /* \"#utility.yul\":14441:14464 */\n sub\n /* \"#utility.yul\":14437:14469 */\n slt\n /* \"#utility.yul\":14434:14553 */\n iszero\n tag_496\n jumpi\n /* \"#utility.yul\":14472:14551 */\n tag_497\n tag_288\n jump\t// in\n tag_497:\n /* \"#utility.yul\":14434:14553 */\n tag_496:\n /* \"#utility.yul\":14592:14593 */\n 0x00\n /* \"#utility.yul\":14617:14679 */\n tag_498\n /* \"#utility.yul\":14671:14678 */\n dup5\n /* \"#utility.yul\":14662:14668 */\n dup3\n /* \"#utility.yul\":14651:14660 */\n dup6\n /* \"#utility.yul\":14647:14669 */\n add\n /* \"#utility.yul\":14617:14679 */\n tag_321\n jump\t// in\n tag_498:\n /* \"#utility.yul\":14607:14679 */\n swap2\n pop\n /* \"#utility.yul\":14563:14689 */\n pop\n /* \"#utility.yul\":14349:14696 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":14702:14800 */\n tag_322:\n /* \"#utility.yul\":14753:14759 */\n 0x00\n /* \"#utility.yul\":14787:14792 */\n dup2\n /* \"#utility.yul\":14781:14793 */\n mload\n /* \"#utility.yul\":14771:14793 */\n swap1\n pop\n /* \"#utility.yul\":14702:14800 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":14806:14953 */\n tag_323:\n /* \"#utility.yul\":14907:14918 */\n 0x00\n /* \"#utility.yul\":14944:14947 */\n dup2\n /* \"#utility.yul\":14929:14947 */\n swap1\n pop\n /* \"#utility.yul\":14806:14953 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":14959:15332 */\n tag_324:\n /* \"#utility.yul\":15063:15066 */\n 0x00\n /* \"#utility.yul\":15091:15129 */\n tag_502\n /* \"#utility.yul\":15123:15128 */\n dup3\n /* \"#utility.yul\":15091:15129 */\n tag_322\n jump\t// in\n tag_502:\n /* \"#utility.yul\":15145:15233 */\n tag_503\n /* \"#utility.yul\":15226:15232 */\n dup2\n /* \"#utility.yul\":15221:15224 */\n dup6\n /* \"#utility.yul\":15145:15233 */\n tag_323\n jump\t// in\n tag_503:\n /* \"#utility.yul\":15138:15233 */\n swap4\n pop\n /* \"#utility.yul\":15242:15294 */\n tag_504\n /* \"#utility.yul\":15287:15293 */\n dup2\n /* \"#utility.yul\":15282:15285 */\n dup6\n /* \"#utility.yul\":15275:15279 */\n 0x20\n /* \"#utility.yul\":15268:15273 */\n dup7\n /* \"#utility.yul\":15264:15280 */\n add\n /* \"#utility.yul\":15242:15294 */\n tag_284\n jump\t// in\n tag_504:\n /* \"#utility.yul\":15319:15325 */\n dup1\n /* \"#utility.yul\":15314:15317 */\n dup5\n /* \"#utility.yul\":15310:15326 */\n add\n /* \"#utility.yul\":15303:15326 */\n swap2\n pop\n /* \"#utility.yul\":15067:15332 */\n pop\n /* \"#utility.yul\":14959:15332 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":15338:15609 */\n tag_216:\n /* \"#utility.yul\":15468:15471 */\n 0x00\n /* \"#utility.yul\":15490:15583 */\n tag_506\n /* \"#utility.yul\":15579:15582 */\n dup3\n /* \"#utility.yul\":15570:15576 */\n dup5\n /* \"#utility.yul\":15490:15583 */\n tag_324\n jump\t// in\n tag_506:\n /* \"#utility.yul\":15483:15583 */\n swap2\n pop\n /* \"#utility.yul\":15600:15603 */\n dup2\n /* \"#utility.yul\":15593:15603 */\n swap1\n pop\n /* \"#utility.yul\":15338:15609 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":15615:15947 */\n tag_252:\n /* \"#utility.yul\":15736:15740 */\n 0x00\n /* \"#utility.yul\":15774:15776 */\n 0x40\n /* \"#utility.yul\":15763:15772 */\n dup3\n /* \"#utility.yul\":15759:15777 */\n add\n /* \"#utility.yul\":15751:15777 */\n swap1\n pop\n /* \"#utility.yul\":15787:15858 */\n tag_508\n /* \"#utility.yul\":15855:15856 */\n 0x00\n /* \"#utility.yul\":15844:15853 */\n dup4\n /* \"#utility.yul\":15840:15857 */\n add\n /* \"#utility.yul\":15831:15837 */\n dup6\n /* \"#utility.yul\":15787:15858 */\n tag_281\n jump\t// in\n tag_508:\n /* \"#utility.yul\":15868:15940 */\n tag_509\n /* \"#utility.yul\":15936:15938 */\n 0x20\n /* \"#utility.yul\":15925:15934 */\n dup4\n /* \"#utility.yul\":15921:15939 */\n add\n /* \"#utility.yul\":15912:15918 */\n dup5\n /* \"#utility.yul\":15868:15940 */\n tag_281\n jump\t// in\n tag_509:\n /* \"#utility.yul\":15615:15947 */\n swap4\n swap3\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":15953:16107 */\n tag_325:\n /* \"#utility.yul\":16037:16043 */\n dup3\n /* \"#utility.yul\":16032:16035 */\n dup2\n /* \"#utility.yul\":16027:16030 */\n dup4\n /* \"#utility.yul\":16014:16044 */\n calldatacopy\n /* \"#utility.yul\":16099:16100 */\n 0x00\n /* \"#utility.yul\":16090:16096 */\n dup4\n /* \"#utility.yul\":16085:16088 */\n dup4\n /* \"#utility.yul\":16081:16097 */\n add\n /* \"#utility.yul\":16074:16101 */\n mstore\n /* \"#utility.yul\":15953:16107 */\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":16137:16441 */\n tag_326:\n /* \"#utility.yul\":16235:16238 */\n 0x00\n /* \"#utility.yul\":16256:16327 */\n tag_512\n /* \"#utility.yul\":16320:16326 */\n dup4\n /* \"#utility.yul\":16315:16318 */\n dup6\n /* \"#utility.yul\":16256:16327 */\n tag_283\n jump\t// in\n tag_512:\n /* \"#utility.yul\":16249:16327 */\n swap4\n pop\n /* \"#utility.yul\":16337:16380 */\n tag_513\n /* \"#utility.yul\":16373:16379 */\n dup4\n /* \"#utility.yul\":16368:16371 */\n dup6\n /* \"#utility.yul\":16361:16366 */\n dup5\n /* \"#utility.yul\":16337:16380 */\n tag_325\n jump\t// in\n tag_513:\n /* \"#utility.yul\":16405:16434 */\n tag_514\n /* \"#utility.yul\":16427:16433 */\n dup4\n /* \"#utility.yul\":16405:16434 */\n tag_285\n jump\t// in\n tag_514:\n /* \"#utility.yul\":16400:16403 */\n dup5\n /* \"#utility.yul\":16396:16435 */\n add\n /* \"#utility.yul\":16389:16435 */\n swap1\n pop\n /* \"#utility.yul\":16137:16441 */\n swap4\n swap3\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":16447:17103 */\n tag_258:\n /* \"#utility.yul\":16652:16656 */\n 0x00\n /* \"#utility.yul\":16690:16692 */\n 0x60\n /* \"#utility.yul\":16679:16688 */\n dup3\n /* \"#utility.yul\":16675:16693 */\n add\n /* \"#utility.yul\":16667:16693 */\n swap1\n pop\n /* \"#utility.yul\":16739:16748 */\n dup2\n /* \"#utility.yul\":16733:16737 */\n dup2\n /* \"#utility.yul\":16729:16749 */\n sub\n /* \"#utility.yul\":16725:16726 */\n 0x00\n /* \"#utility.yul\":16714:16723 */\n dup4\n /* \"#utility.yul\":16710:16727 */\n add\n /* \"#utility.yul\":16703:16750 */\n mstore\n /* \"#utility.yul\":16767:16855 */\n tag_516\n /* \"#utility.yul\":16850:16854 */\n dup2\n /* \"#utility.yul\":16841:16847 */\n dup8\n /* \"#utility.yul\":16833:16839 */\n dup10\n /* \"#utility.yul\":16767:16855 */\n tag_326\n jump\t// in\n tag_516:\n /* \"#utility.yul\":16759:16855 */\n swap1\n pop\n /* \"#utility.yul\":16902:16911 */\n dup2\n /* \"#utility.yul\":16896:16900 */\n dup2\n /* \"#utility.yul\":16892:16912 */\n sub\n /* \"#utility.yul\":16887:16889 */\n 0x20\n /* \"#utility.yul\":16876:16885 */\n dup4\n /* \"#utility.yul\":16872:16890 */\n add\n /* \"#utility.yul\":16865:16913 */\n mstore\n /* \"#utility.yul\":16930:17018 */\n tag_517\n /* \"#utility.yul\":17013:17017 */\n dup2\n /* \"#utility.yul\":17004:17010 */\n dup6\n /* \"#utility.yul\":16996:17002 */\n dup8\n /* \"#utility.yul\":16930:17018 */\n tag_326\n jump\t// in\n tag_517:\n /* \"#utility.yul\":16922:17018 */\n swap1\n pop\n /* \"#utility.yul\":17028:17096 */\n tag_518\n /* \"#utility.yul\":17092:17094 */\n 0x40\n /* \"#utility.yul\":17081:17090 */\n dup4\n /* \"#utility.yul\":17077:17095 */\n add\n /* \"#utility.yul\":17068:17074 */\n dup5\n /* \"#utility.yul\":17028:17096 */\n tag_299\n jump\t// in\n tag_518:\n /* \"#utility.yul\":16447:17103 */\n swap7\n swap6\n pop\n pop\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":17109:17551 */\n tag_275:\n /* \"#utility.yul\":17258:17262 */\n 0x00\n /* \"#utility.yul\":17296:17298 */\n 0x60\n /* \"#utility.yul\":17285:17294 */\n dup3\n /* \"#utility.yul\":17281:17299 */\n add\n /* \"#utility.yul\":17273:17299 */\n swap1\n pop\n /* \"#utility.yul\":17309:17380 */\n tag_520\n /* \"#utility.yul\":17377:17378 */\n 0x00\n /* \"#utility.yul\":17366:17375 */\n dup4\n /* \"#utility.yul\":17362:17379 */\n add\n /* \"#utility.yul\":17353:17359 */\n dup7\n /* \"#utility.yul\":17309:17380 */\n tag_281\n jump\t// in\n tag_520:\n /* \"#utility.yul\":17390:17462 */\n tag_521\n /* \"#utility.yul\":17458:17460 */\n 0x20\n /* \"#utility.yul\":17447:17456 */\n dup4\n /* \"#utility.yul\":17443:17461 */\n add\n /* \"#utility.yul\":17434:17440 */\n dup6\n /* \"#utility.yul\":17390:17462 */\n tag_281\n jump\t// in\n tag_521:\n /* \"#utility.yul\":17472:17544 */\n tag_522\n /* \"#utility.yul\":17540:17542 */\n 0x40\n /* \"#utility.yul\":17529:17538 */\n dup4\n /* \"#utility.yul\":17525:17543 */\n add\n /* \"#utility.yul\":17516:17522 */\n dup5\n /* \"#utility.yul\":17472:17544 */\n tag_281\n jump\t// in\n tag_522:\n /* \"#utility.yul\":17109:17551 */\n swap5\n swap4\n pop\n pop\n pop\n pop\n jump\t// out\n\n auxdata: 0xa2646970667358221220bb130f9250effb623338d0a0c315a1bcd08d8c15c5754a8191f2673314da04c464736f6c634300080b0033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "608060405273fffffffede9001a6f7f4798ccb76ef1e7f6647016000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073fffffffede9001a6f7f4798ccb76ef1e7f664701600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156100b957600080fd5b5061205c806100c96000396000f3fe60806040526004361061016a5760003560e01c806384810219116100d1578063a9059cbb1161008a578063ee5dc1e411610064578063ee5dc1e4146105c1578063f0350c04146105fe578063f5bfbd8a1461063b578063f8bf8e951461067857610171565b8063a9059cbb1461051c578063d3ba4b9e14610559578063dd62ed3e1461058457610171565b806384810219146103e65780638d1fdf2f1461040f57806395d89b411461044c5780639b5067e7146104775780639dc29fac146104a2578063a887c981146104df57610171565b8063313ce56711610123578063313ce5671461029c57806340c10f19146102c75780635ea20216146103045780636b8751c11461034157806370a082311461036c5780637eea1205146103a957610171565b80630131222f1461017657806306fdde03146101a1578063095ea7b3146101cc57806318160ddd146102095780631cddec191461023457806323b872dd1461025f57610171565b3661017157005b600080fd5b34801561018257600080fd5b5061018b6106b5565b6040516101989190611766565b60405180910390f35b3480156101ad57600080fd5b506101b66106df565b6040516101c3919061181a565b60405180910390f35b3480156101d857600080fd5b506101f360048036038101906101ee91906118b2565b61077a565b604051610200919061190d565b60405180910390f35b34801561021557600080fd5b5061021e610823565b60405161022b9190611937565b60405180910390f35b34801561024057600080fd5b506102496108ba565b604051610256919061190d565b60405180910390f35b34801561026b57600080fd5b5061028660048036038101906102819190611952565b610953565b604051610293919061190d565b60405180910390f35b3480156102a857600080fd5b506102b16109ff565b6040516102be91906119c1565b60405180910390f35b3480156102d357600080fd5b506102ee60048036038101906102e991906118b2565b610a96565b6040516102fb919061190d565b60405180910390f35b34801561031057600080fd5b5061032b600480360381019061032691906119dc565b610b3f565b604051610338919061190d565b60405180910390f35b34801561034d57600080fd5b50610356610be5565b604051610363919061190d565b60405180910390f35b34801561037857600080fd5b50610393600480360381019061038e91906119dc565b610c7e565b6040516103a09190611937565b60405180910390f35b3480156103b557600080fd5b506103d060048036038101906103cb9190611952565b610d22565b6040516103dd919061190d565b60405180910390f35b3480156103f257600080fd5b5061040d600480360381019061040891906119dc565b610e50565b005b34801561041b57600080fd5b50610436600480360381019061043191906119dc565b610ed4565b604051610443919061190d565b60405180910390f35b34801561045857600080fd5b50610461610f7a565b60405161046e919061181a565b60405180910390f35b34801561048357600080fd5b5061048c611015565b6040516104999190611a68565b60405180910390f35b3480156104ae57600080fd5b506104c960048036038101906104c491906118b2565b611039565b6040516104d6919061190d565b60405180910390f35b3480156104eb57600080fd5b50610506600480360381019061050191906118b2565b6110e2565b604051610513919061190d565b60405180910390f35b34801561052857600080fd5b50610543600480360381019061053e91906118b2565b61120d565b604051610550919061190d565b60405180910390f35b34801561056557600080fd5b5061056e6112b6565b60405161057b919061190d565b60405180910390f35b34801561059057600080fd5b506105ab60048036038101906105a69190611a83565b61134f565b6040516105b89190611937565b60405180910390f35b3480156105cd57600080fd5b506105e860048036038101906105e39190611b54565b6113f6565b6040516105f5919061190d565b60405180910390f35b34801561060a57600080fd5b50610625600480360381019061062091906119dc565b6114a8565b604051610632919061190d565b60405180910390f35b34801561064757600080fd5b50610662600480360381019061065d91906118b2565b61154e565b60405161066f919061190d565b60405180910390f35b34801561068457600080fd5b5061069f600480360381019061069a9190611be9565b611679565b6040516106ac919061190d565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801561074c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906107759190611d5d565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b384846040518363ffffffff1660e01b81526004016107d8929190611da6565b6020604051808303816000875af11580156107f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081b9190611dfb565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610891573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b59190611e3d565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631cddec196040518163ffffffff1660e01b81526004016020604051808303816000875af115801561092a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094e9190611dfb565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8585856040518463ffffffff1660e01b81526004016109b393929190611e6a565b6020604051808303816000875af11580156109d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f69190611dfb565b90509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a919190611eb6565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1984846040518363ffffffff1660e01b8152600401610af4929190611da6565b6020604051808303816000875af1158015610b13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b379190611dfb565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ea20216836040518263ffffffff1660e01b8152600401610b9b9190611766565b6020604051808303816000875af1158015610bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bde9190611dfb565b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636b8751c16040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c799190611dfb565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401610cda9190611766565b602060405180830381865afa158015610cf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1b9190611e3d565b9050919050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16868686604051602401610d7593929190611e6a565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610dff9190611f2a565b600060405180830381855af49150503d8060008114610e3a576040519150601f19603f3d011682016040523d82523d6000602084013e610e3f565b606091505b509150915081925050509392505050565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d1fdf2f836040518263ffffffff1660e01b8152600401610f309190611766565b6020604051808303816000875af1158015610f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f739190611dfb565b9050919050565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610fe7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906110109190611d5d565b905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dc29fac84846040518363ffffffff1660e01b8152600401611097929190611da6565b6020604051808303816000875af11580156110b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110da9190611dfb565b905092915050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168585604051602401611133929190611da6565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516111bd9190611f2a565b600060405180830381855af49150503d80600081146111f8576040519150601f19603f3d011682016040523d82523d6000602084013e6111fd565b606091505b5091509150819250505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b815260040161126b929190611da6565b6020604051808303816000875af115801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae9190611dfb565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d3ba4b9e6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611326573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134a9190611dfb565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e84846040518363ffffffff1660e01b81526004016113ad929190611f41565b602060405180830381865afa1580156113ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ee9190611e3d565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee5dc1e487878787876040518663ffffffff1660e01b815260040161145a959493929190611fa6565b6020604051808303816000875af1158015611479573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149d9190611dfb565b905095945050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f0350c04836040518263ffffffff1660e01b81526004016115049190611766565b6020604051808303816000875af1158015611523573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115479190611dfb565b9050919050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16858560405160240161159f929190611da6565b6040516020818303038152906040527f095ea7b3000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516116299190611f2a565b600060405180830381855af49150503d8060008114611664576040519150601f19603f3d011682016040523d82523d6000602084013e611669565b606091505b5091509150819250505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8bf8e958585856040518463ffffffff1660e01b81526004016116d993929190611fef565b6020604051808303816000875af11580156116f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171c9190611dfb565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061175082611725565b9050919050565b61176081611745565b82525050565b600060208201905061177b6000830184611757565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156117bb5780820151818401526020810190506117a0565b838111156117ca576000848401525b50505050565b6000601f19601f8301169050919050565b60006117ec82611781565b6117f6818561178c565b935061180681856020860161179d565b61180f816117d0565b840191505092915050565b6000602082019050818103600083015261183481846117e1565b905092915050565b6000604051905090565b600080fd5b600080fd5b61185981611745565b811461186457600080fd5b50565b60008135905061187681611850565b92915050565b6000819050919050565b61188f8161187c565b811461189a57600080fd5b50565b6000813590506118ac81611886565b92915050565b600080604083850312156118c9576118c8611846565b5b60006118d785828601611867565b92505060206118e88582860161189d565b9150509250929050565b60008115159050919050565b611907816118f2565b82525050565b600060208201905061192260008301846118fe565b92915050565b6119318161187c565b82525050565b600060208201905061194c6000830184611928565b92915050565b60008060006060848603121561196b5761196a611846565b5b600061197986828701611867565b935050602061198a86828701611867565b925050604061199b8682870161189d565b9150509250925092565b600060ff82169050919050565b6119bb816119a5565b82525050565b60006020820190506119d660008301846119b2565b92915050565b6000602082840312156119f2576119f1611846565b5b6000611a0084828501611867565b91505092915050565b6000819050919050565b6000611a2e611a29611a2484611725565b611a09565b611725565b9050919050565b6000611a4082611a13565b9050919050565b6000611a5282611a35565b9050919050565b611a6281611a47565b82525050565b6000602082019050611a7d6000830184611a59565b92915050565b60008060408385031215611a9a57611a99611846565b5b6000611aa885828601611867565b9250506020611ab985828601611867565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112611ae857611ae7611ac3565b5b8235905067ffffffffffffffff811115611b0557611b04611ac8565b5b602083019150836001820283011115611b2157611b20611acd565b5b9250929050565b611b31816119a5565b8114611b3c57600080fd5b50565b600081359050611b4e81611b28565b92915050565b600080600080600060608688031215611b7057611b6f611846565b5b600086013567ffffffffffffffff811115611b8e57611b8d61184b565b5b611b9a88828901611ad2565b9550955050602086013567ffffffffffffffff811115611bbd57611bbc61184b565b5b611bc988828901611ad2565b93509350506040611bdc88828901611b3f565b9150509295509295909350565b600080600060608486031215611c0257611c01611846565b5b6000611c1086828701611867565b9350506020611c2186828701611867565b9250506040611c3286828701611867565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611c79826117d0565b810181811067ffffffffffffffff82111715611c9857611c97611c41565b5b80604052505050565b6000611cab61183c565b9050611cb78282611c70565b919050565b600067ffffffffffffffff821115611cd757611cd6611c41565b5b611ce0826117d0565b9050602081019050919050565b6000611d00611cfb84611cbc565b611ca1565b905082815260208101848484011115611d1c57611d1b611c3c565b5b611d2784828561179d565b509392505050565b600082601f830112611d4457611d43611ac3565b5b8151611d54848260208601611ced565b91505092915050565b600060208284031215611d7357611d72611846565b5b600082015167ffffffffffffffff811115611d9157611d9061184b565b5b611d9d84828501611d2f565b91505092915050565b6000604082019050611dbb6000830185611757565b611dc86020830184611928565b9392505050565b611dd8816118f2565b8114611de357600080fd5b50565b600081519050611df581611dcf565b92915050565b600060208284031215611e1157611e10611846565b5b6000611e1f84828501611de6565b91505092915050565b600081519050611e3781611886565b92915050565b600060208284031215611e5357611e52611846565b5b6000611e6184828501611e28565b91505092915050565b6000606082019050611e7f6000830186611757565b611e8c6020830185611757565b611e996040830184611928565b949350505050565b600081519050611eb081611b28565b92915050565b600060208284031215611ecc57611ecb611846565b5b6000611eda84828501611ea1565b91505092915050565b600081519050919050565b600081905092915050565b6000611f0482611ee3565b611f0e8185611eee565b9350611f1e81856020860161179d565b80840191505092915050565b6000611f368284611ef9565b915081905092915050565b6000604082019050611f566000830185611757565b611f636020830184611757565b9392505050565b82818337600083830152505050565b6000611f85838561178c565b9350611f92838584611f6a565b611f9b836117d0565b840190509392505050565b60006060820190508181036000830152611fc1818789611f79565b90508181036020830152611fd6818587611f79565b9050611fe560408301846119b2565b9695505050505050565b60006060820190506120046000830186611757565b6120116020830185611757565b61201e6040830184611757565b94935050505056fea2646970667358221220bb130f9250effb623338d0a0c315a1bcd08d8c15c5754a8191f2673314da04c464736f6c634300080b0033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH20 0xFFFFFFFEDE9001A6F7F4798CCB76EF1E7F664701 PUSH1 0x0 DUP1 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP PUSH20 0xFFFFFFFEDE9001A6F7F4798CCB76EF1E7F664701 PUSH1 0x1 PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP CALLVALUE DUP1 ISZERO PUSH2 0xB9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x205C DUP1 PUSH2 0xC9 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x16A JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x84810219 GT PUSH2 0xD1 JUMPI DUP1 PUSH4 0xA9059CBB GT PUSH2 0x8A JUMPI DUP1 PUSH4 0xEE5DC1E4 GT PUSH2 0x64 JUMPI DUP1 PUSH4 0xEE5DC1E4 EQ PUSH2 0x5C1 JUMPI DUP1 PUSH4 0xF0350C04 EQ PUSH2 0x5FE JUMPI DUP1 PUSH4 0xF5BFBD8A EQ PUSH2 0x63B JUMPI DUP1 PUSH4 0xF8BF8E95 EQ PUSH2 0x678 JUMPI PUSH2 0x171 JUMP JUMPDEST DUP1 PUSH4 0xA9059CBB EQ PUSH2 0x51C JUMPI DUP1 PUSH4 0xD3BA4B9E EQ PUSH2 0x559 JUMPI DUP1 PUSH4 0xDD62ED3E EQ PUSH2 0x584 JUMPI PUSH2 0x171 JUMP JUMPDEST DUP1 PUSH4 0x84810219 EQ PUSH2 0x3E6 JUMPI DUP1 PUSH4 0x8D1FDF2F EQ PUSH2 0x40F JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x44C JUMPI DUP1 PUSH4 0x9B5067E7 EQ PUSH2 0x477 JUMPI DUP1 PUSH4 0x9DC29FAC EQ PUSH2 0x4A2 JUMPI DUP1 PUSH4 0xA887C981 EQ PUSH2 0x4DF JUMPI PUSH2 0x171 JUMP JUMPDEST DUP1 PUSH4 0x313CE567 GT PUSH2 0x123 JUMPI DUP1 PUSH4 0x313CE567 EQ PUSH2 0x29C JUMPI DUP1 PUSH4 0x40C10F19 EQ PUSH2 0x2C7 JUMPI DUP1 PUSH4 0x5EA20216 EQ PUSH2 0x304 JUMPI DUP1 PUSH4 0x6B8751C1 EQ PUSH2 0x341 JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x36C JUMPI DUP1 PUSH4 0x7EEA1205 EQ PUSH2 0x3A9 JUMPI PUSH2 0x171 JUMP JUMPDEST DUP1 PUSH4 0x131222F EQ PUSH2 0x176 JUMPI DUP1 PUSH4 0x6FDDE03 EQ PUSH2 0x1A1 JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x1CC JUMPI DUP1 PUSH4 0x18160DDD EQ PUSH2 0x209 JUMPI DUP1 PUSH4 0x1CDDEC19 EQ PUSH2 0x234 JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x25F JUMPI PUSH2 0x171 JUMP JUMPDEST CALLDATASIZE PUSH2 0x171 JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x182 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x18B PUSH2 0x6B5 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x198 SWAP2 SWAP1 PUSH2 0x1766 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1AD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B6 PUSH2 0x6DF JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1C3 SWAP2 SWAP1 PUSH2 0x181A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1F3 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x1EE SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0x77A JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x200 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x215 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x21E PUSH2 0x823 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x22B SWAP2 SWAP1 PUSH2 0x1937 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x240 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x249 PUSH2 0x8BA JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x256 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x26B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x286 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x281 SWAP2 SWAP1 PUSH2 0x1952 JUMP JUMPDEST PUSH2 0x953 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x293 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2B1 PUSH2 0x9FF JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x2BE SWAP2 SWAP1 PUSH2 0x19C1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2D3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2EE PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x2E9 SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0xA96 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x2FB SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x310 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x32B PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x326 SWAP2 SWAP1 PUSH2 0x19DC JUMP JUMPDEST PUSH2 0xB3F JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x338 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x34D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x356 PUSH2 0xBE5 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x363 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x378 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x393 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x38E SWAP2 SWAP1 PUSH2 0x19DC JUMP JUMPDEST PUSH2 0xC7E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x3A0 SWAP2 SWAP1 PUSH2 0x1937 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3B5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x3D0 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x3CB SWAP2 SWAP1 PUSH2 0x1952 JUMP JUMPDEST PUSH2 0xD22 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x3DD SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3F2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x40D PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x408 SWAP2 SWAP1 PUSH2 0x19DC JUMP JUMPDEST PUSH2 0xE50 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x41B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x436 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x431 SWAP2 SWAP1 PUSH2 0x19DC JUMP JUMPDEST PUSH2 0xED4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x443 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x458 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x461 PUSH2 0xF7A JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x46E SWAP2 SWAP1 PUSH2 0x181A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x483 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x48C PUSH2 0x1015 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x499 SWAP2 SWAP1 PUSH2 0x1A68 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4AE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x4C9 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x4C4 SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0x1039 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x4D6 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4EB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x506 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x501 SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0x10E2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x513 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x528 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x543 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x53E SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0x120D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x550 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x565 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x56E PUSH2 0x12B6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x57B SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x590 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5AB PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x5A6 SWAP2 SWAP1 PUSH2 0x1A83 JUMP JUMPDEST PUSH2 0x134F JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x5B8 SWAP2 SWAP1 PUSH2 0x1937 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5CD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5E8 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x5E3 SWAP2 SWAP1 PUSH2 0x1B54 JUMP JUMPDEST PUSH2 0x13F6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x5F5 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x60A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x625 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x620 SWAP2 SWAP1 PUSH2 0x19DC JUMP JUMPDEST PUSH2 0x14A8 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x632 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x647 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x662 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x65D SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0x154E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x66F SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x684 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x69F PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x69A SWAP2 SWAP1 PUSH2 0x1BE9 JUMP JUMPDEST PUSH2 0x1679 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x6AC SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x6FDDE03 PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x74C JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x0 DUP3 RETURNDATACOPY RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x775 SWAP2 SWAP1 PUSH2 0x1D5D JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x95EA7B3 DUP5 DUP5 PUSH1 0x40 MLOAD DUP4 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x7D8 SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x7F7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x81B SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x18160DDD PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x891 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x8B5 SWAP2 SWAP1 PUSH2 0x1E3D JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x1CDDEC19 PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x92A JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x94E SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x23B872DD DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD DUP5 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x9B3 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1E6A JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x9D2 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x9F6 SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x313CE567 PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0xA6D JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xA91 SWAP2 SWAP1 PUSH2 0x1EB6 JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x40C10F19 DUP5 DUP5 PUSH1 0x40 MLOAD DUP4 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0xAF4 SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0xB13 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xB37 SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x5EA20216 DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0xB9B SWAP2 SWAP1 PUSH2 0x1766 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0xBBA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xBDE SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x6B8751C1 PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0xC55 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xC79 SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x70A08231 DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0xCDA SWAP2 SWAP1 PUSH2 0x1766 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0xCF7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xD1B SWAP2 SWAP1 PUSH2 0x1E3D JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP7 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xD75 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1E6A JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH32 0x23B872DD00000000000000000000000000000000000000000000000000000000 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD PUSH2 0xDFF SWAP2 SWAP1 PUSH2 0x1F2A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0xE3A JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0xE3F JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 SWAP3 POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP1 PUSH1 0x0 DUP1 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP DUP1 PUSH1 0x1 PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x8D1FDF2F DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0xF30 SWAP2 SWAP1 PUSH2 0x1766 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0xF4F JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xF73 SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x95D89B41 PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0xFE7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x0 DUP3 RETURNDATACOPY RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x1010 SWAP2 SWAP1 PUSH2 0x1D5D JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x9DC29FAC DUP5 DUP5 PUSH1 0x40 MLOAD DUP4 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1097 SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x10B6 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x10DA SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 DUP6 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x1133 SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH32 0xA9059CBB00000000000000000000000000000000000000000000000000000000 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD PUSH2 0x11BD SWAP2 SWAP1 PUSH2 0x1F2A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x11F8 JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x11FD JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xA9059CBB DUP5 DUP5 PUSH1 0x40 MLOAD DUP4 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x126B SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x128A JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x12AE SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xD3BA4B9E PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1326 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x134A SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xDD62ED3E DUP5 DUP5 PUSH1 0x40 MLOAD DUP4 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x13AD SWAP3 SWAP2 SWAP1 PUSH2 0x1F41 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x13CA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x13EE SWAP2 SWAP1 PUSH2 0x1E3D JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xEE5DC1E4 DUP8 DUP8 DUP8 DUP8 DUP8 PUSH1 0x40 MLOAD DUP7 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x145A SWAP6 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1FA6 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1479 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x149D SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xF0350C04 DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1504 SWAP2 SWAP1 PUSH2 0x1766 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1523 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x1547 SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 DUP6 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x159F SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH32 0x95EA7B300000000000000000000000000000000000000000000000000000000 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD PUSH2 0x1629 SWAP2 SWAP1 PUSH2 0x1F2A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x1664 JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x1669 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xF8BF8E95 DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD DUP5 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x16D9 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1FEF JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x16F8 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x171C SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1750 DUP3 PUSH2 0x1725 JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x1760 DUP2 PUSH2 0x1745 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x177B PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0x1757 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x17BB JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0x17A0 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x17CA JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x17EC DUP3 PUSH2 0x1781 JUMP JUMPDEST PUSH2 0x17F6 DUP2 DUP6 PUSH2 0x178C JUMP JUMPDEST SWAP4 POP PUSH2 0x1806 DUP2 DUP6 PUSH1 0x20 DUP7 ADD PUSH2 0x179D JUMP JUMPDEST PUSH2 0x180F DUP2 PUSH2 0x17D0 JUMP JUMPDEST DUP5 ADD SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP DUP2 DUP2 SUB PUSH1 0x0 DUP4 ADD MSTORE PUSH2 0x1834 DUP2 DUP5 PUSH2 0x17E1 JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1859 DUP2 PUSH2 0x1745 JUMP JUMPDEST DUP2 EQ PUSH2 0x1864 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 CALLDATALOAD SWAP1 POP PUSH2 0x1876 DUP2 PUSH2 0x1850 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x188F DUP2 PUSH2 0x187C JUMP JUMPDEST DUP2 EQ PUSH2 0x189A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 CALLDATALOAD SWAP1 POP PUSH2 0x18AC DUP2 PUSH2 0x1886 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x18C9 JUMPI PUSH2 0x18C8 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x18D7 DUP6 DUP3 DUP7 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x18E8 DUP6 DUP3 DUP7 ADD PUSH2 0x189D JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP2 ISZERO ISZERO SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x1907 DUP2 PUSH2 0x18F2 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x1922 PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0x18FE JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH2 0x1931 DUP2 PUSH2 0x187C JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x194C PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0x1928 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x196B JUMPI PUSH2 0x196A PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1979 DUP7 DUP3 DUP8 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x198A DUP7 DUP3 DUP8 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 PUSH2 0x199B DUP7 DUP3 DUP8 ADD PUSH2 0x189D JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0xFF DUP3 AND SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x19BB DUP2 PUSH2 0x19A5 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x19D6 PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0x19B2 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x19F2 JUMPI PUSH2 0x19F1 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1A00 DUP5 DUP3 DUP6 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A2E PUSH2 0x1A29 PUSH2 0x1A24 DUP5 PUSH2 0x1725 JUMP JUMPDEST PUSH2 0x1A09 JUMP JUMPDEST PUSH2 0x1725 JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A40 DUP3 PUSH2 0x1A13 JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A52 DUP3 PUSH2 0x1A35 JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x1A62 DUP2 PUSH2 0x1A47 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x1A7D PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0x1A59 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1A9A JUMPI PUSH2 0x1A99 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1AA8 DUP6 DUP3 DUP7 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x1AB9 DUP6 DUP3 DUP7 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x1AE8 JUMPI PUSH2 0x1AE7 PUSH2 0x1AC3 JUMP JUMPDEST JUMPDEST DUP3 CALLDATALOAD SWAP1 POP PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1B05 JUMPI PUSH2 0x1B04 PUSH2 0x1AC8 JUMP JUMPDEST JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x1B21 JUMPI PUSH2 0x1B20 PUSH2 0x1ACD JUMP JUMPDEST JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH2 0x1B31 DUP2 PUSH2 0x19A5 JUMP JUMPDEST DUP2 EQ PUSH2 0x1B3C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 CALLDATALOAD SWAP1 POP PUSH2 0x1B4E DUP2 PUSH2 0x1B28 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP7 DUP9 SUB SLT ISZERO PUSH2 0x1B70 JUMPI PUSH2 0x1B6F PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1B8E JUMPI PUSH2 0x1B8D PUSH2 0x184B JUMP JUMPDEST JUMPDEST PUSH2 0x1B9A DUP9 DUP3 DUP10 ADD PUSH2 0x1AD2 JUMP JUMPDEST SWAP6 POP SWAP6 POP POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1BBD JUMPI PUSH2 0x1BBC PUSH2 0x184B JUMP JUMPDEST JUMPDEST PUSH2 0x1BC9 DUP9 DUP3 DUP10 ADD PUSH2 0x1AD2 JUMP JUMPDEST SWAP4 POP SWAP4 POP POP PUSH1 0x40 PUSH2 0x1BDC DUP9 DUP3 DUP10 ADD PUSH2 0x1B3F JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x1C02 JUMPI PUSH2 0x1C01 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1C10 DUP7 DUP3 DUP8 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x1C21 DUP7 DUP3 DUP8 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 PUSH2 0x1C32 DUP7 DUP3 DUP8 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH2 0x1C79 DUP3 PUSH2 0x17D0 JUMP JUMPDEST DUP2 ADD DUP2 DUP2 LT PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT OR ISZERO PUSH2 0x1C98 JUMPI PUSH2 0x1C97 PUSH2 0x1C41 JUMP JUMPDEST JUMPDEST DUP1 PUSH1 0x40 MSTORE POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1CAB PUSH2 0x183C JUMP JUMPDEST SWAP1 POP PUSH2 0x1CB7 DUP3 DUP3 PUSH2 0x1C70 JUMP JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1CD7 JUMPI PUSH2 0x1CD6 PUSH2 0x1C41 JUMP JUMPDEST JUMPDEST PUSH2 0x1CE0 DUP3 PUSH2 0x17D0 JUMP JUMPDEST SWAP1 POP PUSH1 0x20 DUP2 ADD SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1D00 PUSH2 0x1CFB DUP5 PUSH2 0x1CBC JUMP JUMPDEST PUSH2 0x1CA1 JUMP JUMPDEST SWAP1 POP DUP3 DUP2 MSTORE PUSH1 0x20 DUP2 ADD DUP5 DUP5 DUP5 ADD GT ISZERO PUSH2 0x1D1C JUMPI PUSH2 0x1D1B PUSH2 0x1C3C JUMP JUMPDEST JUMPDEST PUSH2 0x1D27 DUP5 DUP3 DUP6 PUSH2 0x179D JUMP JUMPDEST POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x1D44 JUMPI PUSH2 0x1D43 PUSH2 0x1AC3 JUMP JUMPDEST JUMPDEST DUP2 MLOAD PUSH2 0x1D54 DUP5 DUP3 PUSH1 0x20 DUP7 ADD PUSH2 0x1CED JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1D73 JUMPI PUSH2 0x1D72 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 DUP3 ADD MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1D91 JUMPI PUSH2 0x1D90 PUSH2 0x184B JUMP JUMPDEST JUMPDEST PUSH2 0x1D9D DUP5 DUP3 DUP6 ADD PUSH2 0x1D2F JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP3 ADD SWAP1 POP PUSH2 0x1DBB PUSH1 0x0 DUP4 ADD DUP6 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x1DC8 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x1928 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1DD8 DUP2 PUSH2 0x18F2 JUMP JUMPDEST DUP2 EQ PUSH2 0x1DE3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD SWAP1 POP PUSH2 0x1DF5 DUP2 PUSH2 0x1DCF JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1E11 JUMPI PUSH2 0x1E10 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1E1F DUP5 DUP3 DUP6 ADD PUSH2 0x1DE6 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD SWAP1 POP PUSH2 0x1E37 DUP2 PUSH2 0x1886 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1E53 JUMPI PUSH2 0x1E52 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1E61 DUP5 DUP3 DUP6 ADD PUSH2 0x1E28 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 ADD SWAP1 POP PUSH2 0x1E7F PUSH1 0x0 DUP4 ADD DUP7 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x1E8C PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x1E99 PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0x1928 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD SWAP1 POP PUSH2 0x1EB0 DUP2 PUSH2 0x1B28 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1ECC JUMPI PUSH2 0x1ECB PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1EDA DUP5 DUP3 DUP6 ADD PUSH2 0x1EA1 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP2 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1F04 DUP3 PUSH2 0x1EE3 JUMP JUMPDEST PUSH2 0x1F0E DUP2 DUP6 PUSH2 0x1EEE JUMP JUMPDEST SWAP4 POP PUSH2 0x1F1E DUP2 DUP6 PUSH1 0x20 DUP7 ADD PUSH2 0x179D JUMP JUMPDEST DUP1 DUP5 ADD SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1F36 DUP3 DUP5 PUSH2 0x1EF9 JUMP JUMPDEST SWAP2 POP DUP2 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP3 ADD SWAP1 POP PUSH2 0x1F56 PUSH1 0x0 DUP4 ADD DUP6 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x1F63 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x1757 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY PUSH1 0x0 DUP4 DUP4 ADD MSTORE POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1F85 DUP4 DUP6 PUSH2 0x178C JUMP JUMPDEST SWAP4 POP PUSH2 0x1F92 DUP4 DUP6 DUP5 PUSH2 0x1F6A JUMP JUMPDEST PUSH2 0x1F9B DUP4 PUSH2 0x17D0 JUMP JUMPDEST DUP5 ADD SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 ADD SWAP1 POP DUP2 DUP2 SUB PUSH1 0x0 DUP4 ADD MSTORE PUSH2 0x1FC1 DUP2 DUP8 DUP10 PUSH2 0x1F79 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x1FD6 DUP2 DUP6 DUP8 PUSH2 0x1F79 JUMP JUMPDEST SWAP1 POP PUSH2 0x1FE5 PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0x19B2 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 ADD SWAP1 POP PUSH2 0x2004 PUSH1 0x0 DUP4 ADD DUP7 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x2011 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x201E PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0x1757 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xBB SGT 0xF SWAP3 POP 0xEF 0xFB PUSH3 0x3338D0 LOG0 0xC3 ISZERO LOG1 0xBC 0xD0 DUP14 DUP13 ISZERO 0xC5 PUSH22 0x4A8191F2673314DA04C464736F6C634300080B003300 ", + "sourceMap": "6591:5473:0:-:0;;;6800:42;6727:116;;;;;;;;;;;;;;;;;;;;6886:42;6853:75;;;;;;;;;;;;;;;;;;;;6591:5473;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": { + "@_197": { + "entryPoint": null, + "id": 197, + "parameterSlots": 0, + "returnSlots": 0 + }, + "@allowance_296": { + "entryPoint": 4943, + "id": 296, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@approve_505": { + "entryPoint": 1914, + "id": 505, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@approve_delegate_531": { + "entryPoint": 5454, + "id": 531, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@balanceOf_279": { + "entryPoint": 3198, + "id": 279, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@burn_347": { + "entryPoint": 4153, + "id": 347, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@clear_metadata_462": { + "entryPoint": 4790, + "id": 462, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@decimals_254": { + "entryPoint": 2559, + "id": 254, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@freeze_361": { + "entryPoint": 3796, + "id": 361, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@freeze_asset_386": { + "entryPoint": 3045, + "id": 386, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@get_address_221": { + "entryPoint": 1717, + "id": 221, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@localasseterc20_190": { + "entryPoint": 4117, + "id": 190, + "parameterSlots": 0, + "returnSlots": 0 + }, + "@mint_330": { + "entryPoint": 2710, + "id": 330, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@name_232": { + "entryPoint": 1759, + "id": 232, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@set_address_interface_213": { + "entryPoint": 3664, + "id": 213, + "parameterSlots": 1, + "returnSlots": 0 + }, + "@set_metadata_451": { + "entryPoint": 5110, + "id": 451, + "parameterSlots": 5, + "returnSlots": 1 + }, + "@set_team_431": { + "entryPoint": 5753, + "id": 431, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@symbol_243": { + "entryPoint": 3962, + "id": 243, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@thaw_375": { + "entryPoint": 2879, + "id": 375, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@thaw_asset_397": { + "entryPoint": 2234, + "id": 397, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@totalSupply_265": { + "entryPoint": 2083, + "id": 265, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@transferFrom_551": { + "entryPoint": 2387, + "id": 551, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@transferFrom_delegate_580": { + "entryPoint": 3362, + "id": 580, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@transfer_313": { + "entryPoint": 4621, + "id": 313, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@transfer_delegate_488": { + "entryPoint": 4322, + "id": 488, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@transfer_ownership_411": { + "entryPoint": 5288, + "id": 411, + "parameterSlots": 1, + "returnSlots": 1 + }, + "abi_decode_available_length_t_string_memory_ptr_fromMemory": { + "entryPoint": 7405, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_decode_t_address": { + "entryPoint": 6247, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_t_bool_fromMemory": { + "entryPoint": 7654, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_t_string_calldata_ptr": { + "entryPoint": 6866, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_t_string_memory_ptr_fromMemory": { + "entryPoint": 7471, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_t_uint256": { + "entryPoint": 6301, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_t_uint256_fromMemory": { + "entryPoint": 7720, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_t_uint8": { + "entryPoint": 6975, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_t_uint8_fromMemory": { + "entryPoint": 7841, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_address": { + "entryPoint": 6620, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_addresst_address": { + "entryPoint": 6787, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_tuple_t_addresst_addresst_address": { + "entryPoint": 7145, + "id": null, + "parameterSlots": 2, + "returnSlots": 3 + }, + "abi_decode_tuple_t_addresst_addresst_uint256": { + "entryPoint": 6482, + "id": null, + "parameterSlots": 2, + "returnSlots": 3 + }, + "abi_decode_tuple_t_addresst_uint256": { + "entryPoint": 6322, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_tuple_t_bool_fromMemory": { + "entryPoint": 7675, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_string_calldata_ptrt_string_calldata_ptrt_uint8": { + "entryPoint": 6996, + "id": null, + "parameterSlots": 2, + "returnSlots": 5 + }, + "abi_decode_tuple_t_string_memory_ptr_fromMemory": { + "entryPoint": 7517, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_uint256_fromMemory": { + "entryPoint": 7741, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_uint8_fromMemory": { + "entryPoint": 7862, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_t_address_to_t_address_fromStack": { + "entryPoint": 5975, + "id": null, + "parameterSlots": 2, + "returnSlots": 0 + }, + "abi_encode_t_bool_to_t_bool_fromStack": { + "entryPoint": 6398, + "id": null, + "parameterSlots": 2, + "returnSlots": 0 + }, + "abi_encode_t_bytes_memory_ptr_to_t_bytes_memory_ptr_nonPadded_inplace_fromStack": { + "entryPoint": 7929, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_t_contract$_LocalAssetExtendedErc20_$181_to_t_address_fromStack": { + "entryPoint": 6745, + "id": null, + "parameterSlots": 2, + "returnSlots": 0 + }, + "abi_encode_t_string_calldata_ptr_to_t_string_memory_ptr_fromStack": { + "entryPoint": 8057, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack": { + "entryPoint": 6113, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_t_uint256_to_t_uint256_fromStack": { + "entryPoint": 6440, + "id": null, + "parameterSlots": 2, + "returnSlots": 0 + }, + "abi_encode_t_uint8_to_t_uint8_fromStack": { + "entryPoint": 6578, + "id": null, + "parameterSlots": 2, + "returnSlots": 0 + }, + "abi_encode_tuple_packed_t_bytes_memory_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed": { + "entryPoint": 7978, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address__to_t_address__fromStack_reversed": { + "entryPoint": 5990, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed": { + "entryPoint": 8001, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address_t_address_t_address__to_t_address_t_address_t_address__fromStack_reversed": { + "entryPoint": 8175, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed": { + "entryPoint": 7786, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address_t_uint256__to_t_address_t_uint256__fromStack_reversed": { + "entryPoint": 7590, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed": { + "entryPoint": 6413, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_contract$_LocalAssetExtendedErc20_$181__to_t_address__fromStack_reversed": { + "entryPoint": 6760, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_string_calldata_ptr_t_string_calldata_ptr_t_uint8__to_t_string_memory_ptr_t_string_memory_ptr_t_uint8__fromStack_reversed": { + "entryPoint": 8102, + "id": null, + "parameterSlots": 6, + "returnSlots": 1 + }, + "abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed": { + "entryPoint": 6170, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed": { + "entryPoint": 6455, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint8__to_t_uint8__fromStack_reversed": { + "entryPoint": 6593, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "allocate_memory": { + "entryPoint": 7329, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "allocate_unbounded": { + "entryPoint": 6204, + "id": null, + "parameterSlots": 0, + "returnSlots": 1 + }, + "array_allocation_size_t_string_memory_ptr": { + "entryPoint": 7356, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "array_length_t_bytes_memory_ptr": { + "entryPoint": 7907, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "array_length_t_string_memory_ptr": { + "entryPoint": 6017, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "array_storeLengthForEncoding_t_bytes_memory_ptr_nonPadded_inplace_fromStack": { + "entryPoint": 7918, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "array_storeLengthForEncoding_t_string_memory_ptr_fromStack": { + "entryPoint": 6028, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "cleanup_t_address": { + "entryPoint": 5957, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "cleanup_t_bool": { + "entryPoint": 6386, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "cleanup_t_uint160": { + "entryPoint": 5925, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "cleanup_t_uint256": { + "entryPoint": 6268, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "cleanup_t_uint8": { + "entryPoint": 6565, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "convert_t_contract$_LocalAssetExtendedErc20_$181_to_t_address": { + "entryPoint": 6727, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "convert_t_uint160_to_t_address": { + "entryPoint": 6709, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "convert_t_uint160_to_t_uint160": { + "entryPoint": 6675, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "copy_calldata_to_memory": { + "entryPoint": 8042, + "id": null, + "parameterSlots": 3, + "returnSlots": 0 + }, + "copy_memory_to_memory": { + "entryPoint": 6045, + "id": null, + "parameterSlots": 3, + "returnSlots": 0 + }, + "finalize_allocation": { + "entryPoint": 7280, + "id": null, + "parameterSlots": 2, + "returnSlots": 0 + }, + "identity": { + "entryPoint": 6665, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "panic_error_0x41": { + "entryPoint": 7233, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "revert_error_15abf5612cd996bc235ba1e55a4a30ac60e6bb601ff7ba4ad3f179b6be8d0490": { + "entryPoint": 6856, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d": { + "entryPoint": 6851, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef": { + "entryPoint": 6861, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "revert_error_987264b3b1d58a9c7f8255e93e81c77d86d6299019c33110a076957a3e06e2ae": { + "entryPoint": 7228, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db": { + "entryPoint": 6219, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b": { + "entryPoint": 6214, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "round_up_to_mul_of_32": { + "entryPoint": 6096, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "validator_revert_t_address": { + "entryPoint": 6224, + "id": null, + "parameterSlots": 1, + "returnSlots": 0 + }, + "validator_revert_t_bool": { + "entryPoint": 7631, + "id": null, + "parameterSlots": 1, + "returnSlots": 0 + }, + "validator_revert_t_uint256": { + "entryPoint": 6278, + "id": null, + "parameterSlots": 1, + "returnSlots": 0 + }, + "validator_revert_t_uint8": { + "entryPoint": 6952, + "id": null, + "parameterSlots": 1, + "returnSlots": 0 + } + }, + "generatedSources": [ + { + "ast": { + "nodeType": "YulBlock", + "src": "0:17554:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "52:81:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "62:65:1", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "77:5:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "84:42:1", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "73:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "73:54:1" + }, + "variableNames": [ + { + "name": "cleaned", + "nodeType": "YulIdentifier", + "src": "62:7:1" + } + ] + } + ] + }, + "name": "cleanup_t_uint160", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "34:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "cleaned", + "nodeType": "YulTypedName", + "src": "44:7:1", + "type": "" + } + ], + "src": "7:126:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "184:51:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "194:35:1", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "223:5:1" + } + ], + "functionName": { + "name": "cleanup_t_uint160", + "nodeType": "YulIdentifier", + "src": "205:17:1" + }, + "nodeType": "YulFunctionCall", + "src": "205:24:1" + }, + "variableNames": [ + { + "name": "cleaned", + "nodeType": "YulIdentifier", + "src": "194:7:1" + } + ] + } + ] + }, + "name": "cleanup_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "166:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "cleaned", + "nodeType": "YulTypedName", + "src": "176:7:1", + "type": "" + } + ], + "src": "139:96:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "306:53:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "323:3:1" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "346:5:1" + } + ], + "functionName": { + "name": "cleanup_t_address", + "nodeType": "YulIdentifier", + "src": "328:17:1" + }, + "nodeType": "YulFunctionCall", + "src": "328:24:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "316:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "316:37:1" + }, + "nodeType": "YulExpressionStatement", + "src": "316:37:1" + } + ] + }, + "name": "abi_encode_t_address_to_t_address_fromStack", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "294:5:1", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "301:3:1", + "type": "" + } + ], + "src": "241:118:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "463:124:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "473:26:1", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "485:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "496:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "481:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "481:18:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "473:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "553:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "566:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "577:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "562:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "562:17:1" + } + ], + "functionName": { + "name": "abi_encode_t_address_to_t_address_fromStack", + "nodeType": "YulIdentifier", + "src": "509:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "509:71:1" + }, + "nodeType": "YulExpressionStatement", + "src": "509:71:1" + } + ] + }, + "name": "abi_encode_tuple_t_address__to_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "435:9:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "447:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "458:4:1", + "type": "" + } + ], + "src": "365:222:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "652:40:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "663:22:1", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "679:5:1" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "673:5:1" + }, + "nodeType": "YulFunctionCall", + "src": "673:12:1" + }, + "variableNames": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "663:6:1" + } + ] + } + ] + }, + "name": "array_length_t_string_memory_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "635:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "645:6:1", + "type": "" + } + ], + "src": "593:99:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "794:73:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "811:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "816:6:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "804:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "804:19:1" + }, + "nodeType": "YulExpressionStatement", + "src": "804:19:1" + }, + { + "nodeType": "YulAssignment", + "src": "832:29:1", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "851:3:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "856:4:1", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "847:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "847:14:1" + }, + "variableNames": [ + { + "name": "updated_pos", + "nodeType": "YulIdentifier", + "src": "832:11:1" + } + ] + } + ] + }, + "name": "array_storeLengthForEncoding_t_string_memory_ptr_fromStack", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "766:3:1", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "771:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "updated_pos", + "nodeType": "YulTypedName", + "src": "782:11:1", + "type": "" + } + ], + "src": "698:169:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "922:258:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "932:10:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "941:1:1", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "936:1:1", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1001:63:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "1026:3:1" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "1031:1:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1022:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "1022:11:1" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "1045:3:1" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "1050:1:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1041:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "1041:11:1" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1035:5:1" + }, + "nodeType": "YulFunctionCall", + "src": "1035:18:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "1015:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "1015:39:1" + }, + "nodeType": "YulExpressionStatement", + "src": "1015:39:1" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "962:1:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "965:6:1" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "959:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "959:13:1" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "973:19:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "975:15:1", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "984:1:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "987:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "980:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "980:10:1" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "975:1:1" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "955:3:1", + "statements": [] + }, + "src": "951:113:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1098:76:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "1148:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "1153:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1144:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "1144:16:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1162:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "1137:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "1137:27:1" + }, + "nodeType": "YulExpressionStatement", + "src": "1137:27:1" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "1079:1:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "1082:6:1" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1076:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "1076:13:1" + }, + "nodeType": "YulIf", + "src": "1073:101:1" + } + ] + }, + "name": "copy_memory_to_memory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "src", + "nodeType": "YulTypedName", + "src": "904:3:1", + "type": "" + }, + { + "name": "dst", + "nodeType": "YulTypedName", + "src": "909:3:1", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "914:6:1", + "type": "" + } + ], + "src": "873:307:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1234:54:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "1244:38:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "1262:5:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1269:2:1", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1258:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "1258:14:1" + }, + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1278:2:1", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "not", + "nodeType": "YulIdentifier", + "src": "1274:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "1274:7:1" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "1254:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "1254:28:1" + }, + "variableNames": [ + { + "name": "result", + "nodeType": "YulIdentifier", + "src": "1244:6:1" + } + ] + } + ] + }, + "name": "round_up_to_mul_of_32", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "1217:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "result", + "nodeType": "YulTypedName", + "src": "1227:6:1", + "type": "" + } + ], + "src": "1186:102:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1386:272:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "1396:53:1", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "1443:5:1" + } + ], + "functionName": { + "name": "array_length_t_string_memory_ptr", + "nodeType": "YulIdentifier", + "src": "1410:32:1" + }, + "nodeType": "YulFunctionCall", + "src": "1410:39:1" + }, + "variables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "1400:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "1458:78:1", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "1524:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "1529:6:1" + } + ], + "functionName": { + "name": "array_storeLengthForEncoding_t_string_memory_ptr_fromStack", + "nodeType": "YulIdentifier", + "src": "1465:58:1" + }, + "nodeType": "YulFunctionCall", + "src": "1465:71:1" + }, + "variableNames": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "1458:3:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "1571:5:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1578:4:1", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1567:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "1567:16:1" + }, + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "1585:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "1590:6:1" + } + ], + "functionName": { + "name": "copy_memory_to_memory", + "nodeType": "YulIdentifier", + "src": "1545:21:1" + }, + "nodeType": "YulFunctionCall", + "src": "1545:52:1" + }, + "nodeType": "YulExpressionStatement", + "src": "1545:52:1" + }, + { + "nodeType": "YulAssignment", + "src": "1606:46:1", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "1617:3:1" + }, + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "1644:6:1" + } + ], + "functionName": { + "name": "round_up_to_mul_of_32", + "nodeType": "YulIdentifier", + "src": "1622:21:1" + }, + "nodeType": "YulFunctionCall", + "src": "1622:29:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1613:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "1613:39:1" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "1606:3:1" + } + ] + } + ] + }, + "name": "abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "1367:5:1", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "1374:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "1382:3:1", + "type": "" + } + ], + "src": "1294:364:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1782:195:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "1792:26:1", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1804:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1815:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1800:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "1800:18:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "1792:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1839:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1850:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1835:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "1835:17:1" + }, + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "1858:4:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1864:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "1854:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "1854:20:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "1828:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "1828:47:1" + }, + "nodeType": "YulExpressionStatement", + "src": "1828:47:1" + }, + { + "nodeType": "YulAssignment", + "src": "1884:86:1", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1956:6:1" + }, + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "1965:4:1" + } + ], + "functionName": { + "name": "abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack", + "nodeType": "YulIdentifier", + "src": "1892:63:1" + }, + "nodeType": "YulFunctionCall", + "src": "1892:78:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "1884:4:1" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1754:9:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1766:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "1777:4:1", + "type": "" + } + ], + "src": "1664:313:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2023:35:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "2033:19:1", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2049:2:1", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "2043:5:1" + }, + "nodeType": "YulFunctionCall", + "src": "2043:9:1" + }, + "variableNames": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "2033:6:1" + } + ] + } + ] + }, + "name": "allocate_unbounded", + "nodeType": "YulFunctionDefinition", + "returnVariables": [ + { + "name": "memPtr", + "nodeType": "YulTypedName", + "src": "2016:6:1", + "type": "" + } + ], + "src": "1983:75:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2153:28:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2170:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2173:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2163:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "2163:12:1" + }, + "nodeType": "YulExpressionStatement", + "src": "2163:12:1" + } + ] + }, + "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "nodeType": "YulFunctionDefinition", + "src": "2064:117:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2276:28:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2293:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2296:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2286:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "2286:12:1" + }, + "nodeType": "YulExpressionStatement", + "src": "2286:12:1" + } + ] + }, + "name": "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db", + "nodeType": "YulFunctionDefinition", + "src": "2187:117:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2353:79:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2410:16:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2419:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2422:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2412:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "2412:12:1" + }, + "nodeType": "YulExpressionStatement", + "src": "2412:12:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2376:5:1" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2401:5:1" + } + ], + "functionName": { + "name": "cleanup_t_address", + "nodeType": "YulIdentifier", + "src": "2383:17:1" + }, + "nodeType": "YulFunctionCall", + "src": "2383:24:1" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "2373:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "2373:35:1" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "2366:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "2366:43:1" + }, + "nodeType": "YulIf", + "src": "2363:63:1" + } + ] + }, + "name": "validator_revert_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "2346:5:1", + "type": "" + } + ], + "src": "2310:122:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2490:87:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "2500:29:1", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "2522:6:1" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2509:12:1" + }, + "nodeType": "YulFunctionCall", + "src": "2509:20:1" + }, + "variableNames": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2500:5:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2565:5:1" + } + ], + "functionName": { + "name": "validator_revert_t_address", + "nodeType": "YulIdentifier", + "src": "2538:26:1" + }, + "nodeType": "YulFunctionCall", + "src": "2538:33:1" + }, + "nodeType": "YulExpressionStatement", + "src": "2538:33:1" + } + ] + }, + "name": "abi_decode_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "2468:6:1", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "2476:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "2484:5:1", + "type": "" + } + ], + "src": "2438:139:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2628:32:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "2638:16:1", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2649:5:1" + }, + "variableNames": [ + { + "name": "cleaned", + "nodeType": "YulIdentifier", + "src": "2638:7:1" + } + ] + } + ] + }, + "name": "cleanup_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "2610:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "cleaned", + "nodeType": "YulTypedName", + "src": "2620:7:1", + "type": "" + } + ], + "src": "2583:77:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2709:79:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2766:16:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2775:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2778:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2768:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "2768:12:1" + }, + "nodeType": "YulExpressionStatement", + "src": "2768:12:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2732:5:1" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2757:5:1" + } + ], + "functionName": { + "name": "cleanup_t_uint256", + "nodeType": "YulIdentifier", + "src": "2739:17:1" + }, + "nodeType": "YulFunctionCall", + "src": "2739:24:1" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "2729:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "2729:35:1" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "2722:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "2722:43:1" + }, + "nodeType": "YulIf", + "src": "2719:63:1" + } + ] + }, + "name": "validator_revert_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "2702:5:1", + "type": "" + } + ], + "src": "2666:122:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2846:87:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "2856:29:1", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "2878:6:1" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2865:12:1" + }, + "nodeType": "YulFunctionCall", + "src": "2865:20:1" + }, + "variableNames": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2856:5:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "2921:5:1" + } + ], + "functionName": { + "name": "validator_revert_t_uint256", + "nodeType": "YulIdentifier", + "src": "2894:26:1" + }, + "nodeType": "YulFunctionCall", + "src": "2894:33:1" + }, + "nodeType": "YulExpressionStatement", + "src": "2894:33:1" + } + ] + }, + "name": "abi_decode_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "2824:6:1", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "2832:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "2840:5:1", + "type": "" + } + ], + "src": "2794:139:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3022:391:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3068:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "nodeType": "YulIdentifier", + "src": "3070:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "3070:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "3070:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3043:7:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3052:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3039:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "3039:23:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3064:2:1", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3035:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "3035:32:1" + }, + "nodeType": "YulIf", + "src": "3032:119:1" + }, + { + "nodeType": "YulBlock", + "src": "3161:117:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "3176:15:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3190:1:1", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "3180:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3205:63:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3240:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3251:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3236:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "3236:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3260:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_address", + "nodeType": "YulIdentifier", + "src": "3215:20:1" + }, + "nodeType": "YulFunctionCall", + "src": "3215:53:1" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3205:6:1" + } + ] + } + ] + }, + { + "nodeType": "YulBlock", + "src": "3288:118:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "3303:16:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3317:2:1", + "type": "", + "value": "32" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "3307:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3333:63:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3368:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3379:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3364:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "3364:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3388:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_uint256", + "nodeType": "YulIdentifier", + "src": "3343:20:1" + }, + "nodeType": "YulFunctionCall", + "src": "3343:53:1" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "3333:6:1" + } + ] + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_addresst_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2984:9:1", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "2995:7:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "3007:6:1", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "3015:6:1", + "type": "" + } + ], + "src": "2939:474:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3461:48:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "3471:32:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "3496:5:1" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "3489:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "3489:13:1" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "3482:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "3482:21:1" + }, + "variableNames": [ + { + "name": "cleaned", + "nodeType": "YulIdentifier", + "src": "3471:7:1" + } + ] + } + ] + }, + "name": "cleanup_t_bool", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "3443:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "cleaned", + "nodeType": "YulTypedName", + "src": "3453:7:1", + "type": "" + } + ], + "src": "3419:90:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3574:50:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "3591:3:1" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "3611:5:1" + } + ], + "functionName": { + "name": "cleanup_t_bool", + "nodeType": "YulIdentifier", + "src": "3596:14:1" + }, + "nodeType": "YulFunctionCall", + "src": "3596:21:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "3584:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "3584:34:1" + }, + "nodeType": "YulExpressionStatement", + "src": "3584:34:1" + } + ] + }, + "name": "abi_encode_t_bool_to_t_bool_fromStack", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "3562:5:1", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "3569:3:1", + "type": "" + } + ], + "src": "3515:109:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3722:118:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "3732:26:1", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3744:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3755:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3740:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "3740:18:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "3732:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3806:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3819:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3830:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3815:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "3815:17:1" + } + ], + "functionName": { + "name": "abi_encode_t_bool_to_t_bool_fromStack", + "nodeType": "YulIdentifier", + "src": "3768:37:1" + }, + "nodeType": "YulFunctionCall", + "src": "3768:65:1" + }, + "nodeType": "YulExpressionStatement", + "src": "3768:65:1" + } + ] + }, + "name": "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "3694:9:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "3706:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "3717:4:1", + "type": "" + } + ], + "src": "3630:210:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3911:53:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "3928:3:1" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "3951:5:1" + } + ], + "functionName": { + "name": "cleanup_t_uint256", + "nodeType": "YulIdentifier", + "src": "3933:17:1" + }, + "nodeType": "YulFunctionCall", + "src": "3933:24:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "3921:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "3921:37:1" + }, + "nodeType": "YulExpressionStatement", + "src": "3921:37:1" + } + ] + }, + "name": "abi_encode_t_uint256_to_t_uint256_fromStack", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "3899:5:1", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "3906:3:1", + "type": "" + } + ], + "src": "3846:118:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4068:124:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "4078:26:1", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4090:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4101:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4086:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "4086:18:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "4078:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4158:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4171:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4182:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4167:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "4167:17:1" + } + ], + "functionName": { + "name": "abi_encode_t_uint256_to_t_uint256_fromStack", + "nodeType": "YulIdentifier", + "src": "4114:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "4114:71:1" + }, + "nodeType": "YulExpressionStatement", + "src": "4114:71:1" + } + ] + }, + "name": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "4040:9:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "4052:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "4063:4:1", + "type": "" + } + ], + "src": "3970:222:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4298:519:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "4344:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "nodeType": "YulIdentifier", + "src": "4346:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "4346:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "4346:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4319:7:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4328:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "4315:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "4315:23:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4340:2:1", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "4311:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "4311:32:1" + }, + "nodeType": "YulIf", + "src": "4308:119:1" + }, + { + "nodeType": "YulBlock", + "src": "4437:117:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "4452:15:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4466:1:1", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "4456:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4481:63:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4516:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4527:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4512:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "4512:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4536:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_address", + "nodeType": "YulIdentifier", + "src": "4491:20:1" + }, + "nodeType": "YulFunctionCall", + "src": "4491:53:1" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4481:6:1" + } + ] + } + ] + }, + { + "nodeType": "YulBlock", + "src": "4564:118:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "4579:16:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4593:2:1", + "type": "", + "value": "32" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "4583:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4609:63:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4644:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4655:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4640:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "4640:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4664:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_address", + "nodeType": "YulIdentifier", + "src": "4619:20:1" + }, + "nodeType": "YulFunctionCall", + "src": "4619:53:1" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "4609:6:1" + } + ] + } + ] + }, + { + "nodeType": "YulBlock", + "src": "4692:118:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "4707:16:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4721:2:1", + "type": "", + "value": "64" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "4711:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4737:63:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4772:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4783:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4768:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "4768:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4792:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_uint256", + "nodeType": "YulIdentifier", + "src": "4747:20:1" + }, + "nodeType": "YulFunctionCall", + "src": "4747:53:1" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "4737:6:1" + } + ] + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_addresst_addresst_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "4252:9:1", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "4263:7:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "4275:6:1", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "4283:6:1", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "4291:6:1", + "type": "" + } + ], + "src": "4198:619:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4866:43:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "4876:27:1", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "4891:5:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4898:4:1", + "type": "", + "value": "0xff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "4887:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "4887:16:1" + }, + "variableNames": [ + { + "name": "cleaned", + "nodeType": "YulIdentifier", + "src": "4876:7:1" + } + ] + } + ] + }, + "name": "cleanup_t_uint8", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "4848:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "cleaned", + "nodeType": "YulTypedName", + "src": "4858:7:1", + "type": "" + } + ], + "src": "4823:86:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4976:51:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "4993:3:1" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "5014:5:1" + } + ], + "functionName": { + "name": "cleanup_t_uint8", + "nodeType": "YulIdentifier", + "src": "4998:15:1" + }, + "nodeType": "YulFunctionCall", + "src": "4998:22:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "4986:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "4986:35:1" + }, + "nodeType": "YulExpressionStatement", + "src": "4986:35:1" + } + ] + }, + "name": "abi_encode_t_uint8_to_t_uint8_fromStack", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "4964:5:1", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "4971:3:1", + "type": "" + } + ], + "src": "4915:112:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5127:120:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "5137:26:1", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5149:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5160:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5145:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "5145:18:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "5137:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5213:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5226:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5237:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5222:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "5222:17:1" + } + ], + "functionName": { + "name": "abi_encode_t_uint8_to_t_uint8_fromStack", + "nodeType": "YulIdentifier", + "src": "5173:39:1" + }, + "nodeType": "YulFunctionCall", + "src": "5173:67:1" + }, + "nodeType": "YulExpressionStatement", + "src": "5173:67:1" + } + ] + }, + "name": "abi_encode_tuple_t_uint8__to_t_uint8__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5099:9:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5111:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "5122:4:1", + "type": "" + } + ], + "src": "5033:214:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5319:263:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "5365:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "nodeType": "YulIdentifier", + "src": "5367:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "5367:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "5367:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5340:7:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5349:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "5336:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "5336:23:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5361:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5332:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "5332:32:1" + }, + "nodeType": "YulIf", + "src": "5329:119:1" + }, + { + "nodeType": "YulBlock", + "src": "5458:117:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "5473:15:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5487:1:1", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "5477:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "5502:63:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5537:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "5548:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5533:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "5533:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5557:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_address", + "nodeType": "YulIdentifier", + "src": "5512:20:1" + }, + "nodeType": "YulFunctionCall", + "src": "5512:53:1" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5502:6:1" + } + ] + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5289:9:1", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "5300:7:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5312:6:1", + "type": "" + } + ], + "src": "5253:329:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5620:28:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "5630:12:1", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "5637:5:1" + }, + "variableNames": [ + { + "name": "ret", + "nodeType": "YulIdentifier", + "src": "5630:3:1" + } + ] + } + ] + }, + "name": "identity", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "5606:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "ret", + "nodeType": "YulTypedName", + "src": "5616:3:1", + "type": "" + } + ], + "src": "5588:60:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5714:82:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "5724:66:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "5782:5:1" + } + ], + "functionName": { + "name": "cleanup_t_uint160", + "nodeType": "YulIdentifier", + "src": "5764:17:1" + }, + "nodeType": "YulFunctionCall", + "src": "5764:24:1" + } + ], + "functionName": { + "name": "identity", + "nodeType": "YulIdentifier", + "src": "5755:8:1" + }, + "nodeType": "YulFunctionCall", + "src": "5755:34:1" + } + ], + "functionName": { + "name": "cleanup_t_uint160", + "nodeType": "YulIdentifier", + "src": "5737:17:1" + }, + "nodeType": "YulFunctionCall", + "src": "5737:53:1" + }, + "variableNames": [ + { + "name": "converted", + "nodeType": "YulIdentifier", + "src": "5724:9:1" + } + ] + } + ] + }, + "name": "convert_t_uint160_to_t_uint160", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "5694:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "converted", + "nodeType": "YulTypedName", + "src": "5704:9:1", + "type": "" + } + ], + "src": "5654:142:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5862:66:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "5872:50:1", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "5916:5:1" + } + ], + "functionName": { + "name": "convert_t_uint160_to_t_uint160", + "nodeType": "YulIdentifier", + "src": "5885:30:1" + }, + "nodeType": "YulFunctionCall", + "src": "5885:37:1" + }, + "variableNames": [ + { + "name": "converted", + "nodeType": "YulIdentifier", + "src": "5872:9:1" + } + ] + } + ] + }, + "name": "convert_t_uint160_to_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "5842:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "converted", + "nodeType": "YulTypedName", + "src": "5852:9:1", + "type": "" + } + ], + "src": "5802:126:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6025:66:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "6035:50:1", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "6079:5:1" + } + ], + "functionName": { + "name": "convert_t_uint160_to_t_address", + "nodeType": "YulIdentifier", + "src": "6048:30:1" + }, + "nodeType": "YulFunctionCall", + "src": "6048:37:1" + }, + "variableNames": [ + { + "name": "converted", + "nodeType": "YulIdentifier", + "src": "6035:9:1" + } + ] + } + ] + }, + "name": "convert_t_contract$_LocalAssetExtendedErc20_$181_to_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "6005:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "converted", + "nodeType": "YulTypedName", + "src": "6015:9:1", + "type": "" + } + ], + "src": "5934:157:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6193:97:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "6210:3:1" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "6277:5:1" + } + ], + "functionName": { + "name": "convert_t_contract$_LocalAssetExtendedErc20_$181_to_t_address", + "nodeType": "YulIdentifier", + "src": "6215:61:1" + }, + "nodeType": "YulFunctionCall", + "src": "6215:68:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6203:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "6203:81:1" + }, + "nodeType": "YulExpressionStatement", + "src": "6203:81:1" + } + ] + }, + "name": "abi_encode_t_contract$_LocalAssetExtendedErc20_$181_to_t_address_fromStack", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "6181:5:1", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "6188:3:1", + "type": "" + } + ], + "src": "6097:193:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6425:155:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "6435:26:1", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6447:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6458:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6443:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "6443:18:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "6435:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6546:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6559:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6570:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6555:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "6555:17:1" + } + ], + "functionName": { + "name": "abi_encode_t_contract$_LocalAssetExtendedErc20_$181_to_t_address_fromStack", + "nodeType": "YulIdentifier", + "src": "6471:74:1" + }, + "nodeType": "YulFunctionCall", + "src": "6471:102:1" + }, + "nodeType": "YulExpressionStatement", + "src": "6471:102:1" + } + ] + }, + "name": "abi_encode_tuple_t_contract$_LocalAssetExtendedErc20_$181__to_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "6397:9:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "6409:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "6420:4:1", + "type": "" + } + ], + "src": "6296:284:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6669:391:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "6715:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "nodeType": "YulIdentifier", + "src": "6717:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "6717:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "6717:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "6690:7:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6699:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "6686:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "6686:23:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6711:2:1", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "6682:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "6682:32:1" + }, + "nodeType": "YulIf", + "src": "6679:119:1" + }, + { + "nodeType": "YulBlock", + "src": "6808:117:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "6823:15:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6837:1:1", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "6827:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "6852:63:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6887:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "6898:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6883:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "6883:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "6907:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_address", + "nodeType": "YulIdentifier", + "src": "6862:20:1" + }, + "nodeType": "YulFunctionCall", + "src": "6862:53:1" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6852:6:1" + } + ] + } + ] + }, + { + "nodeType": "YulBlock", + "src": "6935:118:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "6950:16:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6964:2:1", + "type": "", + "value": "32" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "6954:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "6980:63:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7015:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "7026:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7011:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "7011:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "7035:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_address", + "nodeType": "YulIdentifier", + "src": "6990:20:1" + }, + "nodeType": "YulFunctionCall", + "src": "6990:53:1" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "6980:6:1" + } + ] + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_addresst_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "6631:9:1", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "6642:7:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "6654:6:1", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "6662:6:1", + "type": "" + } + ], + "src": "6586:474:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7155:28:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7172:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7175:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "7165:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "7165:12:1" + }, + "nodeType": "YulExpressionStatement", + "src": "7165:12:1" + } + ] + }, + "name": "revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d", + "nodeType": "YulFunctionDefinition", + "src": "7066:117:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7278:28:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7295:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7298:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "7288:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "7288:12:1" + }, + "nodeType": "YulExpressionStatement", + "src": "7288:12:1" + } + ] + }, + "name": "revert_error_15abf5612cd996bc235ba1e55a4a30ac60e6bb601ff7ba4ad3f179b6be8d0490", + "nodeType": "YulFunctionDefinition", + "src": "7189:117:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7401:28:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7418:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7421:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "7411:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "7411:12:1" + }, + "nodeType": "YulExpressionStatement", + "src": "7411:12:1" + } + ] + }, + "name": "revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef", + "nodeType": "YulFunctionDefinition", + "src": "7312:117:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7524:478:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "7573:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d", + "nodeType": "YulIdentifier", + "src": "7575:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "7575:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "7575:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "7552:6:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7560:4:1", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7548:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "7548:17:1" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "7567:3:1" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "7544:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "7544:27:1" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "7537:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "7537:35:1" + }, + "nodeType": "YulIf", + "src": "7534:122:1" + }, + { + "nodeType": "YulAssignment", + "src": "7665:30:1", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "7688:6:1" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "7675:12:1" + }, + "nodeType": "YulFunctionCall", + "src": "7675:20:1" + }, + "variableNames": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7665:6:1" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7738:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_15abf5612cd996bc235ba1e55a4a30ac60e6bb601ff7ba4ad3f179b6be8d0490", + "nodeType": "YulIdentifier", + "src": "7740:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "7740:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "7740:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7710:6:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7718:18:1", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "7707:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "7707:30:1" + }, + "nodeType": "YulIf", + "src": "7704:117:1" + }, + { + "nodeType": "YulAssignment", + "src": "7830:29:1", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "7846:6:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7854:4:1", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7842:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "7842:17:1" + }, + "variableNames": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "7830:8:1" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7913:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef", + "nodeType": "YulIdentifier", + "src": "7915:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "7915:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "7915:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "7878:8:1" + }, + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7892:6:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7900:4:1", + "type": "", + "value": "0x01" + } + ], + "functionName": { + "name": "mul", + "nodeType": "YulIdentifier", + "src": "7888:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "7888:17:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7874:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "7874:32:1" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "7908:3:1" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "7871:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "7871:41:1" + }, + "nodeType": "YulIf", + "src": "7868:128:1" + } + ] + }, + "name": "abi_decode_t_string_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "7491:6:1", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "7499:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "arrayPos", + "nodeType": "YulTypedName", + "src": "7507:8:1", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "7517:6:1", + "type": "" + } + ], + "src": "7449:553:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8049:77:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "8104:16:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8113:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8116:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "8106:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "8106:12:1" + }, + "nodeType": "YulExpressionStatement", + "src": "8106:12:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "8072:5:1" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "8095:5:1" + } + ], + "functionName": { + "name": "cleanup_t_uint8", + "nodeType": "YulIdentifier", + "src": "8079:15:1" + }, + "nodeType": "YulFunctionCall", + "src": "8079:22:1" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "8069:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "8069:33:1" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8062:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "8062:41:1" + }, + "nodeType": "YulIf", + "src": "8059:61:1" + } + ] + }, + "name": "validator_revert_t_uint8", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "8042:5:1", + "type": "" + } + ], + "src": "8008:118:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8182:85:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "8192:29:1", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "8214:6:1" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "8201:12:1" + }, + "nodeType": "YulFunctionCall", + "src": "8201:20:1" + }, + "variableNames": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "8192:5:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "8255:5:1" + } + ], + "functionName": { + "name": "validator_revert_t_uint8", + "nodeType": "YulIdentifier", + "src": "8230:24:1" + }, + "nodeType": "YulFunctionCall", + "src": "8230:31:1" + }, + "nodeType": "YulExpressionStatement", + "src": "8230:31:1" + } + ] + }, + "name": "abi_decode_t_uint8", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "8160:6:1", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "8168:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "8176:5:1", + "type": "" + } + ], + "src": "8132:135:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8411:877:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "8457:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "nodeType": "YulIdentifier", + "src": "8459:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "8459:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "8459:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "8432:7:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8441:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "8428:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "8428:23:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8453:2:1", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "8424:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "8424:32:1" + }, + "nodeType": "YulIf", + "src": "8421:119:1" + }, + { + "nodeType": "YulBlock", + "src": "8550:297:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "8565:45:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8596:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8607:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8592:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "8592:17:1" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "8579:12:1" + }, + "nodeType": "YulFunctionCall", + "src": "8579:31:1" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "8569:6:1", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8657:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db", + "nodeType": "YulIdentifier", + "src": "8659:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "8659:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "8659:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "8629:6:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8637:18:1", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "8626:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "8626:30:1" + }, + "nodeType": "YulIf", + "src": "8623:117:1" + }, + { + "nodeType": "YulAssignment", + "src": "8754:83:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8809:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "8820:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8805:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "8805:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "8829:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_string_calldata_ptr", + "nodeType": "YulIdentifier", + "src": "8772:32:1" + }, + "nodeType": "YulFunctionCall", + "src": "8772:65:1" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "8754:6:1" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "8762:6:1" + } + ] + } + ] + }, + { + "nodeType": "YulBlock", + "src": "8857:298:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "8872:46:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "8903:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8914:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8899:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "8899:18:1" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "8886:12:1" + }, + "nodeType": "YulFunctionCall", + "src": "8886:32:1" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "8876:6:1", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8965:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db", + "nodeType": "YulIdentifier", + "src": "8967:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "8967:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "8967:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "8937:6:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8945:18:1", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "8934:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "8934:30:1" + }, + "nodeType": "YulIf", + "src": "8931:117:1" + }, + { + "nodeType": "YulAssignment", + "src": "9062:83:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9117:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "9128:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9113:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "9113:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "9137:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_string_calldata_ptr", + "nodeType": "YulIdentifier", + "src": "9080:32:1" + }, + "nodeType": "YulFunctionCall", + "src": "9080:65:1" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "9062:6:1" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "9070:6:1" + } + ] + } + ] + }, + { + "nodeType": "YulBlock", + "src": "9165:116:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "9180:16:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9194:2:1", + "type": "", + "value": "64" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "9184:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "9210:61:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9243:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "9254:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9239:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "9239:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "9263:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_uint8", + "nodeType": "YulIdentifier", + "src": "9220:18:1" + }, + "nodeType": "YulFunctionCall", + "src": "9220:51:1" + }, + "variableNames": [ + { + "name": "value4", + "nodeType": "YulIdentifier", + "src": "9210:6:1" + } + ] + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_string_calldata_ptrt_string_calldata_ptrt_uint8", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "8349:9:1", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "8360:7:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "8372:6:1", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "8380:6:1", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "8388:6:1", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "8396:6:1", + "type": "" + }, + { + "name": "value4", + "nodeType": "YulTypedName", + "src": "8404:6:1", + "type": "" + } + ], + "src": "8273:1015:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9394:519:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "9440:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "nodeType": "YulIdentifier", + "src": "9442:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "9442:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "9442:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "9415:7:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9424:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "9411:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "9411:23:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9436:2:1", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "9407:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "9407:32:1" + }, + "nodeType": "YulIf", + "src": "9404:119:1" + }, + { + "nodeType": "YulBlock", + "src": "9533:117:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "9548:15:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9562:1:1", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "9552:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "9577:63:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9612:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "9623:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9608:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "9608:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "9632:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_address", + "nodeType": "YulIdentifier", + "src": "9587:20:1" + }, + "nodeType": "YulFunctionCall", + "src": "9587:53:1" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "9577:6:1" + } + ] + } + ] + }, + { + "nodeType": "YulBlock", + "src": "9660:118:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "9675:16:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9689:2:1", + "type": "", + "value": "32" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "9679:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "9705:63:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9740:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "9751:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9736:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "9736:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "9760:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_address", + "nodeType": "YulIdentifier", + "src": "9715:20:1" + }, + "nodeType": "YulFunctionCall", + "src": "9715:53:1" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "9705:6:1" + } + ] + } + ] + }, + { + "nodeType": "YulBlock", + "src": "9788:118:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "9803:16:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9817:2:1", + "type": "", + "value": "64" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "9807:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "9833:63:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "9868:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "9879:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9864:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "9864:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "9888:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_address", + "nodeType": "YulIdentifier", + "src": "9843:20:1" + }, + "nodeType": "YulFunctionCall", + "src": "9843:53:1" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "9833:6:1" + } + ] + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_addresst_addresst_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "9348:9:1", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "9359:7:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "9371:6:1", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "9379:6:1", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "9387:6:1", + "type": "" + } + ], + "src": "9294:619:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10008:28:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10025:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10028:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "10018:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "10018:12:1" + }, + "nodeType": "YulExpressionStatement", + "src": "10018:12:1" + } + ] + }, + "name": "revert_error_987264b3b1d58a9c7f8255e93e81c77d86d6299019c33110a076957a3e06e2ae", + "nodeType": "YulFunctionDefinition", + "src": "9919:117:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10070:152:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10087:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10090:77:1", + "type": "", + "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10080:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "10080:88:1" + }, + "nodeType": "YulExpressionStatement", + "src": "10080:88:1" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10184:1:1", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10187:4:1", + "type": "", + "value": "0x41" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10177:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "10177:15:1" + }, + "nodeType": "YulExpressionStatement", + "src": "10177:15:1" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10208:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10211:4:1", + "type": "", + "value": "0x24" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "10201:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "10201:15:1" + }, + "nodeType": "YulExpressionStatement", + "src": "10201:15:1" + } + ] + }, + "name": "panic_error_0x41", + "nodeType": "YulFunctionDefinition", + "src": "10042:180:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10271:238:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "10281:58:1", + "value": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "10303:6:1" + }, + { + "arguments": [ + { + "name": "size", + "nodeType": "YulIdentifier", + "src": "10333:4:1" + } + ], + "functionName": { + "name": "round_up_to_mul_of_32", + "nodeType": "YulIdentifier", + "src": "10311:21:1" + }, + "nodeType": "YulFunctionCall", + "src": "10311:27:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10299:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "10299:40:1" + }, + "variables": [ + { + "name": "newFreePtr", + "nodeType": "YulTypedName", + "src": "10285:10:1", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10450:22:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x41", + "nodeType": "YulIdentifier", + "src": "10452:16:1" + }, + "nodeType": "YulFunctionCall", + "src": "10452:18:1" + }, + "nodeType": "YulExpressionStatement", + "src": "10452:18:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "10393:10:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10405:18:1", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "10390:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "10390:34:1" + }, + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "10429:10:1" + }, + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "10441:6:1" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "10426:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "10426:22:1" + } + ], + "functionName": { + "name": "or", + "nodeType": "YulIdentifier", + "src": "10387:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "10387:62:1" + }, + "nodeType": "YulIf", + "src": "10384:88:1" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10488:2:1", + "type": "", + "value": "64" + }, + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "10492:10:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10481:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "10481:22:1" + }, + "nodeType": "YulExpressionStatement", + "src": "10481:22:1" + } + ] + }, + "name": "finalize_allocation", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "memPtr", + "nodeType": "YulTypedName", + "src": "10257:6:1", + "type": "" + }, + { + "name": "size", + "nodeType": "YulTypedName", + "src": "10265:4:1", + "type": "" + } + ], + "src": "10228:281:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10556:88:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "10566:30:1", + "value": { + "arguments": [], + "functionName": { + "name": "allocate_unbounded", + "nodeType": "YulIdentifier", + "src": "10576:18:1" + }, + "nodeType": "YulFunctionCall", + "src": "10576:20:1" + }, + "variableNames": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "10566:6:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "10625:6:1" + }, + { + "name": "size", + "nodeType": "YulIdentifier", + "src": "10633:4:1" + } + ], + "functionName": { + "name": "finalize_allocation", + "nodeType": "YulIdentifier", + "src": "10605:19:1" + }, + "nodeType": "YulFunctionCall", + "src": "10605:33:1" + }, + "nodeType": "YulExpressionStatement", + "src": "10605:33:1" + } + ] + }, + "name": "allocate_memory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "size", + "nodeType": "YulTypedName", + "src": "10540:4:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "memPtr", + "nodeType": "YulTypedName", + "src": "10549:6:1", + "type": "" + } + ], + "src": "10515:129:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10717:241:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "10822:22:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x41", + "nodeType": "YulIdentifier", + "src": "10824:16:1" + }, + "nodeType": "YulFunctionCall", + "src": "10824:18:1" + }, + "nodeType": "YulExpressionStatement", + "src": "10824:18:1" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "10794:6:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10802:18:1", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "10791:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "10791:30:1" + }, + "nodeType": "YulIf", + "src": "10788:56:1" + }, + { + "nodeType": "YulAssignment", + "src": "10854:37:1", + "value": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "10884:6:1" + } + ], + "functionName": { + "name": "round_up_to_mul_of_32", + "nodeType": "YulIdentifier", + "src": "10862:21:1" + }, + "nodeType": "YulFunctionCall", + "src": "10862:29:1" + }, + "variableNames": [ + { + "name": "size", + "nodeType": "YulIdentifier", + "src": "10854:4:1" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "10928:23:1", + "value": { + "arguments": [ + { + "name": "size", + "nodeType": "YulIdentifier", + "src": "10940:4:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10946:4:1", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10936:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "10936:15:1" + }, + "variableNames": [ + { + "name": "size", + "nodeType": "YulIdentifier", + "src": "10928:4:1" + } + ] + } + ] + }, + "name": "array_allocation_size_t_string_memory_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "10701:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "size", + "nodeType": "YulTypedName", + "src": "10712:4:1", + "type": "" + } + ], + "src": "10650:308:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11059:326:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "11069:75:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "11136:6:1" + } + ], + "functionName": { + "name": "array_allocation_size_t_string_memory_ptr", + "nodeType": "YulIdentifier", + "src": "11094:41:1" + }, + "nodeType": "YulFunctionCall", + "src": "11094:49:1" + } + ], + "functionName": { + "name": "allocate_memory", + "nodeType": "YulIdentifier", + "src": "11078:15:1" + }, + "nodeType": "YulFunctionCall", + "src": "11078:66:1" + }, + "variableNames": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "11069:5:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "11160:5:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "11167:6:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11153:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "11153:21:1" + }, + "nodeType": "YulExpressionStatement", + "src": "11153:21:1" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "11183:27:1", + "value": { + "arguments": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "11198:5:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11205:4:1", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11194:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "11194:16:1" + }, + "variables": [ + { + "name": "dst", + "nodeType": "YulTypedName", + "src": "11187:3:1", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11248:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_987264b3b1d58a9c7f8255e93e81c77d86d6299019c33110a076957a3e06e2ae", + "nodeType": "YulIdentifier", + "src": "11250:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "11250:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "11250:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "11229:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "11234:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11225:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "11225:16:1" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "11243:3:1" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "11222:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "11222:25:1" + }, + "nodeType": "YulIf", + "src": "11219:112:1" + }, + { + "expression": { + "arguments": [ + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "11362:3:1" + }, + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "11367:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "11372:6:1" + } + ], + "functionName": { + "name": "copy_memory_to_memory", + "nodeType": "YulIdentifier", + "src": "11340:21:1" + }, + "nodeType": "YulFunctionCall", + "src": "11340:39:1" + }, + "nodeType": "YulExpressionStatement", + "src": "11340:39:1" + } + ] + }, + "name": "abi_decode_available_length_t_string_memory_ptr_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "src", + "nodeType": "YulTypedName", + "src": "11032:3:1", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "11037:6:1", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "11045:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "array", + "nodeType": "YulTypedName", + "src": "11053:5:1", + "type": "" + } + ], + "src": "10964:421:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11478:282:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "11527:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d", + "nodeType": "YulIdentifier", + "src": "11529:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "11529:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "11529:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "11506:6:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11514:4:1", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11502:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "11502:17:1" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "11521:3:1" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "11498:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "11498:27:1" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "11491:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "11491:35:1" + }, + "nodeType": "YulIf", + "src": "11488:122:1" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "11619:27:1", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "11639:6:1" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "11633:5:1" + }, + "nodeType": "YulFunctionCall", + "src": "11633:13:1" + }, + "variables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "11623:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "11655:99:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "11727:6:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11735:4:1", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11723:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "11723:17:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "11742:6:1" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "11750:3:1" + } + ], + "functionName": { + "name": "abi_decode_available_length_t_string_memory_ptr_fromMemory", + "nodeType": "YulIdentifier", + "src": "11664:58:1" + }, + "nodeType": "YulFunctionCall", + "src": "11664:90:1" + }, + "variableNames": [ + { + "name": "array", + "nodeType": "YulIdentifier", + "src": "11655:5:1" + } + ] + } + ] + }, + "name": "abi_decode_t_string_memory_ptr_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "11456:6:1", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "11464:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "array", + "nodeType": "YulTypedName", + "src": "11472:5:1", + "type": "" + } + ], + "src": "11405:355:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11853:437:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "11899:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "nodeType": "YulIdentifier", + "src": "11901:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "11901:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "11901:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "11874:7:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11883:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "11870:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "11870:23:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11895:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "11866:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "11866:32:1" + }, + "nodeType": "YulIf", + "src": "11863:119:1" + }, + { + "nodeType": "YulBlock", + "src": "11992:291:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "12007:38:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12031:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12042:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12027:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "12027:17:1" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "12021:5:1" + }, + "nodeType": "YulFunctionCall", + "src": "12021:24:1" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "12011:6:1", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12092:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db", + "nodeType": "YulIdentifier", + "src": "12094:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "12094:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "12094:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "12064:6:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12072:18:1", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "12061:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "12061:30:1" + }, + "nodeType": "YulIf", + "src": "12058:117:1" + }, + { + "nodeType": "YulAssignment", + "src": "12189:84:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12245:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "12256:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12241:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "12241:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "12265:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_string_memory_ptr_fromMemory", + "nodeType": "YulIdentifier", + "src": "12199:41:1" + }, + "nodeType": "YulFunctionCall", + "src": "12199:74:1" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "12189:6:1" + } + ] + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_string_memory_ptr_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "11823:9:1", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "11834:7:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "11846:6:1", + "type": "" + } + ], + "src": "11766:524:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12422:206:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "12432:26:1", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12444:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12455:2:1", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12440:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "12440:18:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "12432:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "12512:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12525:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12536:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12521:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "12521:17:1" + } + ], + "functionName": { + "name": "abi_encode_t_address_to_t_address_fromStack", + "nodeType": "YulIdentifier", + "src": "12468:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "12468:71:1" + }, + "nodeType": "YulExpressionStatement", + "src": "12468:71:1" + }, + { + "expression": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "12593:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12606:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12617:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12602:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "12602:18:1" + } + ], + "functionName": { + "name": "abi_encode_t_uint256_to_t_uint256_fromStack", + "nodeType": "YulIdentifier", + "src": "12549:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "12549:72:1" + }, + "nodeType": "YulExpressionStatement", + "src": "12549:72:1" + } + ] + }, + "name": "abi_encode_tuple_t_address_t_uint256__to_t_address_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "12386:9:1", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "12398:6:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "12406:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "12417:4:1", + "type": "" + } + ], + "src": "12296:332:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12674:76:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "12728:16:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12737:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12740:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "12730:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "12730:12:1" + }, + "nodeType": "YulExpressionStatement", + "src": "12730:12:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "12697:5:1" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "12719:5:1" + } + ], + "functionName": { + "name": "cleanup_t_bool", + "nodeType": "YulIdentifier", + "src": "12704:14:1" + }, + "nodeType": "YulFunctionCall", + "src": "12704:21:1" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "12694:2:1" + }, + "nodeType": "YulFunctionCall", + "src": "12694:32:1" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "12687:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "12687:40:1" + }, + "nodeType": "YulIf", + "src": "12684:60:1" + } + ] + }, + "name": "validator_revert_t_bool", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "12667:5:1", + "type": "" + } + ], + "src": "12634:116:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12816:77:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "12826:22:1", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "12841:6:1" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "12835:5:1" + }, + "nodeType": "YulFunctionCall", + "src": "12835:13:1" + }, + "variableNames": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "12826:5:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "12881:5:1" + } + ], + "functionName": { + "name": "validator_revert_t_bool", + "nodeType": "YulIdentifier", + "src": "12857:23:1" + }, + "nodeType": "YulFunctionCall", + "src": "12857:30:1" + }, + "nodeType": "YulExpressionStatement", + "src": "12857:30:1" + } + ] + }, + "name": "abi_decode_t_bool_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "12794:6:1", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "12802:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "12810:5:1", + "type": "" + } + ], + "src": "12756:137:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12973:271:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "13019:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "nodeType": "YulIdentifier", + "src": "13021:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "13021:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "13021:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "12994:7:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13003:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "12990:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "12990:23:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13015:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "12986:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "12986:32:1" + }, + "nodeType": "YulIf", + "src": "12983:119:1" + }, + { + "nodeType": "YulBlock", + "src": "13112:125:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "13127:15:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13141:1:1", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "13131:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "13156:71:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13199:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "13210:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13195:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "13195:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "13219:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_bool_fromMemory", + "nodeType": "YulIdentifier", + "src": "13166:28:1" + }, + "nodeType": "YulFunctionCall", + "src": "13166:61:1" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "13156:6:1" + } + ] + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bool_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "12943:9:1", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "12954:7:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "12966:6:1", + "type": "" + } + ], + "src": "12899:345:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13313:80:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "13323:22:1", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "13338:6:1" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "13332:5:1" + }, + "nodeType": "YulFunctionCall", + "src": "13332:13:1" + }, + "variableNames": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "13323:5:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "13381:5:1" + } + ], + "functionName": { + "name": "validator_revert_t_uint256", + "nodeType": "YulIdentifier", + "src": "13354:26:1" + }, + "nodeType": "YulFunctionCall", + "src": "13354:33:1" + }, + "nodeType": "YulExpressionStatement", + "src": "13354:33:1" + } + ] + }, + "name": "abi_decode_t_uint256_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "13291:6:1", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "13299:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "13307:5:1", + "type": "" + } + ], + "src": "13250:143:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13476:274:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "13522:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "nodeType": "YulIdentifier", + "src": "13524:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "13524:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "13524:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "13497:7:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13506:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "13493:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "13493:23:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13518:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "13489:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "13489:32:1" + }, + "nodeType": "YulIf", + "src": "13486:119:1" + }, + { + "nodeType": "YulBlock", + "src": "13615:128:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "13630:15:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13644:1:1", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "13634:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "13659:74:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13705:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "13716:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13701:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "13701:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "13725:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_uint256_fromMemory", + "nodeType": "YulIdentifier", + "src": "13669:31:1" + }, + "nodeType": "YulFunctionCall", + "src": "13669:64:1" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "13659:6:1" + } + ] + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "13446:9:1", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "13457:7:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "13469:6:1", + "type": "" + } + ], + "src": "13399:351:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13910:288:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "13920:26:1", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13932:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13943:2:1", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13928:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "13928:18:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "13920:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "14000:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14013:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14024:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14009:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "14009:17:1" + } + ], + "functionName": { + "name": "abi_encode_t_address_to_t_address_fromStack", + "nodeType": "YulIdentifier", + "src": "13956:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "13956:71:1" + }, + "nodeType": "YulExpressionStatement", + "src": "13956:71:1" + }, + { + "expression": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "14081:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14094:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14105:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14090:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "14090:18:1" + } + ], + "functionName": { + "name": "abi_encode_t_address_to_t_address_fromStack", + "nodeType": "YulIdentifier", + "src": "14037:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "14037:72:1" + }, + "nodeType": "YulExpressionStatement", + "src": "14037:72:1" + }, + { + "expression": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "14163:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14176:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14187:2:1", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14172:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "14172:18:1" + } + ], + "functionName": { + "name": "abi_encode_t_uint256_to_t_uint256_fromStack", + "nodeType": "YulIdentifier", + "src": "14119:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "14119:72:1" + }, + "nodeType": "YulExpressionStatement", + "src": "14119:72:1" + } + ] + }, + "name": "abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "13866:9:1", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "13878:6:1", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "13886:6:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "13894:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "13905:4:1", + "type": "" + } + ], + "src": "13756:442:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14265:78:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "14275:22:1", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "14290:6:1" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "14284:5:1" + }, + "nodeType": "YulFunctionCall", + "src": "14284:13:1" + }, + "variableNames": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "14275:5:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "14331:5:1" + } + ], + "functionName": { + "name": "validator_revert_t_uint8", + "nodeType": "YulIdentifier", + "src": "14306:24:1" + }, + "nodeType": "YulFunctionCall", + "src": "14306:31:1" + }, + "nodeType": "YulExpressionStatement", + "src": "14306:31:1" + } + ] + }, + "name": "abi_decode_t_uint8_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "14243:6:1", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "14251:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "14259:5:1", + "type": "" + } + ], + "src": "14204:139:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14424:272:1", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "14470:83:1", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b", + "nodeType": "YulIdentifier", + "src": "14472:77:1" + }, + "nodeType": "YulFunctionCall", + "src": "14472:79:1" + }, + "nodeType": "YulExpressionStatement", + "src": "14472:79:1" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "14445:7:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14454:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "14441:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "14441:23:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14466:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "14437:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "14437:32:1" + }, + "nodeType": "YulIf", + "src": "14434:119:1" + }, + { + "nodeType": "YulBlock", + "src": "14563:126:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "14578:15:1", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14592:1:1", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "14582:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "14607:72:1", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14651:9:1" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "14662:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14647:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "14647:22:1" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "14671:7:1" + } + ], + "functionName": { + "name": "abi_decode_t_uint8_fromMemory", + "nodeType": "YulIdentifier", + "src": "14617:29:1" + }, + "nodeType": "YulFunctionCall", + "src": "14617:62:1" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "14607:6:1" + } + ] + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint8_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "14394:9:1", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "14405:7:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "14417:6:1", + "type": "" + } + ], + "src": "14349:347:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14760:40:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "14771:22:1", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "14787:5:1" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "14781:5:1" + }, + "nodeType": "YulFunctionCall", + "src": "14781:12:1" + }, + "variableNames": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "14771:6:1" + } + ] + } + ] + }, + "name": "array_length_t_bytes_memory_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "14743:5:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "14753:6:1", + "type": "" + } + ], + "src": "14702:98:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14919:34:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "14929:18:1", + "value": { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "14944:3:1" + }, + "variableNames": [ + { + "name": "updated_pos", + "nodeType": "YulIdentifier", + "src": "14929:11:1" + } + ] + } + ] + }, + "name": "array_storeLengthForEncoding_t_bytes_memory_ptr_nonPadded_inplace_fromStack", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "14891:3:1", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "14896:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "updated_pos", + "nodeType": "YulTypedName", + "src": "14907:11:1", + "type": "" + } + ], + "src": "14806:147:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15067:265:1", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "15077:52:1", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "15123:5:1" + } + ], + "functionName": { + "name": "array_length_t_bytes_memory_ptr", + "nodeType": "YulIdentifier", + "src": "15091:31:1" + }, + "nodeType": "YulFunctionCall", + "src": "15091:38:1" + }, + "variables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "15081:6:1", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "15138:95:1", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "15221:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "15226:6:1" + } + ], + "functionName": { + "name": "array_storeLengthForEncoding_t_bytes_memory_ptr_nonPadded_inplace_fromStack", + "nodeType": "YulIdentifier", + "src": "15145:75:1" + }, + "nodeType": "YulFunctionCall", + "src": "15145:88:1" + }, + "variableNames": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "15138:3:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "15268:5:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15275:4:1", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15264:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "15264:16:1" + }, + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "15282:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "15287:6:1" + } + ], + "functionName": { + "name": "copy_memory_to_memory", + "nodeType": "YulIdentifier", + "src": "15242:21:1" + }, + "nodeType": "YulFunctionCall", + "src": "15242:52:1" + }, + "nodeType": "YulExpressionStatement", + "src": "15242:52:1" + }, + { + "nodeType": "YulAssignment", + "src": "15303:23:1", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "15314:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "15319:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15310:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "15310:16:1" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "15303:3:1" + } + ] + } + ] + }, + "name": "abi_encode_t_bytes_memory_ptr_to_t_bytes_memory_ptr_nonPadded_inplace_fromStack", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "15048:5:1", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "15055:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "15063:3:1", + "type": "" + } + ], + "src": "14959:373:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15472:137:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "15483:100:1", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "15570:6:1" + }, + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "15579:3:1" + } + ], + "functionName": { + "name": "abi_encode_t_bytes_memory_ptr_to_t_bytes_memory_ptr_nonPadded_inplace_fromStack", + "nodeType": "YulIdentifier", + "src": "15490:79:1" + }, + "nodeType": "YulFunctionCall", + "src": "15490:93:1" + }, + "variableNames": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "15483:3:1" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "15593:10:1", + "value": { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "15600:3:1" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "15593:3:1" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_bytes_memory_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "15451:3:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "15457:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "15468:3:1", + "type": "" + } + ], + "src": "15338:271:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15741:206:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "15751:26:1", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15763:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15774:2:1", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15759:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "15759:18:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "15751:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "15831:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15844:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15855:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15840:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "15840:17:1" + } + ], + "functionName": { + "name": "abi_encode_t_address_to_t_address_fromStack", + "nodeType": "YulIdentifier", + "src": "15787:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "15787:71:1" + }, + "nodeType": "YulExpressionStatement", + "src": "15787:71:1" + }, + { + "expression": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "15912:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15925:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15936:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15921:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "15921:18:1" + } + ], + "functionName": { + "name": "abi_encode_t_address_to_t_address_fromStack", + "nodeType": "YulIdentifier", + "src": "15868:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "15868:72:1" + }, + "nodeType": "YulExpressionStatement", + "src": "15868:72:1" + } + ] + }, + "name": "abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "15705:9:1", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "15717:6:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "15725:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "15736:4:1", + "type": "" + } + ], + "src": "15615:332:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16004:103:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "16027:3:1" + }, + { + "name": "src", + "nodeType": "YulIdentifier", + "src": "16032:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "16037:6:1" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "16014:12:1" + }, + "nodeType": "YulFunctionCall", + "src": "16014:30:1" + }, + "nodeType": "YulExpressionStatement", + "src": "16014:30:1" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "dst", + "nodeType": "YulIdentifier", + "src": "16085:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "16090:6:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16081:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "16081:16:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16099:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16074:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "16074:27:1" + }, + "nodeType": "YulExpressionStatement", + "src": "16074:27:1" + } + ] + }, + "name": "copy_calldata_to_memory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "src", + "nodeType": "YulTypedName", + "src": "15986:3:1", + "type": "" + }, + { + "name": "dst", + "nodeType": "YulTypedName", + "src": "15991:3:1", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "15996:6:1", + "type": "" + } + ], + "src": "15953:154:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16239:202:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "16249:78:1", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "16315:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "16320:6:1" + } + ], + "functionName": { + "name": "array_storeLengthForEncoding_t_string_memory_ptr_fromStack", + "nodeType": "YulIdentifier", + "src": "16256:58:1" + }, + "nodeType": "YulFunctionCall", + "src": "16256:71:1" + }, + "variableNames": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "16249:3:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "start", + "nodeType": "YulIdentifier", + "src": "16361:5:1" + }, + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "16368:3:1" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "16373:6:1" + } + ], + "functionName": { + "name": "copy_calldata_to_memory", + "nodeType": "YulIdentifier", + "src": "16337:23:1" + }, + "nodeType": "YulFunctionCall", + "src": "16337:43:1" + }, + "nodeType": "YulExpressionStatement", + "src": "16337:43:1" + }, + { + "nodeType": "YulAssignment", + "src": "16389:46:1", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "16400:3:1" + }, + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "16427:6:1" + } + ], + "functionName": { + "name": "round_up_to_mul_of_32", + "nodeType": "YulIdentifier", + "src": "16405:21:1" + }, + "nodeType": "YulFunctionCall", + "src": "16405:29:1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16396:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "16396:39:1" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "16389:3:1" + } + ] + } + ] + }, + "name": "abi_encode_t_string_calldata_ptr_to_t_string_memory_ptr_fromStack", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "start", + "nodeType": "YulTypedName", + "src": "16212:5:1", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "16219:6:1", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "16227:3:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "16235:3:1", + "type": "" + } + ], + "src": "16137:304:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16657:446:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "16667:26:1", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16679:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16690:2:1", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16675:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "16675:18:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16667:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16714:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16725:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16710:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "16710:17:1" + }, + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16733:4:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16739:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "16729:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "16729:20:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16703:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "16703:47:1" + }, + "nodeType": "YulExpressionStatement", + "src": "16703:47:1" + }, + { + "nodeType": "YulAssignment", + "src": "16759:96:1", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "16833:6:1" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "16841:6:1" + }, + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16850:4:1" + } + ], + "functionName": { + "name": "abi_encode_t_string_calldata_ptr_to_t_string_memory_ptr_fromStack", + "nodeType": "YulIdentifier", + "src": "16767:65:1" + }, + "nodeType": "YulFunctionCall", + "src": "16767:88:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16759:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16876:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16887:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16872:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "16872:18:1" + }, + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16896:4:1" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16902:9:1" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "16892:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "16892:20:1" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16865:6:1" + }, + "nodeType": "YulFunctionCall", + "src": "16865:48:1" + }, + "nodeType": "YulExpressionStatement", + "src": "16865:48:1" + }, + { + "nodeType": "YulAssignment", + "src": "16922:96:1", + "value": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "16996:6:1" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "17004:6:1" + }, + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "17013:4:1" + } + ], + "functionName": { + "name": "abi_encode_t_string_calldata_ptr_to_t_string_memory_ptr_fromStack", + "nodeType": "YulIdentifier", + "src": "16930:65:1" + }, + "nodeType": "YulFunctionCall", + "src": "16930:88:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16922:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value4", + "nodeType": "YulIdentifier", + "src": "17068:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17081:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17092:2:1", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17077:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "17077:18:1" + } + ], + "functionName": { + "name": "abi_encode_t_uint8_to_t_uint8_fromStack", + "nodeType": "YulIdentifier", + "src": "17028:39:1" + }, + "nodeType": "YulFunctionCall", + "src": "17028:68:1" + }, + "nodeType": "YulExpressionStatement", + "src": "17028:68:1" + } + ] + }, + "name": "abi_encode_tuple_t_string_calldata_ptr_t_string_calldata_ptr_t_uint8__to_t_string_memory_ptr_t_string_memory_ptr_t_uint8__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16597:9:1", + "type": "" + }, + { + "name": "value4", + "nodeType": "YulTypedName", + "src": "16609:6:1", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "16617:6:1", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "16625:6:1", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16633:6:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16641:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16652:4:1", + "type": "" + } + ], + "src": "16447:656:1" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17263:288:1", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "17273:26:1", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17285:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17296:2:1", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17281:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "17281:18:1" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "17273:4:1" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "17353:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17366:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17377:1:1", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17362:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "17362:17:1" + } + ], + "functionName": { + "name": "abi_encode_t_address_to_t_address_fromStack", + "nodeType": "YulIdentifier", + "src": "17309:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "17309:71:1" + }, + "nodeType": "YulExpressionStatement", + "src": "17309:71:1" + }, + { + "expression": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "17434:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17447:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17458:2:1", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17443:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "17443:18:1" + } + ], + "functionName": { + "name": "abi_encode_t_address_to_t_address_fromStack", + "nodeType": "YulIdentifier", + "src": "17390:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "17390:72:1" + }, + "nodeType": "YulExpressionStatement", + "src": "17390:72:1" + }, + { + "expression": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "17516:6:1" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17529:9:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17540:2:1", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17525:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "17525:18:1" + } + ], + "functionName": { + "name": "abi_encode_t_address_to_t_address_fromStack", + "nodeType": "YulIdentifier", + "src": "17472:43:1" + }, + "nodeType": "YulFunctionCall", + "src": "17472:72:1" + }, + "nodeType": "YulExpressionStatement", + "src": "17472:72:1" + } + ] + }, + "name": "abi_encode_tuple_t_address_t_address_t_address__to_t_address_t_address_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "17219:9:1", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "17231:6:1", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "17239:6:1", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "17247:6:1", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "17258:4:1", + "type": "" + } + ], + "src": "17109:442:1" + } + ] + }, + "contents": "{\n\n function cleanup_t_uint160(value) -> cleaned {\n cleaned := and(value, 0xffffffffffffffffffffffffffffffffffffffff)\n }\n\n function cleanup_t_address(value) -> cleaned {\n cleaned := cleanup_t_uint160(value)\n }\n\n function abi_encode_t_address_to_t_address_fromStack(value, pos) {\n mstore(pos, cleanup_t_address(value))\n }\n\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart , value0) -> tail {\n tail := add(headStart, 32)\n\n abi_encode_t_address_to_t_address_fromStack(value0, add(headStart, 0))\n\n }\n\n function array_length_t_string_memory_ptr(value) -> length {\n\n length := mload(value)\n\n }\n\n function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos {\n mstore(pos, length)\n updated_pos := add(pos, 0x20)\n }\n\n function copy_memory_to_memory(src, dst, length) {\n let i := 0\n for { } lt(i, length) { i := add(i, 32) }\n {\n mstore(add(dst, i), mload(add(src, i)))\n }\n if gt(i, length)\n {\n // clear end\n mstore(add(dst, length), 0)\n }\n }\n\n function round_up_to_mul_of_32(value) -> result {\n result := and(add(value, 31), not(31))\n }\n\n function abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value, pos) -> end {\n let length := array_length_t_string_memory_ptr(value)\n pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length)\n copy_memory_to_memory(add(value, 0x20), pos, length)\n end := add(pos, round_up_to_mul_of_32(length))\n }\n\n function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed(headStart , value0) -> tail {\n tail := add(headStart, 32)\n\n mstore(add(headStart, 0), sub(tail, headStart))\n tail := abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value0, tail)\n\n }\n\n function allocate_unbounded() -> memPtr {\n memPtr := mload(64)\n }\n\n function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n revert(0, 0)\n }\n\n function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n revert(0, 0)\n }\n\n function validator_revert_t_address(value) {\n if iszero(eq(value, cleanup_t_address(value))) { revert(0, 0) }\n }\n\n function abi_decode_t_address(offset, end) -> value {\n value := calldataload(offset)\n validator_revert_t_address(value)\n }\n\n function cleanup_t_uint256(value) -> cleaned {\n cleaned := value\n }\n\n function validator_revert_t_uint256(value) {\n if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n }\n\n function abi_decode_t_uint256(offset, end) -> value {\n value := calldataload(offset)\n validator_revert_t_uint256(value)\n }\n\n function abi_decode_tuple_t_addresst_uint256(headStart, dataEnd) -> value0, value1 {\n if slt(sub(dataEnd, headStart), 64) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n {\n\n let offset := 0\n\n value0 := abi_decode_t_address(add(headStart, offset), dataEnd)\n }\n\n {\n\n let offset := 32\n\n value1 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n }\n\n }\n\n function cleanup_t_bool(value) -> cleaned {\n cleaned := iszero(iszero(value))\n }\n\n function abi_encode_t_bool_to_t_bool_fromStack(value, pos) {\n mstore(pos, cleanup_t_bool(value))\n }\n\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart , value0) -> tail {\n tail := add(headStart, 32)\n\n abi_encode_t_bool_to_t_bool_fromStack(value0, add(headStart, 0))\n\n }\n\n function abi_encode_t_uint256_to_t_uint256_fromStack(value, pos) {\n mstore(pos, cleanup_t_uint256(value))\n }\n\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart , value0) -> tail {\n tail := add(headStart, 32)\n\n abi_encode_t_uint256_to_t_uint256_fromStack(value0, add(headStart, 0))\n\n }\n\n function abi_decode_tuple_t_addresst_addresst_uint256(headStart, dataEnd) -> value0, value1, value2 {\n if slt(sub(dataEnd, headStart), 96) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n {\n\n let offset := 0\n\n value0 := abi_decode_t_address(add(headStart, offset), dataEnd)\n }\n\n {\n\n let offset := 32\n\n value1 := abi_decode_t_address(add(headStart, offset), dataEnd)\n }\n\n {\n\n let offset := 64\n\n value2 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n }\n\n }\n\n function cleanup_t_uint8(value) -> cleaned {\n cleaned := and(value, 0xff)\n }\n\n function abi_encode_t_uint8_to_t_uint8_fromStack(value, pos) {\n mstore(pos, cleanup_t_uint8(value))\n }\n\n function abi_encode_tuple_t_uint8__to_t_uint8__fromStack_reversed(headStart , value0) -> tail {\n tail := add(headStart, 32)\n\n abi_encode_t_uint8_to_t_uint8_fromStack(value0, add(headStart, 0))\n\n }\n\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0 {\n if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n {\n\n let offset := 0\n\n value0 := abi_decode_t_address(add(headStart, offset), dataEnd)\n }\n\n }\n\n function identity(value) -> ret {\n ret := value\n }\n\n function convert_t_uint160_to_t_uint160(value) -> converted {\n converted := cleanup_t_uint160(identity(cleanup_t_uint160(value)))\n }\n\n function convert_t_uint160_to_t_address(value) -> converted {\n converted := convert_t_uint160_to_t_uint160(value)\n }\n\n function convert_t_contract$_LocalAssetExtendedErc20_$181_to_t_address(value) -> converted {\n converted := convert_t_uint160_to_t_address(value)\n }\n\n function abi_encode_t_contract$_LocalAssetExtendedErc20_$181_to_t_address_fromStack(value, pos) {\n mstore(pos, convert_t_contract$_LocalAssetExtendedErc20_$181_to_t_address(value))\n }\n\n function abi_encode_tuple_t_contract$_LocalAssetExtendedErc20_$181__to_t_address__fromStack_reversed(headStart , value0) -> tail {\n tail := add(headStart, 32)\n\n abi_encode_t_contract$_LocalAssetExtendedErc20_$181_to_t_address_fromStack(value0, add(headStart, 0))\n\n }\n\n function abi_decode_tuple_t_addresst_address(headStart, dataEnd) -> value0, value1 {\n if slt(sub(dataEnd, headStart), 64) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n {\n\n let offset := 0\n\n value0 := abi_decode_t_address(add(headStart, offset), dataEnd)\n }\n\n {\n\n let offset := 32\n\n value1 := abi_decode_t_address(add(headStart, offset), dataEnd)\n }\n\n }\n\n function revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() {\n revert(0, 0)\n }\n\n function revert_error_15abf5612cd996bc235ba1e55a4a30ac60e6bb601ff7ba4ad3f179b6be8d0490() {\n revert(0, 0)\n }\n\n function revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef() {\n revert(0, 0)\n }\n\n // string\n function abi_decode_t_string_calldata_ptr(offset, end) -> arrayPos, length {\n if iszero(slt(add(offset, 0x1f), end)) { revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert_error_15abf5612cd996bc235ba1e55a4a30ac60e6bb601ff7ba4ad3f179b6be8d0490() }\n arrayPos := add(offset, 0x20)\n if gt(add(arrayPos, mul(length, 0x01)), end) { revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef() }\n }\n\n function validator_revert_t_uint8(value) {\n if iszero(eq(value, cleanup_t_uint8(value))) { revert(0, 0) }\n }\n\n function abi_decode_t_uint8(offset, end) -> value {\n value := calldataload(offset)\n validator_revert_t_uint8(value)\n }\n\n function abi_decode_tuple_t_string_calldata_ptrt_string_calldata_ptrt_uint8(headStart, dataEnd) -> value0, value1, value2, value3, value4 {\n if slt(sub(dataEnd, headStart), 96) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n {\n\n let offset := calldataload(add(headStart, 0))\n if gt(offset, 0xffffffffffffffff) { revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() }\n\n value0, value1 := abi_decode_t_string_calldata_ptr(add(headStart, offset), dataEnd)\n }\n\n {\n\n let offset := calldataload(add(headStart, 32))\n if gt(offset, 0xffffffffffffffff) { revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() }\n\n value2, value3 := abi_decode_t_string_calldata_ptr(add(headStart, offset), dataEnd)\n }\n\n {\n\n let offset := 64\n\n value4 := abi_decode_t_uint8(add(headStart, offset), dataEnd)\n }\n\n }\n\n function abi_decode_tuple_t_addresst_addresst_address(headStart, dataEnd) -> value0, value1, value2 {\n if slt(sub(dataEnd, headStart), 96) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n {\n\n let offset := 0\n\n value0 := abi_decode_t_address(add(headStart, offset), dataEnd)\n }\n\n {\n\n let offset := 32\n\n value1 := abi_decode_t_address(add(headStart, offset), dataEnd)\n }\n\n {\n\n let offset := 64\n\n value2 := abi_decode_t_address(add(headStart, offset), dataEnd)\n }\n\n }\n\n function revert_error_987264b3b1d58a9c7f8255e93e81c77d86d6299019c33110a076957a3e06e2ae() {\n revert(0, 0)\n }\n\n function panic_error_0x41() {\n mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n\n function finalize_allocation(memPtr, size) {\n let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n // protect against overflow\n if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n }\n\n function allocate_memory(size) -> memPtr {\n memPtr := allocate_unbounded()\n finalize_allocation(memPtr, size)\n }\n\n function array_allocation_size_t_string_memory_ptr(length) -> size {\n // Make sure we can allocate memory without overflow\n if gt(length, 0xffffffffffffffff) { panic_error_0x41() }\n\n size := round_up_to_mul_of_32(length)\n\n // add length slot\n size := add(size, 0x20)\n\n }\n\n function abi_decode_available_length_t_string_memory_ptr_fromMemory(src, length, end) -> array {\n array := allocate_memory(array_allocation_size_t_string_memory_ptr(length))\n mstore(array, length)\n let dst := add(array, 0x20)\n if gt(add(src, length), end) { revert_error_987264b3b1d58a9c7f8255e93e81c77d86d6299019c33110a076957a3e06e2ae() }\n copy_memory_to_memory(src, dst, length)\n }\n\n // string\n function abi_decode_t_string_memory_ptr_fromMemory(offset, end) -> array {\n if iszero(slt(add(offset, 0x1f), end)) { revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() }\n let length := mload(offset)\n array := abi_decode_available_length_t_string_memory_ptr_fromMemory(add(offset, 0x20), length, end)\n }\n\n function abi_decode_tuple_t_string_memory_ptr_fromMemory(headStart, dataEnd) -> value0 {\n if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n {\n\n let offset := mload(add(headStart, 0))\n if gt(offset, 0xffffffffffffffff) { revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() }\n\n value0 := abi_decode_t_string_memory_ptr_fromMemory(add(headStart, offset), dataEnd)\n }\n\n }\n\n function abi_encode_tuple_t_address_t_uint256__to_t_address_t_uint256__fromStack_reversed(headStart , value1, value0) -> tail {\n tail := add(headStart, 64)\n\n abi_encode_t_address_to_t_address_fromStack(value0, add(headStart, 0))\n\n abi_encode_t_uint256_to_t_uint256_fromStack(value1, add(headStart, 32))\n\n }\n\n function validator_revert_t_bool(value) {\n if iszero(eq(value, cleanup_t_bool(value))) { revert(0, 0) }\n }\n\n function abi_decode_t_bool_fromMemory(offset, end) -> value {\n value := mload(offset)\n validator_revert_t_bool(value)\n }\n\n function abi_decode_tuple_t_bool_fromMemory(headStart, dataEnd) -> value0 {\n if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n {\n\n let offset := 0\n\n value0 := abi_decode_t_bool_fromMemory(add(headStart, offset), dataEnd)\n }\n\n }\n\n function abi_decode_t_uint256_fromMemory(offset, end) -> value {\n value := mload(offset)\n validator_revert_t_uint256(value)\n }\n\n function abi_decode_tuple_t_uint256_fromMemory(headStart, dataEnd) -> value0 {\n if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n {\n\n let offset := 0\n\n value0 := abi_decode_t_uint256_fromMemory(add(headStart, offset), dataEnd)\n }\n\n }\n\n function abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed(headStart , value2, value1, value0) -> tail {\n tail := add(headStart, 96)\n\n abi_encode_t_address_to_t_address_fromStack(value0, add(headStart, 0))\n\n abi_encode_t_address_to_t_address_fromStack(value1, add(headStart, 32))\n\n abi_encode_t_uint256_to_t_uint256_fromStack(value2, add(headStart, 64))\n\n }\n\n function abi_decode_t_uint8_fromMemory(offset, end) -> value {\n value := mload(offset)\n validator_revert_t_uint8(value)\n }\n\n function abi_decode_tuple_t_uint8_fromMemory(headStart, dataEnd) -> value0 {\n if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n {\n\n let offset := 0\n\n value0 := abi_decode_t_uint8_fromMemory(add(headStart, offset), dataEnd)\n }\n\n }\n\n function array_length_t_bytes_memory_ptr(value) -> length {\n\n length := mload(value)\n\n }\n\n function array_storeLengthForEncoding_t_bytes_memory_ptr_nonPadded_inplace_fromStack(pos, length) -> updated_pos {\n updated_pos := pos\n }\n\n function abi_encode_t_bytes_memory_ptr_to_t_bytes_memory_ptr_nonPadded_inplace_fromStack(value, pos) -> end {\n let length := array_length_t_bytes_memory_ptr(value)\n pos := array_storeLengthForEncoding_t_bytes_memory_ptr_nonPadded_inplace_fromStack(pos, length)\n copy_memory_to_memory(add(value, 0x20), pos, length)\n end := add(pos, length)\n }\n\n function abi_encode_tuple_packed_t_bytes_memory_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed(pos , value0) -> end {\n\n pos := abi_encode_t_bytes_memory_ptr_to_t_bytes_memory_ptr_nonPadded_inplace_fromStack(value0, pos)\n\n end := pos\n }\n\n function abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed(headStart , value1, value0) -> tail {\n tail := add(headStart, 64)\n\n abi_encode_t_address_to_t_address_fromStack(value0, add(headStart, 0))\n\n abi_encode_t_address_to_t_address_fromStack(value1, add(headStart, 32))\n\n }\n\n function copy_calldata_to_memory(src, dst, length) {\n calldatacopy(dst, src, length)\n // clear end\n mstore(add(dst, length), 0)\n }\n\n // string -> string\n function abi_encode_t_string_calldata_ptr_to_t_string_memory_ptr_fromStack(start, length, pos) -> end {\n pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length)\n\n copy_calldata_to_memory(start, pos, length)\n end := add(pos, round_up_to_mul_of_32(length))\n }\n\n function abi_encode_tuple_t_string_calldata_ptr_t_string_calldata_ptr_t_uint8__to_t_string_memory_ptr_t_string_memory_ptr_t_uint8__fromStack_reversed(headStart , value4, value3, value2, value1, value0) -> tail {\n tail := add(headStart, 96)\n\n mstore(add(headStart, 0), sub(tail, headStart))\n tail := abi_encode_t_string_calldata_ptr_to_t_string_memory_ptr_fromStack(value0, value1, tail)\n\n mstore(add(headStart, 32), sub(tail, headStart))\n tail := abi_encode_t_string_calldata_ptr_to_t_string_memory_ptr_fromStack(value2, value3, tail)\n\n abi_encode_t_uint8_to_t_uint8_fromStack(value4, add(headStart, 64))\n\n }\n\n function abi_encode_tuple_t_address_t_address_t_address__to_t_address_t_address_t_address__fromStack_reversed(headStart , value2, value1, value0) -> tail {\n tail := add(headStart, 96)\n\n abi_encode_t_address_to_t_address_fromStack(value0, add(headStart, 0))\n\n abi_encode_t_address_to_t_address_fromStack(value1, add(headStart, 32))\n\n abi_encode_t_address_to_t_address_fromStack(value2, add(headStart, 64))\n\n }\n\n}\n", + "id": 1, + "language": "Yul", + "name": "#utility.yul" + } + ], + "immutableReferences": {}, + "linkReferences": {}, + "object": "60806040526004361061016a5760003560e01c806384810219116100d1578063a9059cbb1161008a578063ee5dc1e411610064578063ee5dc1e4146105c1578063f0350c04146105fe578063f5bfbd8a1461063b578063f8bf8e951461067857610171565b8063a9059cbb1461051c578063d3ba4b9e14610559578063dd62ed3e1461058457610171565b806384810219146103e65780638d1fdf2f1461040f57806395d89b411461044c5780639b5067e7146104775780639dc29fac146104a2578063a887c981146104df57610171565b8063313ce56711610123578063313ce5671461029c57806340c10f19146102c75780635ea20216146103045780636b8751c11461034157806370a082311461036c5780637eea1205146103a957610171565b80630131222f1461017657806306fdde03146101a1578063095ea7b3146101cc57806318160ddd146102095780631cddec191461023457806323b872dd1461025f57610171565b3661017157005b600080fd5b34801561018257600080fd5b5061018b6106b5565b6040516101989190611766565b60405180910390f35b3480156101ad57600080fd5b506101b66106df565b6040516101c3919061181a565b60405180910390f35b3480156101d857600080fd5b506101f360048036038101906101ee91906118b2565b61077a565b604051610200919061190d565b60405180910390f35b34801561021557600080fd5b5061021e610823565b60405161022b9190611937565b60405180910390f35b34801561024057600080fd5b506102496108ba565b604051610256919061190d565b60405180910390f35b34801561026b57600080fd5b5061028660048036038101906102819190611952565b610953565b604051610293919061190d565b60405180910390f35b3480156102a857600080fd5b506102b16109ff565b6040516102be91906119c1565b60405180910390f35b3480156102d357600080fd5b506102ee60048036038101906102e991906118b2565b610a96565b6040516102fb919061190d565b60405180910390f35b34801561031057600080fd5b5061032b600480360381019061032691906119dc565b610b3f565b604051610338919061190d565b60405180910390f35b34801561034d57600080fd5b50610356610be5565b604051610363919061190d565b60405180910390f35b34801561037857600080fd5b50610393600480360381019061038e91906119dc565b610c7e565b6040516103a09190611937565b60405180910390f35b3480156103b557600080fd5b506103d060048036038101906103cb9190611952565b610d22565b6040516103dd919061190d565b60405180910390f35b3480156103f257600080fd5b5061040d600480360381019061040891906119dc565b610e50565b005b34801561041b57600080fd5b50610436600480360381019061043191906119dc565b610ed4565b604051610443919061190d565b60405180910390f35b34801561045857600080fd5b50610461610f7a565b60405161046e919061181a565b60405180910390f35b34801561048357600080fd5b5061048c611015565b6040516104999190611a68565b60405180910390f35b3480156104ae57600080fd5b506104c960048036038101906104c491906118b2565b611039565b6040516104d6919061190d565b60405180910390f35b3480156104eb57600080fd5b50610506600480360381019061050191906118b2565b6110e2565b604051610513919061190d565b60405180910390f35b34801561052857600080fd5b50610543600480360381019061053e91906118b2565b61120d565b604051610550919061190d565b60405180910390f35b34801561056557600080fd5b5061056e6112b6565b60405161057b919061190d565b60405180910390f35b34801561059057600080fd5b506105ab60048036038101906105a69190611a83565b61134f565b6040516105b89190611937565b60405180910390f35b3480156105cd57600080fd5b506105e860048036038101906105e39190611b54565b6113f6565b6040516105f5919061190d565b60405180910390f35b34801561060a57600080fd5b50610625600480360381019061062091906119dc565b6114a8565b604051610632919061190d565b60405180910390f35b34801561064757600080fd5b50610662600480360381019061065d91906118b2565b61154e565b60405161066f919061190d565b60405180910390f35b34801561068457600080fd5b5061069f600480360381019061069a9190611be9565b611679565b6040516106ac919061190d565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801561074c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906107759190611d5d565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b384846040518363ffffffff1660e01b81526004016107d8929190611da6565b6020604051808303816000875af11580156107f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081b9190611dfb565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610891573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b59190611e3d565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631cddec196040518163ffffffff1660e01b81526004016020604051808303816000875af115801561092a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094e9190611dfb565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd8585856040518463ffffffff1660e01b81526004016109b393929190611e6a565b6020604051808303816000875af11580156109d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f69190611dfb565b90509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a919190611eb6565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1984846040518363ffffffff1660e01b8152600401610af4929190611da6565b6020604051808303816000875af1158015610b13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b379190611dfb565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ea20216836040518263ffffffff1660e01b8152600401610b9b9190611766565b6020604051808303816000875af1158015610bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bde9190611dfb565b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636b8751c16040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c799190611dfb565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401610cda9190611766565b602060405180830381865afa158015610cf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1b9190611e3d565b9050919050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16868686604051602401610d7593929190611e6a565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610dff9190611f2a565b600060405180830381855af49150503d8060008114610e3a576040519150601f19603f3d011682016040523d82523d6000602084013e610e3f565b606091505b509150915081925050509392505050565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d1fdf2f836040518263ffffffff1660e01b8152600401610f309190611766565b6020604051808303816000875af1158015610f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f739190611dfb565b9050919050565b606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610fe7573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906110109190611d5d565b905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639dc29fac84846040518363ffffffff1660e01b8152600401611097929190611da6565b6020604051808303816000875af11580156110b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110da9190611dfb565b905092915050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168585604051602401611133929190611da6565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516111bd9190611f2a565b600060405180830381855af49150503d80600081146111f8576040519150601f19603f3d011682016040523d82523d6000602084013e6111fd565b606091505b5091509150819250505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b815260040161126b929190611da6565b6020604051808303816000875af115801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae9190611dfb565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d3ba4b9e6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611326573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134a9190611dfb565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e84846040518363ffffffff1660e01b81526004016113ad929190611f41565b602060405180830381865afa1580156113ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ee9190611e3d565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee5dc1e487878787876040518663ffffffff1660e01b815260040161145a959493929190611fa6565b6020604051808303816000875af1158015611479573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149d9190611dfb565b905095945050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f0350c04836040518263ffffffff1660e01b81526004016115049190611766565b6020604051808303816000875af1158015611523573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115479190611dfb565b9050919050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16858560405160240161159f929190611da6565b6040516020818303038152906040527f095ea7b3000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516116299190611f2a565b600060405180830381855af49150503d8060008114611664576040519150601f19603f3d011682016040523d82523d6000602084013e611669565b606091505b5091509150819250505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8bf8e958585856040518463ffffffff1660e01b81526004016116d993929190611fef565b6020604051808303816000875af11580156116f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171c9190611dfb565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061175082611725565b9050919050565b61176081611745565b82525050565b600060208201905061177b6000830184611757565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156117bb5780820151818401526020810190506117a0565b838111156117ca576000848401525b50505050565b6000601f19601f8301169050919050565b60006117ec82611781565b6117f6818561178c565b935061180681856020860161179d565b61180f816117d0565b840191505092915050565b6000602082019050818103600083015261183481846117e1565b905092915050565b6000604051905090565b600080fd5b600080fd5b61185981611745565b811461186457600080fd5b50565b60008135905061187681611850565b92915050565b6000819050919050565b61188f8161187c565b811461189a57600080fd5b50565b6000813590506118ac81611886565b92915050565b600080604083850312156118c9576118c8611846565b5b60006118d785828601611867565b92505060206118e88582860161189d565b9150509250929050565b60008115159050919050565b611907816118f2565b82525050565b600060208201905061192260008301846118fe565b92915050565b6119318161187c565b82525050565b600060208201905061194c6000830184611928565b92915050565b60008060006060848603121561196b5761196a611846565b5b600061197986828701611867565b935050602061198a86828701611867565b925050604061199b8682870161189d565b9150509250925092565b600060ff82169050919050565b6119bb816119a5565b82525050565b60006020820190506119d660008301846119b2565b92915050565b6000602082840312156119f2576119f1611846565b5b6000611a0084828501611867565b91505092915050565b6000819050919050565b6000611a2e611a29611a2484611725565b611a09565b611725565b9050919050565b6000611a4082611a13565b9050919050565b6000611a5282611a35565b9050919050565b611a6281611a47565b82525050565b6000602082019050611a7d6000830184611a59565b92915050565b60008060408385031215611a9a57611a99611846565b5b6000611aa885828601611867565b9250506020611ab985828601611867565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112611ae857611ae7611ac3565b5b8235905067ffffffffffffffff811115611b0557611b04611ac8565b5b602083019150836001820283011115611b2157611b20611acd565b5b9250929050565b611b31816119a5565b8114611b3c57600080fd5b50565b600081359050611b4e81611b28565b92915050565b600080600080600060608688031215611b7057611b6f611846565b5b600086013567ffffffffffffffff811115611b8e57611b8d61184b565b5b611b9a88828901611ad2565b9550955050602086013567ffffffffffffffff811115611bbd57611bbc61184b565b5b611bc988828901611ad2565b93509350506040611bdc88828901611b3f565b9150509295509295909350565b600080600060608486031215611c0257611c01611846565b5b6000611c1086828701611867565b9350506020611c2186828701611867565b9250506040611c3286828701611867565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611c79826117d0565b810181811067ffffffffffffffff82111715611c9857611c97611c41565b5b80604052505050565b6000611cab61183c565b9050611cb78282611c70565b919050565b600067ffffffffffffffff821115611cd757611cd6611c41565b5b611ce0826117d0565b9050602081019050919050565b6000611d00611cfb84611cbc565b611ca1565b905082815260208101848484011115611d1c57611d1b611c3c565b5b611d2784828561179d565b509392505050565b600082601f830112611d4457611d43611ac3565b5b8151611d54848260208601611ced565b91505092915050565b600060208284031215611d7357611d72611846565b5b600082015167ffffffffffffffff811115611d9157611d9061184b565b5b611d9d84828501611d2f565b91505092915050565b6000604082019050611dbb6000830185611757565b611dc86020830184611928565b9392505050565b611dd8816118f2565b8114611de357600080fd5b50565b600081519050611df581611dcf565b92915050565b600060208284031215611e1157611e10611846565b5b6000611e1f84828501611de6565b91505092915050565b600081519050611e3781611886565b92915050565b600060208284031215611e5357611e52611846565b5b6000611e6184828501611e28565b91505092915050565b6000606082019050611e7f6000830186611757565b611e8c6020830185611757565b611e996040830184611928565b949350505050565b600081519050611eb081611b28565b92915050565b600060208284031215611ecc57611ecb611846565b5b6000611eda84828501611ea1565b91505092915050565b600081519050919050565b600081905092915050565b6000611f0482611ee3565b611f0e8185611eee565b9350611f1e81856020860161179d565b80840191505092915050565b6000611f368284611ef9565b915081905092915050565b6000604082019050611f566000830185611757565b611f636020830184611757565b9392505050565b82818337600083830152505050565b6000611f85838561178c565b9350611f92838584611f6a565b611f9b836117d0565b840190509392505050565b60006060820190508181036000830152611fc1818789611f79565b90508181036020830152611fd6818587611f79565b9050611fe560408301846119b2565b9695505050505050565b60006060820190506120046000830186611757565b6120116020830185611757565b61201e6040830184611757565b94935050505056fea2646970667358221220bb130f9250effb623338d0a0c315a1bcd08d8c15c5754a8191f2673314da04c464736f6c634300080b0033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x16A JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x84810219 GT PUSH2 0xD1 JUMPI DUP1 PUSH4 0xA9059CBB GT PUSH2 0x8A JUMPI DUP1 PUSH4 0xEE5DC1E4 GT PUSH2 0x64 JUMPI DUP1 PUSH4 0xEE5DC1E4 EQ PUSH2 0x5C1 JUMPI DUP1 PUSH4 0xF0350C04 EQ PUSH2 0x5FE JUMPI DUP1 PUSH4 0xF5BFBD8A EQ PUSH2 0x63B JUMPI DUP1 PUSH4 0xF8BF8E95 EQ PUSH2 0x678 JUMPI PUSH2 0x171 JUMP JUMPDEST DUP1 PUSH4 0xA9059CBB EQ PUSH2 0x51C JUMPI DUP1 PUSH4 0xD3BA4B9E EQ PUSH2 0x559 JUMPI DUP1 PUSH4 0xDD62ED3E EQ PUSH2 0x584 JUMPI PUSH2 0x171 JUMP JUMPDEST DUP1 PUSH4 0x84810219 EQ PUSH2 0x3E6 JUMPI DUP1 PUSH4 0x8D1FDF2F EQ PUSH2 0x40F JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x44C JUMPI DUP1 PUSH4 0x9B5067E7 EQ PUSH2 0x477 JUMPI DUP1 PUSH4 0x9DC29FAC EQ PUSH2 0x4A2 JUMPI DUP1 PUSH4 0xA887C981 EQ PUSH2 0x4DF JUMPI PUSH2 0x171 JUMP JUMPDEST DUP1 PUSH4 0x313CE567 GT PUSH2 0x123 JUMPI DUP1 PUSH4 0x313CE567 EQ PUSH2 0x29C JUMPI DUP1 PUSH4 0x40C10F19 EQ PUSH2 0x2C7 JUMPI DUP1 PUSH4 0x5EA20216 EQ PUSH2 0x304 JUMPI DUP1 PUSH4 0x6B8751C1 EQ PUSH2 0x341 JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x36C JUMPI DUP1 PUSH4 0x7EEA1205 EQ PUSH2 0x3A9 JUMPI PUSH2 0x171 JUMP JUMPDEST DUP1 PUSH4 0x131222F EQ PUSH2 0x176 JUMPI DUP1 PUSH4 0x6FDDE03 EQ PUSH2 0x1A1 JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x1CC JUMPI DUP1 PUSH4 0x18160DDD EQ PUSH2 0x209 JUMPI DUP1 PUSH4 0x1CDDEC19 EQ PUSH2 0x234 JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x25F JUMPI PUSH2 0x171 JUMP JUMPDEST CALLDATASIZE PUSH2 0x171 JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x182 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x18B PUSH2 0x6B5 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x198 SWAP2 SWAP1 PUSH2 0x1766 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1AD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B6 PUSH2 0x6DF JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x1C3 SWAP2 SWAP1 PUSH2 0x181A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1F3 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x1EE SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0x77A JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x200 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x215 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x21E PUSH2 0x823 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x22B SWAP2 SWAP1 PUSH2 0x1937 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x240 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x249 PUSH2 0x8BA JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x256 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x26B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x286 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x281 SWAP2 SWAP1 PUSH2 0x1952 JUMP JUMPDEST PUSH2 0x953 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x293 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2B1 PUSH2 0x9FF JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x2BE SWAP2 SWAP1 PUSH2 0x19C1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2D3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2EE PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x2E9 SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0xA96 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x2FB SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x310 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x32B PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x326 SWAP2 SWAP1 PUSH2 0x19DC JUMP JUMPDEST PUSH2 0xB3F JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x338 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x34D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x356 PUSH2 0xBE5 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x363 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x378 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x393 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x38E SWAP2 SWAP1 PUSH2 0x19DC JUMP JUMPDEST PUSH2 0xC7E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x3A0 SWAP2 SWAP1 PUSH2 0x1937 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3B5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x3D0 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x3CB SWAP2 SWAP1 PUSH2 0x1952 JUMP JUMPDEST PUSH2 0xD22 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x3DD SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3F2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x40D PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x408 SWAP2 SWAP1 PUSH2 0x19DC JUMP JUMPDEST PUSH2 0xE50 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x41B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x436 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x431 SWAP2 SWAP1 PUSH2 0x19DC JUMP JUMPDEST PUSH2 0xED4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x443 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x458 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x461 PUSH2 0xF7A JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x46E SWAP2 SWAP1 PUSH2 0x181A JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x483 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x48C PUSH2 0x1015 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x499 SWAP2 SWAP1 PUSH2 0x1A68 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4AE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x4C9 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x4C4 SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0x1039 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x4D6 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x4EB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x506 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x501 SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0x10E2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x513 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x528 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x543 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x53E SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0x120D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x550 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x565 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x56E PUSH2 0x12B6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x57B SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x590 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5AB PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x5A6 SWAP2 SWAP1 PUSH2 0x1A83 JUMP JUMPDEST PUSH2 0x134F JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x5B8 SWAP2 SWAP1 PUSH2 0x1937 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x5CD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5E8 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x5E3 SWAP2 SWAP1 PUSH2 0x1B54 JUMP JUMPDEST PUSH2 0x13F6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x5F5 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x60A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x625 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x620 SWAP2 SWAP1 PUSH2 0x19DC JUMP JUMPDEST PUSH2 0x14A8 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x632 SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x647 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x662 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x65D SWAP2 SWAP1 PUSH2 0x18B2 JUMP JUMPDEST PUSH2 0x154E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x66F SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x684 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x69F PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x69A SWAP2 SWAP1 PUSH2 0x1BE9 JUMP JUMPDEST PUSH2 0x1679 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x6AC SWAP2 SWAP1 PUSH2 0x190D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x6FDDE03 PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x74C JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x0 DUP3 RETURNDATACOPY RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x775 SWAP2 SWAP1 PUSH2 0x1D5D JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x95EA7B3 DUP5 DUP5 PUSH1 0x40 MLOAD DUP4 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x7D8 SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x7F7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x81B SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x18160DDD PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x891 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x8B5 SWAP2 SWAP1 PUSH2 0x1E3D JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x1CDDEC19 PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x92A JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x94E SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x23B872DD DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD DUP5 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x9B3 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1E6A JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x9D2 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x9F6 SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x313CE567 PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0xA6D JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xA91 SWAP2 SWAP1 PUSH2 0x1EB6 JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x40C10F19 DUP5 DUP5 PUSH1 0x40 MLOAD DUP4 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0xAF4 SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0xB13 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xB37 SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x5EA20216 DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0xB9B SWAP2 SWAP1 PUSH2 0x1766 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0xBBA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xBDE SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x6B8751C1 PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0xC55 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xC79 SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x70A08231 DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0xCDA SWAP2 SWAP1 PUSH2 0x1766 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0xCF7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xD1B SWAP2 SWAP1 PUSH2 0x1E3D JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP7 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0xD75 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1E6A JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH32 0x23B872DD00000000000000000000000000000000000000000000000000000000 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD PUSH2 0xDFF SWAP2 SWAP1 PUSH2 0x1F2A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0xE3A JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0xE3F JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 SWAP3 POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP1 PUSH1 0x0 DUP1 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP DUP1 PUSH1 0x1 PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF MUL NOT AND SWAP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND MUL OR SWAP1 SSTORE POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x8D1FDF2F DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0xF30 SWAP2 SWAP1 PUSH2 0x1766 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0xF4F JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0xF73 SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x95D89B41 PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0xFE7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x0 DUP3 RETURNDATACOPY RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x1010 SWAP2 SWAP1 PUSH2 0x1D5D JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x9DC29FAC DUP5 DUP5 PUSH1 0x40 MLOAD DUP4 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1097 SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x10B6 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x10DA SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 DUP6 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x1133 SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH32 0xA9059CBB00000000000000000000000000000000000000000000000000000000 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD PUSH2 0x11BD SWAP2 SWAP1 PUSH2 0x1F2A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x11F8 JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x11FD JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xA9059CBB DUP5 DUP5 PUSH1 0x40 MLOAD DUP4 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x126B SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x128A JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x12AE SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xD3BA4B9E PUSH1 0x40 MLOAD DUP2 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1326 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x134A SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xDD62ED3E DUP5 DUP5 PUSH1 0x40 MLOAD DUP4 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x13AD SWAP3 SWAP2 SWAP1 PUSH2 0x1F41 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x13CA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x13EE SWAP2 SWAP1 PUSH2 0x1E3D JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xEE5DC1E4 DUP8 DUP8 DUP8 DUP8 DUP8 PUSH1 0x40 MLOAD DUP7 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x145A SWAP6 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1FA6 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1479 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x149D SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xF0350C04 DUP4 PUSH1 0x40 MLOAD DUP3 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1504 SWAP2 SWAP1 PUSH2 0x1766 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x1523 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x1547 SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP6 DUP6 PUSH1 0x40 MLOAD PUSH1 0x24 ADD PUSH2 0x159F SWAP3 SWAP2 SWAP1 PUSH2 0x1DA6 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE PUSH32 0x95EA7B300000000000000000000000000000000000000000000000000000000 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD PUSH2 0x1629 SWAP2 SWAP1 PUSH2 0x1F2A JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 GAS DELEGATECALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x1664 JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x1669 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xF8BF8E95 DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD DUP5 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x16D9 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x1FEF JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x16F8 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x171C SWAP2 SWAP1 PUSH2 0x1DFB JUMP JUMPDEST SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1750 DUP3 PUSH2 0x1725 JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x1760 DUP2 PUSH2 0x1745 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x177B PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0x1757 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x17BB JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0x17A0 JUMP JUMPDEST DUP4 DUP2 GT ISZERO PUSH2 0x17CA JUMPI PUSH1 0x0 DUP5 DUP5 ADD MSTORE JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x17EC DUP3 PUSH2 0x1781 JUMP JUMPDEST PUSH2 0x17F6 DUP2 DUP6 PUSH2 0x178C JUMP JUMPDEST SWAP4 POP PUSH2 0x1806 DUP2 DUP6 PUSH1 0x20 DUP7 ADD PUSH2 0x179D JUMP JUMPDEST PUSH2 0x180F DUP2 PUSH2 0x17D0 JUMP JUMPDEST DUP5 ADD SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP DUP2 DUP2 SUB PUSH1 0x0 DUP4 ADD MSTORE PUSH2 0x1834 DUP2 DUP5 PUSH2 0x17E1 JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1859 DUP2 PUSH2 0x1745 JUMP JUMPDEST DUP2 EQ PUSH2 0x1864 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 CALLDATALOAD SWAP1 POP PUSH2 0x1876 DUP2 PUSH2 0x1850 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x188F DUP2 PUSH2 0x187C JUMP JUMPDEST DUP2 EQ PUSH2 0x189A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 CALLDATALOAD SWAP1 POP PUSH2 0x18AC DUP2 PUSH2 0x1886 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x18C9 JUMPI PUSH2 0x18C8 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x18D7 DUP6 DUP3 DUP7 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x18E8 DUP6 DUP3 DUP7 ADD PUSH2 0x189D JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP2 ISZERO ISZERO SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x1907 DUP2 PUSH2 0x18F2 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x1922 PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0x18FE JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH2 0x1931 DUP2 PUSH2 0x187C JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x194C PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0x1928 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x196B JUMPI PUSH2 0x196A PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1979 DUP7 DUP3 DUP8 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x198A DUP7 DUP3 DUP8 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 PUSH2 0x199B DUP7 DUP3 DUP8 ADD PUSH2 0x189D JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0xFF DUP3 AND SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x19BB DUP2 PUSH2 0x19A5 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x19D6 PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0x19B2 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x19F2 JUMPI PUSH2 0x19F1 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1A00 DUP5 DUP3 DUP6 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A2E PUSH2 0x1A29 PUSH2 0x1A24 DUP5 PUSH2 0x1725 JUMP JUMPDEST PUSH2 0x1A09 JUMP JUMPDEST PUSH2 0x1725 JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A40 DUP3 PUSH2 0x1A13 JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1A52 DUP3 PUSH2 0x1A35 JUMP JUMPDEST SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x1A62 DUP2 PUSH2 0x1A47 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x1A7D PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0x1A59 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1A9A JUMPI PUSH2 0x1A99 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1AA8 DUP6 DUP3 DUP7 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x20 PUSH2 0x1AB9 DUP6 DUP3 DUP7 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x1AE8 JUMPI PUSH2 0x1AE7 PUSH2 0x1AC3 JUMP JUMPDEST JUMPDEST DUP3 CALLDATALOAD SWAP1 POP PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1B05 JUMPI PUSH2 0x1B04 PUSH2 0x1AC8 JUMP JUMPDEST JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x1 DUP3 MUL DUP4 ADD GT ISZERO PUSH2 0x1B21 JUMPI PUSH2 0x1B20 PUSH2 0x1ACD JUMP JUMPDEST JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH2 0x1B31 DUP2 PUSH2 0x19A5 JUMP JUMPDEST DUP2 EQ PUSH2 0x1B3C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 CALLDATALOAD SWAP1 POP PUSH2 0x1B4E DUP2 PUSH2 0x1B28 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP7 DUP9 SUB SLT ISZERO PUSH2 0x1B70 JUMPI PUSH2 0x1B6F PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1B8E JUMPI PUSH2 0x1B8D PUSH2 0x184B JUMP JUMPDEST JUMPDEST PUSH2 0x1B9A DUP9 DUP3 DUP10 ADD PUSH2 0x1AD2 JUMP JUMPDEST SWAP6 POP SWAP6 POP POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1BBD JUMPI PUSH2 0x1BBC PUSH2 0x184B JUMP JUMPDEST JUMPDEST PUSH2 0x1BC9 DUP9 DUP3 DUP10 ADD PUSH2 0x1AD2 JUMP JUMPDEST SWAP4 POP SWAP4 POP POP PUSH1 0x40 PUSH2 0x1BDC DUP9 DUP3 DUP10 ADD PUSH2 0x1B3F JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x1C02 JUMPI PUSH2 0x1C01 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1C10 DUP7 DUP3 DUP8 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP4 POP POP PUSH1 0x20 PUSH2 0x1C21 DUP7 DUP3 DUP8 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP3 POP POP PUSH1 0x40 PUSH2 0x1C32 DUP7 DUP3 DUP8 ADD PUSH2 0x1867 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH2 0x1C79 DUP3 PUSH2 0x17D0 JUMP JUMPDEST DUP2 ADD DUP2 DUP2 LT PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT OR ISZERO PUSH2 0x1C98 JUMPI PUSH2 0x1C97 PUSH2 0x1C41 JUMP JUMPDEST JUMPDEST DUP1 PUSH1 0x40 MSTORE POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1CAB PUSH2 0x183C JUMP JUMPDEST SWAP1 POP PUSH2 0x1CB7 DUP3 DUP3 PUSH2 0x1C70 JUMP JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1CD7 JUMPI PUSH2 0x1CD6 PUSH2 0x1C41 JUMP JUMPDEST JUMPDEST PUSH2 0x1CE0 DUP3 PUSH2 0x17D0 JUMP JUMPDEST SWAP1 POP PUSH1 0x20 DUP2 ADD SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1D00 PUSH2 0x1CFB DUP5 PUSH2 0x1CBC JUMP JUMPDEST PUSH2 0x1CA1 JUMP JUMPDEST SWAP1 POP DUP3 DUP2 MSTORE PUSH1 0x20 DUP2 ADD DUP5 DUP5 DUP5 ADD GT ISZERO PUSH2 0x1D1C JUMPI PUSH2 0x1D1B PUSH2 0x1C3C JUMP JUMPDEST JUMPDEST PUSH2 0x1D27 DUP5 DUP3 DUP6 PUSH2 0x179D JUMP JUMPDEST POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x1D44 JUMPI PUSH2 0x1D43 PUSH2 0x1AC3 JUMP JUMPDEST JUMPDEST DUP2 MLOAD PUSH2 0x1D54 DUP5 DUP3 PUSH1 0x20 DUP7 ADD PUSH2 0x1CED JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1D73 JUMPI PUSH2 0x1D72 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 DUP3 ADD MLOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1D91 JUMPI PUSH2 0x1D90 PUSH2 0x184B JUMP JUMPDEST JUMPDEST PUSH2 0x1D9D DUP5 DUP3 DUP6 ADD PUSH2 0x1D2F JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP3 ADD SWAP1 POP PUSH2 0x1DBB PUSH1 0x0 DUP4 ADD DUP6 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x1DC8 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x1928 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH2 0x1DD8 DUP2 PUSH2 0x18F2 JUMP JUMPDEST DUP2 EQ PUSH2 0x1DE3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD SWAP1 POP PUSH2 0x1DF5 DUP2 PUSH2 0x1DCF JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1E11 JUMPI PUSH2 0x1E10 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1E1F DUP5 DUP3 DUP6 ADD PUSH2 0x1DE6 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD SWAP1 POP PUSH2 0x1E37 DUP2 PUSH2 0x1886 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1E53 JUMPI PUSH2 0x1E52 PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1E61 DUP5 DUP3 DUP6 ADD PUSH2 0x1E28 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 ADD SWAP1 POP PUSH2 0x1E7F PUSH1 0x0 DUP4 ADD DUP7 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x1E8C PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x1E99 PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0x1928 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD SWAP1 POP PUSH2 0x1EB0 DUP2 PUSH2 0x1B28 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1ECC JUMPI PUSH2 0x1ECB PUSH2 0x1846 JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0x1EDA DUP5 DUP3 DUP6 ADD PUSH2 0x1EA1 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP2 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1F04 DUP3 PUSH2 0x1EE3 JUMP JUMPDEST PUSH2 0x1F0E DUP2 DUP6 PUSH2 0x1EEE JUMP JUMPDEST SWAP4 POP PUSH2 0x1F1E DUP2 DUP6 PUSH1 0x20 DUP7 ADD PUSH2 0x179D JUMP JUMPDEST DUP1 DUP5 ADD SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1F36 DUP3 DUP5 PUSH2 0x1EF9 JUMP JUMPDEST SWAP2 POP DUP2 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 DUP3 ADD SWAP1 POP PUSH2 0x1F56 PUSH1 0x0 DUP4 ADD DUP6 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x1F63 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x1757 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST DUP3 DUP2 DUP4 CALLDATACOPY PUSH1 0x0 DUP4 DUP4 ADD MSTORE POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x1F85 DUP4 DUP6 PUSH2 0x178C JUMP JUMPDEST SWAP4 POP PUSH2 0x1F92 DUP4 DUP6 DUP5 PUSH2 0x1F6A JUMP JUMPDEST PUSH2 0x1F9B DUP4 PUSH2 0x17D0 JUMP JUMPDEST DUP5 ADD SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 ADD SWAP1 POP DUP2 DUP2 SUB PUSH1 0x0 DUP4 ADD MSTORE PUSH2 0x1FC1 DUP2 DUP8 DUP10 PUSH2 0x1F79 JUMP JUMPDEST SWAP1 POP DUP2 DUP2 SUB PUSH1 0x20 DUP4 ADD MSTORE PUSH2 0x1FD6 DUP2 DUP6 DUP8 PUSH2 0x1F79 JUMP JUMPDEST SWAP1 POP PUSH2 0x1FE5 PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0x19B2 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x60 DUP3 ADD SWAP1 POP PUSH2 0x2004 PUSH1 0x0 DUP4 ADD DUP7 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x2011 PUSH1 0x20 DUP4 ADD DUP6 PUSH2 0x1757 JUMP JUMPDEST PUSH2 0x201E PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0x1757 JUMP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xBB SGT 0xF SWAP3 POP 0xEF 0xFB PUSH3 0x3338D0 LOG0 0xC3 ISZERO LOG1 0xBC 0xD0 DUP14 DUP13 ISZERO 0xC5 PUSH22 0x4A8191F2673314DA04C464736F6C634300080B003300 ", + "sourceMap": "6591:5473:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7268:114;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7396:205;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10928:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8081:212;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9727:123;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11419:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7862:205;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8966:145;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9439:133;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9586:127;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8319:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11687:371;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7039:215;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;9288:137;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7627:209;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6727:116;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9125:149;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10616:286;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8799:153;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10459:131;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8567:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10236:209;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9864:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11099:294;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10035:187;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7268:114;7311:7;7345:22;;;;;;;;;;;7338:29;;7268:114;:::o;7396:205::-;7444:13;7564:15;;;;;;;;;;:20;;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7557:29;;7396:205;:::o;10928:157::-;11004:4;11031:15;;;;;;;;;;;:23;;;11055:7;11064:5;11031:39;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11024:46;;10928:157;;;;:::o;8081:212::-;8136:7;8249:15;;;;;;;;;;;:27;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8242:36;;8081:212;:::o;9727:123::-;9776:4;9807:15;;;;;;;;;;;:26;;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9800:35;;9727:123;:::o;11419:242::-;11570:4;11601:15;;;;;;;;;;;:28;;;11630:4;11636:2;11640:5;11601:45;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11594:52;;11419:242;;;;;:::o;7862:205::-;7914:5;8026:15;;;;;;;;;;;:24;;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8019:33;;7862:205;:::o;8966:145::-;9034:4;9065:15;;;;;;;;;;;:20;;;9086:2;9090:5;9065:31;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9058:38;;8966:145;;;;:::o;9439:133::-;9497:4;9528:15;;;;;;;;;;;:20;;;9549:7;9528:29;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9521:36;;9439:133;;;:::o;9586:127::-;9637:4;9668:15;;;;;;;;;;;:28;;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9661:37;;9586:127;:::o;8319:222::-;8383:7;8496:15;;;;;;;;;;;:25;;;8522:3;8496:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8489:37;;8319:222;;;:::o;11687:371::-;11826:4;11847:11;11860:17;11881:22;;;;;;;;;;;:35;;11999:4;12005:2;12009:5;11934:81;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11881:135;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11846:170;;;;12037:6;12030:13;;;;11687:371;;;;;:::o;7039:215::-;7163:16;7121:15;;:59;;;;;;;;;;;;;;;;;;7223:16;7198:22;;:41;;;;;;;;;;;;;;;;;;7039:215;:::o;9288:137::-;9348:4;9379:15;;;;;;;;;;;:22;;;9402:7;9379:31;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9372:38;;9288:137;;;:::o;7627:209::-;7677:13;7797:15;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7790:31;;7627:209;:::o;6727:116::-;;;;;;;;;;;;:::o;9125:149::-;9195:4;9226:15;;;;;;;;;;;:20;;;9247:4;9253:5;9226:33;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9219:40;;9125:149;;;;:::o;10616:286::-;10688:4;10709:11;10722:17;10743:22;;;;;;;;;;;:35;;10849:2;10853:5;10796:63;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10743:117;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10708:152;;;;10881:6;10874:13;;;;10616:286;;;;:::o;8799:153::-;8871:4;8902:15;;;;;;;;;;;:24;;;8927:2;8931:5;8902:35;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8895:42;;8799:153;;;;:::o;10459:131::-;10512:4;10543:15;;;;;;;;;;;:30;;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10536:39;;10459:131;:::o;8567:218::-;8696:7;8729:15;;;;;;;;;;;:25;;;8755:5;8762:7;8729:41;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8722:48;;8567:218;;;;:::o;10236:209::-;10347:4;10378:15;;;;;;;;;;;:28;;;10407:4;;10413:6;;10421:8;10378:52;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10371:59;;10236:209;;;;;;;:::o;9864:157::-;9934:4;9965:15;;;;;;;;;;;:34;;;10000:5;9965:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9958:48;;9864:157;;;:::o;11099:294::-;11175:4;11196:11;11209:17;11230:22;;;;;;;;;;;:35;;11335:7;11344:5;11283:67;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11230:121;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11195:156;;;;11372:6;11365:13;;;;11099:294;;;;:::o;10035:187::-;10128:4;10159:15;;;;;;;;;;;:24;;;10184:6;10192:5;10199:7;10159:48;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10152:55;;10035:187;;;;;:::o;7:126:1:-;44:7;84:42;77:5;73:54;62:65;;7:126;;;:::o;139:96::-;176:7;205:24;223:5;205:24;:::i;:::-;194:35;;139:96;;;:::o;241:118::-;328:24;346:5;328:24;:::i;:::-;323:3;316:37;241:118;;:::o;365:222::-;458:4;496:2;485:9;481:18;473:26;;509:71;577:1;566:9;562:17;553:6;509:71;:::i;:::-;365:222;;;;:::o;593:99::-;645:6;679:5;673:12;663:22;;593:99;;;:::o;698:169::-;782:11;816:6;811:3;804:19;856:4;851:3;847:14;832:29;;698:169;;;;:::o;873:307::-;941:1;951:113;965:6;962:1;959:13;951:113;;;1050:1;1045:3;1041:11;1035:18;1031:1;1026:3;1022:11;1015:39;987:2;984:1;980:10;975:15;;951:113;;;1082:6;1079:1;1076:13;1073:101;;;1162:1;1153:6;1148:3;1144:16;1137:27;1073:101;922:258;873:307;;;:::o;1186:102::-;1227:6;1278:2;1274:7;1269:2;1262:5;1258:14;1254:28;1244:38;;1186:102;;;:::o;1294:364::-;1382:3;1410:39;1443:5;1410:39;:::i;:::-;1465:71;1529:6;1524:3;1465:71;:::i;:::-;1458:78;;1545:52;1590:6;1585:3;1578:4;1571:5;1567:16;1545:52;:::i;:::-;1622:29;1644:6;1622:29;:::i;:::-;1617:3;1613:39;1606:46;;1386:272;1294:364;;;;:::o;1664:313::-;1777:4;1815:2;1804:9;1800:18;1792:26;;1864:9;1858:4;1854:20;1850:1;1839:9;1835:17;1828:47;1892:78;1965:4;1956:6;1892:78;:::i;:::-;1884:86;;1664:313;;;;:::o;1983:75::-;2016:6;2049:2;2043:9;2033:19;;1983:75;:::o;2064:117::-;2173:1;2170;2163:12;2187:117;2296:1;2293;2286:12;2310:122;2383:24;2401:5;2383:24;:::i;:::-;2376:5;2373:35;2363:63;;2422:1;2419;2412:12;2363:63;2310:122;:::o;2438:139::-;2484:5;2522:6;2509:20;2500:29;;2538:33;2565:5;2538:33;:::i;:::-;2438:139;;;;:::o;2583:77::-;2620:7;2649:5;2638:16;;2583:77;;;:::o;2666:122::-;2739:24;2757:5;2739:24;:::i;:::-;2732:5;2729:35;2719:63;;2778:1;2775;2768:12;2719:63;2666:122;:::o;2794:139::-;2840:5;2878:6;2865:20;2856:29;;2894:33;2921:5;2894:33;:::i;:::-;2794:139;;;;:::o;2939:474::-;3007:6;3015;3064:2;3052:9;3043:7;3039:23;3035:32;3032:119;;;3070:79;;:::i;:::-;3032:119;3190:1;3215:53;3260:7;3251:6;3240:9;3236:22;3215:53;:::i;:::-;3205:63;;3161:117;3317:2;3343:53;3388:7;3379:6;3368:9;3364:22;3343:53;:::i;:::-;3333:63;;3288:118;2939:474;;;;;:::o;3419:90::-;3453:7;3496:5;3489:13;3482:21;3471:32;;3419:90;;;:::o;3515:109::-;3596:21;3611:5;3596:21;:::i;:::-;3591:3;3584:34;3515:109;;:::o;3630:210::-;3717:4;3755:2;3744:9;3740:18;3732:26;;3768:65;3830:1;3819:9;3815:17;3806:6;3768:65;:::i;:::-;3630:210;;;;:::o;3846:118::-;3933:24;3951:5;3933:24;:::i;:::-;3928:3;3921:37;3846:118;;:::o;3970:222::-;4063:4;4101:2;4090:9;4086:18;4078:26;;4114:71;4182:1;4171:9;4167:17;4158:6;4114:71;:::i;:::-;3970:222;;;;:::o;4198:619::-;4275:6;4283;4291;4340:2;4328:9;4319:7;4315:23;4311:32;4308:119;;;4346:79;;:::i;:::-;4308:119;4466:1;4491:53;4536:7;4527:6;4516:9;4512:22;4491:53;:::i;:::-;4481:63;;4437:117;4593:2;4619:53;4664:7;4655:6;4644:9;4640:22;4619:53;:::i;:::-;4609:63;;4564:118;4721:2;4747:53;4792:7;4783:6;4772:9;4768:22;4747:53;:::i;:::-;4737:63;;4692:118;4198:619;;;;;:::o;4823:86::-;4858:7;4898:4;4891:5;4887:16;4876:27;;4823:86;;;:::o;4915:112::-;4998:22;5014:5;4998:22;:::i;:::-;4993:3;4986:35;4915:112;;:::o;5033:214::-;5122:4;5160:2;5149:9;5145:18;5137:26;;5173:67;5237:1;5226:9;5222:17;5213:6;5173:67;:::i;:::-;5033:214;;;;:::o;5253:329::-;5312:6;5361:2;5349:9;5340:7;5336:23;5332:32;5329:119;;;5367:79;;:::i;:::-;5329:119;5487:1;5512:53;5557:7;5548:6;5537:9;5533:22;5512:53;:::i;:::-;5502:63;;5458:117;5253:329;;;;:::o;5588:60::-;5616:3;5637:5;5630:12;;5588:60;;;:::o;5654:142::-;5704:9;5737:53;5755:34;5764:24;5782:5;5764:24;:::i;:::-;5755:34;:::i;:::-;5737:53;:::i;:::-;5724:66;;5654:142;;;:::o;5802:126::-;5852:9;5885:37;5916:5;5885:37;:::i;:::-;5872:50;;5802:126;;;:::o;5934:157::-;6015:9;6048:37;6079:5;6048:37;:::i;:::-;6035:50;;5934:157;;;:::o;6097:193::-;6215:68;6277:5;6215:68;:::i;:::-;6210:3;6203:81;6097:193;;:::o;6296:284::-;6420:4;6458:2;6447:9;6443:18;6435:26;;6471:102;6570:1;6559:9;6555:17;6546:6;6471:102;:::i;:::-;6296:284;;;;:::o;6586:474::-;6654:6;6662;6711:2;6699:9;6690:7;6686:23;6682:32;6679:119;;;6717:79;;:::i;:::-;6679:119;6837:1;6862:53;6907:7;6898:6;6887:9;6883:22;6862:53;:::i;:::-;6852:63;;6808:117;6964:2;6990:53;7035:7;7026:6;7015:9;7011:22;6990:53;:::i;:::-;6980:63;;6935:118;6586:474;;;;;:::o;7066:117::-;7175:1;7172;7165:12;7189:117;7298:1;7295;7288:12;7312:117;7421:1;7418;7411:12;7449:553;7507:8;7517:6;7567:3;7560:4;7552:6;7548:17;7544:27;7534:122;;7575:79;;:::i;:::-;7534:122;7688:6;7675:20;7665:30;;7718:18;7710:6;7707:30;7704:117;;;7740:79;;:::i;:::-;7704:117;7854:4;7846:6;7842:17;7830:29;;7908:3;7900:4;7892:6;7888:17;7878:8;7874:32;7871:41;7868:128;;;7915:79;;:::i;:::-;7868:128;7449:553;;;;;:::o;8008:118::-;8079:22;8095:5;8079:22;:::i;:::-;8072:5;8069:33;8059:61;;8116:1;8113;8106:12;8059:61;8008:118;:::o;8132:135::-;8176:5;8214:6;8201:20;8192:29;;8230:31;8255:5;8230:31;:::i;:::-;8132:135;;;;:::o;8273:1015::-;8372:6;8380;8388;8396;8404;8453:2;8441:9;8432:7;8428:23;8424:32;8421:119;;;8459:79;;:::i;:::-;8421:119;8607:1;8596:9;8592:17;8579:31;8637:18;8629:6;8626:30;8623:117;;;8659:79;;:::i;:::-;8623:117;8772:65;8829:7;8820:6;8809:9;8805:22;8772:65;:::i;:::-;8754:83;;;;8550:297;8914:2;8903:9;8899:18;8886:32;8945:18;8937:6;8934:30;8931:117;;;8967:79;;:::i;:::-;8931:117;9080:65;9137:7;9128:6;9117:9;9113:22;9080:65;:::i;:::-;9062:83;;;;8857:298;9194:2;9220:51;9263:7;9254:6;9243:9;9239:22;9220:51;:::i;:::-;9210:61;;9165:116;8273:1015;;;;;;;;:::o;9294:619::-;9371:6;9379;9387;9436:2;9424:9;9415:7;9411:23;9407:32;9404:119;;;9442:79;;:::i;:::-;9404:119;9562:1;9587:53;9632:7;9623:6;9612:9;9608:22;9587:53;:::i;:::-;9577:63;;9533:117;9689:2;9715:53;9760:7;9751:6;9740:9;9736:22;9715:53;:::i;:::-;9705:63;;9660:118;9817:2;9843:53;9888:7;9879:6;9868:9;9864:22;9843:53;:::i;:::-;9833:63;;9788:118;9294:619;;;;;:::o;9919:117::-;10028:1;10025;10018:12;10042:180;10090:77;10087:1;10080:88;10187:4;10184:1;10177:15;10211:4;10208:1;10201:15;10228:281;10311:27;10333:4;10311:27;:::i;:::-;10303:6;10299:40;10441:6;10429:10;10426:22;10405:18;10393:10;10390:34;10387:62;10384:88;;;10452:18;;:::i;:::-;10384:88;10492:10;10488:2;10481:22;10271:238;10228:281;;:::o;10515:129::-;10549:6;10576:20;;:::i;:::-;10566:30;;10605:33;10633:4;10625:6;10605:33;:::i;:::-;10515:129;;;:::o;10650:308::-;10712:4;10802:18;10794:6;10791:30;10788:56;;;10824:18;;:::i;:::-;10788:56;10862:29;10884:6;10862:29;:::i;:::-;10854:37;;10946:4;10940;10936:15;10928:23;;10650:308;;;:::o;10964:421::-;11053:5;11078:66;11094:49;11136:6;11094:49;:::i;:::-;11078:66;:::i;:::-;11069:75;;11167:6;11160:5;11153:21;11205:4;11198:5;11194:16;11243:3;11234:6;11229:3;11225:16;11222:25;11219:112;;;11250:79;;:::i;:::-;11219:112;11340:39;11372:6;11367:3;11362;11340:39;:::i;:::-;11059:326;10964:421;;;;;:::o;11405:355::-;11472:5;11521:3;11514:4;11506:6;11502:17;11498:27;11488:122;;11529:79;;:::i;:::-;11488:122;11639:6;11633:13;11664:90;11750:3;11742:6;11735:4;11727:6;11723:17;11664:90;:::i;:::-;11655:99;;11478:282;11405:355;;;;:::o;11766:524::-;11846:6;11895:2;11883:9;11874:7;11870:23;11866:32;11863:119;;;11901:79;;:::i;:::-;11863:119;12042:1;12031:9;12027:17;12021:24;12072:18;12064:6;12061:30;12058:117;;;12094:79;;:::i;:::-;12058:117;12199:74;12265:7;12256:6;12245:9;12241:22;12199:74;:::i;:::-;12189:84;;11992:291;11766:524;;;;:::o;12296:332::-;12417:4;12455:2;12444:9;12440:18;12432:26;;12468:71;12536:1;12525:9;12521:17;12512:6;12468:71;:::i;:::-;12549:72;12617:2;12606:9;12602:18;12593:6;12549:72;:::i;:::-;12296:332;;;;;:::o;12634:116::-;12704:21;12719:5;12704:21;:::i;:::-;12697:5;12694:32;12684:60;;12740:1;12737;12730:12;12684:60;12634:116;:::o;12756:137::-;12810:5;12841:6;12835:13;12826:22;;12857:30;12881:5;12857:30;:::i;:::-;12756:137;;;;:::o;12899:345::-;12966:6;13015:2;13003:9;12994:7;12990:23;12986:32;12983:119;;;13021:79;;:::i;:::-;12983:119;13141:1;13166:61;13219:7;13210:6;13199:9;13195:22;13166:61;:::i;:::-;13156:71;;13112:125;12899:345;;;;:::o;13250:143::-;13307:5;13338:6;13332:13;13323:22;;13354:33;13381:5;13354:33;:::i;:::-;13250:143;;;;:::o;13399:351::-;13469:6;13518:2;13506:9;13497:7;13493:23;13489:32;13486:119;;;13524:79;;:::i;:::-;13486:119;13644:1;13669:64;13725:7;13716:6;13705:9;13701:22;13669:64;:::i;:::-;13659:74;;13615:128;13399:351;;;;:::o;13756:442::-;13905:4;13943:2;13932:9;13928:18;13920:26;;13956:71;14024:1;14013:9;14009:17;14000:6;13956:71;:::i;:::-;14037:72;14105:2;14094:9;14090:18;14081:6;14037:72;:::i;:::-;14119;14187:2;14176:9;14172:18;14163:6;14119:72;:::i;:::-;13756:442;;;;;;:::o;14204:139::-;14259:5;14290:6;14284:13;14275:22;;14306:31;14331:5;14306:31;:::i;:::-;14204:139;;;;:::o;14349:347::-;14417:6;14466:2;14454:9;14445:7;14441:23;14437:32;14434:119;;;14472:79;;:::i;:::-;14434:119;14592:1;14617:62;14671:7;14662:6;14651:9;14647:22;14617:62;:::i;:::-;14607:72;;14563:126;14349:347;;;;:::o;14702:98::-;14753:6;14787:5;14781:12;14771:22;;14702:98;;;:::o;14806:147::-;14907:11;14944:3;14929:18;;14806:147;;;;:::o;14959:373::-;15063:3;15091:38;15123:5;15091:38;:::i;:::-;15145:88;15226:6;15221:3;15145:88;:::i;:::-;15138:95;;15242:52;15287:6;15282:3;15275:4;15268:5;15264:16;15242:52;:::i;:::-;15319:6;15314:3;15310:16;15303:23;;15067:265;14959:373;;;;:::o;15338:271::-;15468:3;15490:93;15579:3;15570:6;15490:93;:::i;:::-;15483:100;;15600:3;15593:10;;15338:271;;;;:::o;15615:332::-;15736:4;15774:2;15763:9;15759:18;15751:26;;15787:71;15855:1;15844:9;15840:17;15831:6;15787:71;:::i;:::-;15868:72;15936:2;15925:9;15921:18;15912:6;15868:72;:::i;:::-;15615:332;;;;;:::o;15953:154::-;16037:6;16032:3;16027;16014:30;16099:1;16090:6;16085:3;16081:16;16074:27;15953:154;;;:::o;16137:304::-;16235:3;16256:71;16320:6;16315:3;16256:71;:::i;:::-;16249:78;;16337:43;16373:6;16368:3;16361:5;16337:43;:::i;:::-;16405:29;16427:6;16405:29;:::i;:::-;16400:3;16396:39;16389:46;;16137:304;;;;;:::o;16447:656::-;16652:4;16690:2;16679:9;16675:18;16667:26;;16739:9;16733:4;16729:20;16725:1;16714:9;16710:17;16703:47;16767:88;16850:4;16841:6;16833;16767:88;:::i;:::-;16759:96;;16902:9;16896:4;16892:20;16887:2;16876:9;16872:18;16865:48;16930:88;17013:4;17004:6;16996;16930:88;:::i;:::-;16922:96;;17028:68;17092:2;17081:9;17077:18;17068:6;17028:68;:::i;:::-;16447:656;;;;;;;;:::o;17109:442::-;17258:4;17296:2;17285:9;17281:18;17273:26;;17309:71;17377:1;17366:9;17362:17;17353:6;17309:71;:::i;:::-;17390:72;17458:2;17447:9;17443:18;17434:6;17390:72;:::i;:::-;17472;17540:2;17529:9;17525:18;17516:6;17472:72;:::i;:::-;17109:442;;;;;;:::o" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "1656800", + "executionCost": "50270", + "totalCost": "1707070" + }, + "external": { + "allowance(address,address)": "infinite", + "approve(address,uint256)": "infinite", + "approve_delegate(address,uint256)": "infinite", + "balanceOf(address)": "infinite", + "burn(address,uint256)": "infinite", + "clear_metadata()": "infinite", + "decimals()": "infinite", + "freeze(address)": "infinite", + "freeze_asset()": "infinite", + "get_address()": "2546", + "localasseterc20()": "infinite", + "mint(address,uint256)": "infinite", + "name()": "infinite", + "set_address_interface(address)": "49012", + "set_metadata(string,string,uint8)": "infinite", + "set_team(address,address,address)": "infinite", + "symbol()": "infinite", + "thaw(address)": "infinite", + "thaw_asset()": "infinite", + "totalSupply()": "infinite", + "transfer(address,uint256)": "infinite", + "transferFrom(address,address,uint256)": "infinite", + "transferFrom_delegate(address,address,uint256)": "infinite", + "transfer_delegate(address,uint256)": "infinite", + "transfer_ownership(address)": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "80" + }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 6591, "end": 12064, "name": "MSTORE", "source": 0 }, + { + "begin": 6800, + "end": 6842, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFEDE9001A6F7F4798CCB76EF1E7F664701" + }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 6727, "end": 6843, "name": "DUP1", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 6727, "end": 6843, "name": "EXP", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "DUP2", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "SLOAD", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "DUP2", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 6727, "end": 6843, "name": "MUL", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "NOT", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "AND", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "SWAP1", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "DUP4", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 6727, "end": 6843, "name": "AND", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "MUL", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "OR", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "SWAP1", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "SSTORE", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "POP", "source": 0 }, + { + "begin": 6886, + "end": 6928, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFEDE9001A6F7F4798CCB76EF1E7F664701" + }, + { + "begin": 6853, + "end": 6928, + "name": "PUSH", + "source": 0, + "value": "1" + }, + { + "begin": 6853, + "end": 6928, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 6853, + "end": 6928, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 6853, "end": 6928, "name": "EXP", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "DUP2", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "SLOAD", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "DUP2", "source": 0 }, + { + "begin": 6853, + "end": 6928, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 6853, "end": 6928, "name": "MUL", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "NOT", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "AND", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "SWAP1", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "DUP4", "source": 0 }, + { + "begin": 6853, + "end": 6928, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 6853, "end": 6928, "name": "AND", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "MUL", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "OR", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "SWAP1", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "SSTORE", "source": 0 }, + { "begin": 6853, "end": 6928, "name": "POP", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "CALLVALUE", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "ISZERO", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "1" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "REVERT", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "tag", + "source": 0, + "value": "1" + }, + { "begin": 6591, "end": 12064, "name": "JUMPDEST", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "POP", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH #[$]", + "source": 0, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [$]", + "source": 0, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 6591, "end": 12064, "name": "CODECOPY", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 6591, "end": 12064, "name": "RETURN", "source": 0 } + ], + ".data": { + "0": { + ".auxdata": "a2646970667358221220bb130f9250effb623338d0a0c315a1bcd08d8c15c5754a8191f2673314da04c464736f6c634300080b0033", + ".code": [ + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "80" + }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 6591, "end": 12064, "name": "MSTORE", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { + "begin": 6591, + "end": 12064, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 6591, "end": 12064, "name": "LT", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "1" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 6591, + "end": 12064, + "name": "CALLDATALOAD", + "source": 0 + }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 6591, "end": 12064, "name": "SHR", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "84810219" + }, + { "begin": 6591, "end": 12064, "name": "GT", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "28" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "A9059CBB" + }, + { "begin": 6591, "end": 12064, "name": "GT", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "29" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "EE5DC1E4" + }, + { "begin": 6591, "end": 12064, "name": "GT", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "30" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "EE5DC1E4" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "24" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "F0350C04" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "25" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "F5BFBD8A" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "26" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "F8BF8E95" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "27" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "2" + }, + { "begin": 6591, "end": 12064, "name": "JUMP", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "tag", + "source": 0, + "value": "30" + }, + { "begin": 6591, "end": 12064, "name": "JUMPDEST", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "A9059CBB" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "21" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "D3BA4B9E" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "22" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "DD62ED3E" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "23" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "2" + }, + { "begin": 6591, "end": 12064, "name": "JUMP", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "tag", + "source": 0, + "value": "29" + }, + { "begin": 6591, "end": 12064, "name": "JUMPDEST", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "84810219" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "15" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "8D1FDF2F" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "16" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "95D89B41" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "17" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "9B5067E7" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "18" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "9DC29FAC" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "19" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "A887C981" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "20" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "2" + }, + { "begin": 6591, "end": 12064, "name": "JUMP", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "tag", + "source": 0, + "value": "28" + }, + { "begin": 6591, "end": 12064, "name": "JUMPDEST", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "313CE567" + }, + { "begin": 6591, "end": 12064, "name": "GT", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "31" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "313CE567" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "9" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "40C10F19" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "10" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "5EA20216" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "11" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "6B8751C1" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "12" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "70A08231" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "13" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "7EEA1205" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "14" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "2" + }, + { "begin": 6591, "end": 12064, "name": "JUMP", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "tag", + "source": 0, + "value": "31" + }, + { "begin": 6591, "end": 12064, "name": "JUMPDEST", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "131222F" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "3" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "6FDDE03" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "4" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "95EA7B3" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "5" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "18160DDD" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "6" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "1CDDEC19" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "7" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "23B872DD" + }, + { "begin": 6591, "end": 12064, "name": "EQ", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "8" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "2" + }, + { "begin": 6591, "end": 12064, "name": "JUMP", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "tag", + "source": 0, + "value": "1" + }, + { "begin": 6591, "end": 12064, "name": "JUMPDEST", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "CALLDATASIZE", + "source": 0 + }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH [tag]", + "source": 0, + "value": "2" + }, + { "begin": 6591, "end": 12064, "name": "JUMPI", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "STOP", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "tag", + "source": 0, + "value": "2" + }, + { "begin": 6591, "end": 12064, "name": "JUMPDEST", "source": 0 }, + { + "begin": 6591, + "end": 12064, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 6591, "end": 12064, "name": "DUP1", "source": 0 }, + { "begin": 6591, "end": 12064, "name": "REVERT", "source": 0 }, + { + "begin": 7268, + "end": 7382, + "name": "tag", + "source": 0, + "value": "3" + }, + { "begin": 7268, "end": 7382, "name": "JUMPDEST", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "CALLVALUE", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "DUP1", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "ISZERO", "source": 0 }, + { + "begin": 7268, + "end": 7382, + "name": "PUSH [tag]", + "source": 0, + "value": "34" + }, + { "begin": 7268, "end": 7382, "name": "JUMPI", "source": 0 }, + { + "begin": 7268, + "end": 7382, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7268, "end": 7382, "name": "DUP1", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "REVERT", "source": 0 }, + { + "begin": 7268, + "end": 7382, + "name": "tag", + "source": 0, + "value": "34" + }, + { "begin": 7268, "end": 7382, "name": "JUMPDEST", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "POP", "source": 0 }, + { + "begin": 7268, + "end": 7382, + "name": "PUSH [tag]", + "source": 0, + "value": "35" + }, + { + "begin": 7268, + "end": 7382, + "name": "PUSH [tag]", + "source": 0, + "value": "36" + }, + { + "begin": 7268, + "end": 7382, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7268, + "end": 7382, + "name": "tag", + "source": 0, + "value": "35" + }, + { "begin": 7268, "end": 7382, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7268, + "end": 7382, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7268, "end": 7382, "name": "MLOAD", "source": 0 }, + { + "begin": 7268, + "end": 7382, + "name": "PUSH [tag]", + "source": 0, + "value": "37" + }, + { "begin": 7268, "end": 7382, "name": "SWAP2", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "SWAP1", "source": 0 }, + { + "begin": 7268, + "end": 7382, + "name": "PUSH [tag]", + "source": 0, + "value": "38" + }, + { + "begin": 7268, + "end": 7382, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7268, + "end": 7382, + "name": "tag", + "source": 0, + "value": "37" + }, + { "begin": 7268, "end": 7382, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7268, + "end": 7382, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7268, "end": 7382, "name": "MLOAD", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "DUP1", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "SWAP2", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "SUB", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "SWAP1", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "RETURN", "source": 0 }, + { + "begin": 7396, + "end": 7601, + "name": "tag", + "source": 0, + "value": "4" + }, + { "begin": 7396, "end": 7601, "name": "JUMPDEST", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "CALLVALUE", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "DUP1", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "ISZERO", "source": 0 }, + { + "begin": 7396, + "end": 7601, + "name": "PUSH [tag]", + "source": 0, + "value": "39" + }, + { "begin": 7396, "end": 7601, "name": "JUMPI", "source": 0 }, + { + "begin": 7396, + "end": 7601, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7396, "end": 7601, "name": "DUP1", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "REVERT", "source": 0 }, + { + "begin": 7396, + "end": 7601, + "name": "tag", + "source": 0, + "value": "39" + }, + { "begin": 7396, "end": 7601, "name": "JUMPDEST", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "POP", "source": 0 }, + { + "begin": 7396, + "end": 7601, + "name": "PUSH [tag]", + "source": 0, + "value": "40" + }, + { + "begin": 7396, + "end": 7601, + "name": "PUSH [tag]", + "source": 0, + "value": "41" + }, + { + "begin": 7396, + "end": 7601, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7396, + "end": 7601, + "name": "tag", + "source": 0, + "value": "40" + }, + { "begin": 7396, "end": 7601, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7396, + "end": 7601, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7396, "end": 7601, "name": "MLOAD", "source": 0 }, + { + "begin": 7396, + "end": 7601, + "name": "PUSH [tag]", + "source": 0, + "value": "42" + }, + { "begin": 7396, "end": 7601, "name": "SWAP2", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "SWAP1", "source": 0 }, + { + "begin": 7396, + "end": 7601, + "name": "PUSH [tag]", + "source": 0, + "value": "43" + }, + { + "begin": 7396, + "end": 7601, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7396, + "end": 7601, + "name": "tag", + "source": 0, + "value": "42" + }, + { "begin": 7396, "end": 7601, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7396, + "end": 7601, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7396, "end": 7601, "name": "MLOAD", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "DUP1", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "SWAP2", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "SUB", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "SWAP1", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "RETURN", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "tag", + "source": 0, + "value": "5" + }, + { "begin": 10928, "end": 11085, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "CALLVALUE", + "source": 0 + }, + { "begin": 10928, "end": 11085, "name": "DUP1", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "ISZERO", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "PUSH [tag]", + "source": 0, + "value": "44" + }, + { "begin": 10928, "end": 11085, "name": "JUMPI", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10928, "end": 11085, "name": "DUP1", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "REVERT", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "tag", + "source": 0, + "value": "44" + }, + { "begin": 10928, "end": 11085, "name": "JUMPDEST", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "POP", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "PUSH [tag]", + "source": 0, + "value": "45" + }, + { + "begin": 10928, + "end": 11085, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 10928, "end": 11085, "name": "DUP1", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 10928, "end": 11085, "name": "SUB", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "DUP2", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "ADD", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "SWAP1", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "PUSH [tag]", + "source": 0, + "value": "46" + }, + { "begin": 10928, "end": 11085, "name": "SWAP2", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "SWAP1", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "PUSH [tag]", + "source": 0, + "value": "47" + }, + { + "begin": 10928, + "end": 11085, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10928, + "end": 11085, + "name": "tag", + "source": 0, + "value": "46" + }, + { "begin": 10928, "end": 11085, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "PUSH [tag]", + "source": 0, + "value": "48" + }, + { + "begin": 10928, + "end": 11085, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10928, + "end": 11085, + "name": "tag", + "source": 0, + "value": "45" + }, + { "begin": 10928, "end": 11085, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10928, "end": 11085, "name": "MLOAD", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "PUSH [tag]", + "source": 0, + "value": "49" + }, + { "begin": 10928, "end": 11085, "name": "SWAP2", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "SWAP1", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 10928, + "end": 11085, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10928, + "end": 11085, + "name": "tag", + "source": 0, + "value": "49" + }, + { "begin": 10928, "end": 11085, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10928, "end": 11085, "name": "MLOAD", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "DUP1", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "SWAP2", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "SUB", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "SWAP1", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "RETURN", "source": 0 }, + { + "begin": 8081, + "end": 8293, + "name": "tag", + "source": 0, + "value": "6" + }, + { "begin": 8081, "end": 8293, "name": "JUMPDEST", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "CALLVALUE", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "DUP1", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "ISZERO", "source": 0 }, + { + "begin": 8081, + "end": 8293, + "name": "PUSH [tag]", + "source": 0, + "value": "51" + }, + { "begin": 8081, "end": 8293, "name": "JUMPI", "source": 0 }, + { + "begin": 8081, + "end": 8293, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8081, "end": 8293, "name": "DUP1", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "REVERT", "source": 0 }, + { + "begin": 8081, + "end": 8293, + "name": "tag", + "source": 0, + "value": "51" + }, + { "begin": 8081, "end": 8293, "name": "JUMPDEST", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "POP", "source": 0 }, + { + "begin": 8081, + "end": 8293, + "name": "PUSH [tag]", + "source": 0, + "value": "52" + }, + { + "begin": 8081, + "end": 8293, + "name": "PUSH [tag]", + "source": 0, + "value": "53" + }, + { + "begin": 8081, + "end": 8293, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8081, + "end": 8293, + "name": "tag", + "source": 0, + "value": "52" + }, + { "begin": 8081, "end": 8293, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8081, + "end": 8293, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8081, "end": 8293, "name": "MLOAD", "source": 0 }, + { + "begin": 8081, + "end": 8293, + "name": "PUSH [tag]", + "source": 0, + "value": "54" + }, + { "begin": 8081, "end": 8293, "name": "SWAP2", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "SWAP1", "source": 0 }, + { + "begin": 8081, + "end": 8293, + "name": "PUSH [tag]", + "source": 0, + "value": "55" + }, + { + "begin": 8081, + "end": 8293, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8081, + "end": 8293, + "name": "tag", + "source": 0, + "value": "54" + }, + { "begin": 8081, "end": 8293, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8081, + "end": 8293, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8081, "end": 8293, "name": "MLOAD", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "DUP1", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "SWAP2", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "SUB", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "SWAP1", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "RETURN", "source": 0 }, + { + "begin": 9727, + "end": 9850, + "name": "tag", + "source": 0, + "value": "7" + }, + { "begin": 9727, "end": 9850, "name": "JUMPDEST", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "CALLVALUE", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "DUP1", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "ISZERO", "source": 0 }, + { + "begin": 9727, + "end": 9850, + "name": "PUSH [tag]", + "source": 0, + "value": "56" + }, + { "begin": 9727, "end": 9850, "name": "JUMPI", "source": 0 }, + { + "begin": 9727, + "end": 9850, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9727, "end": 9850, "name": "DUP1", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "REVERT", "source": 0 }, + { + "begin": 9727, + "end": 9850, + "name": "tag", + "source": 0, + "value": "56" + }, + { "begin": 9727, "end": 9850, "name": "JUMPDEST", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "POP", "source": 0 }, + { + "begin": 9727, + "end": 9850, + "name": "PUSH [tag]", + "source": 0, + "value": "57" + }, + { + "begin": 9727, + "end": 9850, + "name": "PUSH [tag]", + "source": 0, + "value": "58" + }, + { + "begin": 9727, + "end": 9850, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9727, + "end": 9850, + "name": "tag", + "source": 0, + "value": "57" + }, + { "begin": 9727, "end": 9850, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9727, + "end": 9850, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9727, "end": 9850, "name": "MLOAD", "source": 0 }, + { + "begin": 9727, + "end": 9850, + "name": "PUSH [tag]", + "source": 0, + "value": "59" + }, + { "begin": 9727, "end": 9850, "name": "SWAP2", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "SWAP1", "source": 0 }, + { + "begin": 9727, + "end": 9850, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 9727, + "end": 9850, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9727, + "end": 9850, + "name": "tag", + "source": 0, + "value": "59" + }, + { "begin": 9727, "end": 9850, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9727, + "end": 9850, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9727, "end": 9850, "name": "MLOAD", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "DUP1", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "SWAP2", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "SUB", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "SWAP1", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "RETURN", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "tag", + "source": 0, + "value": "8" + }, + { "begin": 11419, "end": 11661, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "CALLVALUE", + "source": 0 + }, + { "begin": 11419, "end": 11661, "name": "DUP1", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "ISZERO", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "PUSH [tag]", + "source": 0, + "value": "60" + }, + { "begin": 11419, "end": 11661, "name": "JUMPI", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11419, "end": 11661, "name": "DUP1", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "REVERT", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "tag", + "source": 0, + "value": "60" + }, + { "begin": 11419, "end": 11661, "name": "JUMPDEST", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "POP", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "PUSH [tag]", + "source": 0, + "value": "61" + }, + { + "begin": 11419, + "end": 11661, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 11419, "end": 11661, "name": "DUP1", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 11419, "end": 11661, "name": "SUB", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "DUP2", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "ADD", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "SWAP1", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "PUSH [tag]", + "source": 0, + "value": "62" + }, + { "begin": 11419, "end": 11661, "name": "SWAP2", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "SWAP1", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "PUSH [tag]", + "source": 0, + "value": "63" + }, + { + "begin": 11419, + "end": 11661, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11419, + "end": 11661, + "name": "tag", + "source": 0, + "value": "62" + }, + { "begin": 11419, "end": 11661, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "PUSH [tag]", + "source": 0, + "value": "64" + }, + { + "begin": 11419, + "end": 11661, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11419, + "end": 11661, + "name": "tag", + "source": 0, + "value": "61" + }, + { "begin": 11419, "end": 11661, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11419, "end": 11661, "name": "MLOAD", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "PUSH [tag]", + "source": 0, + "value": "65" + }, + { "begin": 11419, "end": 11661, "name": "SWAP2", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "SWAP1", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 11419, + "end": 11661, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11419, + "end": 11661, + "name": "tag", + "source": 0, + "value": "65" + }, + { "begin": 11419, "end": 11661, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11419, "end": 11661, "name": "MLOAD", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "DUP1", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "SWAP2", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "SUB", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "SWAP1", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "RETURN", "source": 0 }, + { + "begin": 7862, + "end": 8067, + "name": "tag", + "source": 0, + "value": "9" + }, + { "begin": 7862, "end": 8067, "name": "JUMPDEST", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "CALLVALUE", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "DUP1", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "ISZERO", "source": 0 }, + { + "begin": 7862, + "end": 8067, + "name": "PUSH [tag]", + "source": 0, + "value": "66" + }, + { "begin": 7862, "end": 8067, "name": "JUMPI", "source": 0 }, + { + "begin": 7862, + "end": 8067, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7862, "end": 8067, "name": "DUP1", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "REVERT", "source": 0 }, + { + "begin": 7862, + "end": 8067, + "name": "tag", + "source": 0, + "value": "66" + }, + { "begin": 7862, "end": 8067, "name": "JUMPDEST", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "POP", "source": 0 }, + { + "begin": 7862, + "end": 8067, + "name": "PUSH [tag]", + "source": 0, + "value": "67" + }, + { + "begin": 7862, + "end": 8067, + "name": "PUSH [tag]", + "source": 0, + "value": "68" + }, + { + "begin": 7862, + "end": 8067, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7862, + "end": 8067, + "name": "tag", + "source": 0, + "value": "67" + }, + { "begin": 7862, "end": 8067, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7862, + "end": 8067, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7862, "end": 8067, "name": "MLOAD", "source": 0 }, + { + "begin": 7862, + "end": 8067, + "name": "PUSH [tag]", + "source": 0, + "value": "69" + }, + { "begin": 7862, "end": 8067, "name": "SWAP2", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "SWAP1", "source": 0 }, + { + "begin": 7862, + "end": 8067, + "name": "PUSH [tag]", + "source": 0, + "value": "70" + }, + { + "begin": 7862, + "end": 8067, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7862, + "end": 8067, + "name": "tag", + "source": 0, + "value": "69" + }, + { "begin": 7862, "end": 8067, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7862, + "end": 8067, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7862, "end": 8067, "name": "MLOAD", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "DUP1", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "SWAP2", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "SUB", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "SWAP1", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "RETURN", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "tag", + "source": 0, + "value": "10" + }, + { "begin": 8966, "end": 9111, "name": "JUMPDEST", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "CALLVALUE", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "DUP1", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "ISZERO", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "PUSH [tag]", + "source": 0, + "value": "71" + }, + { "begin": 8966, "end": 9111, "name": "JUMPI", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8966, "end": 9111, "name": "DUP1", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "REVERT", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "tag", + "source": 0, + "value": "71" + }, + { "begin": 8966, "end": 9111, "name": "JUMPDEST", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "POP", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "PUSH [tag]", + "source": 0, + "value": "72" + }, + { + "begin": 8966, + "end": 9111, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 8966, "end": 9111, "name": "DUP1", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 8966, "end": 9111, "name": "SUB", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "DUP2", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "ADD", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "SWAP1", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "PUSH [tag]", + "source": 0, + "value": "73" + }, + { "begin": 8966, "end": 9111, "name": "SWAP2", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "SWAP1", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "PUSH [tag]", + "source": 0, + "value": "47" + }, + { + "begin": 8966, + "end": 9111, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8966, + "end": 9111, + "name": "tag", + "source": 0, + "value": "73" + }, + { "begin": 8966, "end": 9111, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "PUSH [tag]", + "source": 0, + "value": "74" + }, + { + "begin": 8966, + "end": 9111, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8966, + "end": 9111, + "name": "tag", + "source": 0, + "value": "72" + }, + { "begin": 8966, "end": 9111, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8966, "end": 9111, "name": "MLOAD", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "PUSH [tag]", + "source": 0, + "value": "75" + }, + { "begin": 8966, "end": 9111, "name": "SWAP2", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "SWAP1", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 8966, + "end": 9111, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8966, + "end": 9111, + "name": "tag", + "source": 0, + "value": "75" + }, + { "begin": 8966, "end": 9111, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8966, "end": 9111, "name": "MLOAD", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "DUP1", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "SWAP2", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "SUB", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "SWAP1", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "RETURN", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "tag", + "source": 0, + "value": "11" + }, + { "begin": 9439, "end": 9572, "name": "JUMPDEST", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "CALLVALUE", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "DUP1", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "ISZERO", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "PUSH [tag]", + "source": 0, + "value": "76" + }, + { "begin": 9439, "end": 9572, "name": "JUMPI", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9439, "end": 9572, "name": "DUP1", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "REVERT", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "tag", + "source": 0, + "value": "76" + }, + { "begin": 9439, "end": 9572, "name": "JUMPDEST", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "POP", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "PUSH [tag]", + "source": 0, + "value": "77" + }, + { + "begin": 9439, + "end": 9572, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 9439, "end": 9572, "name": "DUP1", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 9439, "end": 9572, "name": "SUB", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "DUP2", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "ADD", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "SWAP1", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "PUSH [tag]", + "source": 0, + "value": "78" + }, + { "begin": 9439, "end": 9572, "name": "SWAP2", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "SWAP1", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "PUSH [tag]", + "source": 0, + "value": "79" + }, + { + "begin": 9439, + "end": 9572, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9439, + "end": 9572, + "name": "tag", + "source": 0, + "value": "78" + }, + { "begin": 9439, "end": 9572, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "PUSH [tag]", + "source": 0, + "value": "80" + }, + { + "begin": 9439, + "end": 9572, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9439, + "end": 9572, + "name": "tag", + "source": 0, + "value": "77" + }, + { "begin": 9439, "end": 9572, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9439, "end": 9572, "name": "MLOAD", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "PUSH [tag]", + "source": 0, + "value": "81" + }, + { "begin": 9439, "end": 9572, "name": "SWAP2", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "SWAP1", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 9439, + "end": 9572, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9439, + "end": 9572, + "name": "tag", + "source": 0, + "value": "81" + }, + { "begin": 9439, "end": 9572, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9439, "end": 9572, "name": "MLOAD", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "DUP1", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "SWAP2", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "SUB", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "SWAP1", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "RETURN", "source": 0 }, + { + "begin": 9586, + "end": 9713, + "name": "tag", + "source": 0, + "value": "12" + }, + { "begin": 9586, "end": 9713, "name": "JUMPDEST", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "CALLVALUE", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "DUP1", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "ISZERO", "source": 0 }, + { + "begin": 9586, + "end": 9713, + "name": "PUSH [tag]", + "source": 0, + "value": "82" + }, + { "begin": 9586, "end": 9713, "name": "JUMPI", "source": 0 }, + { + "begin": 9586, + "end": 9713, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9586, "end": 9713, "name": "DUP1", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "REVERT", "source": 0 }, + { + "begin": 9586, + "end": 9713, + "name": "tag", + "source": 0, + "value": "82" + }, + { "begin": 9586, "end": 9713, "name": "JUMPDEST", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "POP", "source": 0 }, + { + "begin": 9586, + "end": 9713, + "name": "PUSH [tag]", + "source": 0, + "value": "83" + }, + { + "begin": 9586, + "end": 9713, + "name": "PUSH [tag]", + "source": 0, + "value": "84" + }, + { + "begin": 9586, + "end": 9713, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9586, + "end": 9713, + "name": "tag", + "source": 0, + "value": "83" + }, + { "begin": 9586, "end": 9713, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9586, + "end": 9713, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9586, "end": 9713, "name": "MLOAD", "source": 0 }, + { + "begin": 9586, + "end": 9713, + "name": "PUSH [tag]", + "source": 0, + "value": "85" + }, + { "begin": 9586, "end": 9713, "name": "SWAP2", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "SWAP1", "source": 0 }, + { + "begin": 9586, + "end": 9713, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 9586, + "end": 9713, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9586, + "end": 9713, + "name": "tag", + "source": 0, + "value": "85" + }, + { "begin": 9586, "end": 9713, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9586, + "end": 9713, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9586, "end": 9713, "name": "MLOAD", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "DUP1", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "SWAP2", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "SUB", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "SWAP1", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "RETURN", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "tag", + "source": 0, + "value": "13" + }, + { "begin": 8319, "end": 8541, "name": "JUMPDEST", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "CALLVALUE", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "DUP1", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "ISZERO", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "PUSH [tag]", + "source": 0, + "value": "86" + }, + { "begin": 8319, "end": 8541, "name": "JUMPI", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8319, "end": 8541, "name": "DUP1", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "REVERT", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "tag", + "source": 0, + "value": "86" + }, + { "begin": 8319, "end": 8541, "name": "JUMPDEST", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "POP", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "PUSH [tag]", + "source": 0, + "value": "87" + }, + { + "begin": 8319, + "end": 8541, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 8319, "end": 8541, "name": "DUP1", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 8319, "end": 8541, "name": "SUB", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "DUP2", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "ADD", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "SWAP1", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "PUSH [tag]", + "source": 0, + "value": "88" + }, + { "begin": 8319, "end": 8541, "name": "SWAP2", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "SWAP1", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "PUSH [tag]", + "source": 0, + "value": "79" + }, + { + "begin": 8319, + "end": 8541, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8319, + "end": 8541, + "name": "tag", + "source": 0, + "value": "88" + }, + { "begin": 8319, "end": 8541, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "PUSH [tag]", + "source": 0, + "value": "89" + }, + { + "begin": 8319, + "end": 8541, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8319, + "end": 8541, + "name": "tag", + "source": 0, + "value": "87" + }, + { "begin": 8319, "end": 8541, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8319, "end": 8541, "name": "MLOAD", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "PUSH [tag]", + "source": 0, + "value": "90" + }, + { "begin": 8319, "end": 8541, "name": "SWAP2", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "SWAP1", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "PUSH [tag]", + "source": 0, + "value": "55" + }, + { + "begin": 8319, + "end": 8541, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8319, + "end": 8541, + "name": "tag", + "source": 0, + "value": "90" + }, + { "begin": 8319, "end": 8541, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8319, "end": 8541, "name": "MLOAD", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "DUP1", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "SWAP2", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "SUB", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "SWAP1", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "RETURN", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "tag", + "source": 0, + "value": "14" + }, + { "begin": 11687, "end": 12058, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "CALLVALUE", + "source": 0 + }, + { "begin": 11687, "end": 12058, "name": "DUP1", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "ISZERO", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "PUSH [tag]", + "source": 0, + "value": "91" + }, + { "begin": 11687, "end": 12058, "name": "JUMPI", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11687, "end": 12058, "name": "DUP1", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "REVERT", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "tag", + "source": 0, + "value": "91" + }, + { "begin": 11687, "end": 12058, "name": "JUMPDEST", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "POP", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "PUSH [tag]", + "source": 0, + "value": "92" + }, + { + "begin": 11687, + "end": 12058, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 11687, "end": 12058, "name": "DUP1", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 11687, "end": 12058, "name": "SUB", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "DUP2", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "ADD", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "SWAP1", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "PUSH [tag]", + "source": 0, + "value": "93" + }, + { "begin": 11687, "end": 12058, "name": "SWAP2", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "SWAP1", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "PUSH [tag]", + "source": 0, + "value": "63" + }, + { + "begin": 11687, + "end": 12058, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11687, + "end": 12058, + "name": "tag", + "source": 0, + "value": "93" + }, + { "begin": 11687, "end": 12058, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "PUSH [tag]", + "source": 0, + "value": "94" + }, + { + "begin": 11687, + "end": 12058, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11687, + "end": 12058, + "name": "tag", + "source": 0, + "value": "92" + }, + { "begin": 11687, "end": 12058, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11687, "end": 12058, "name": "MLOAD", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "PUSH [tag]", + "source": 0, + "value": "95" + }, + { "begin": 11687, "end": 12058, "name": "SWAP2", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "SWAP1", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 11687, + "end": 12058, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11687, + "end": 12058, + "name": "tag", + "source": 0, + "value": "95" + }, + { "begin": 11687, "end": 12058, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11687, "end": 12058, "name": "MLOAD", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "DUP1", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "SWAP2", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "SUB", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "SWAP1", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "RETURN", "source": 0 }, + { + "begin": 7039, + "end": 7254, + "name": "tag", + "source": 0, + "value": "15" + }, + { "begin": 7039, "end": 7254, "name": "JUMPDEST", "source": 0 }, + { "begin": 7039, "end": 7254, "name": "CALLVALUE", "source": 0 }, + { "begin": 7039, "end": 7254, "name": "DUP1", "source": 0 }, + { "begin": 7039, "end": 7254, "name": "ISZERO", "source": 0 }, + { + "begin": 7039, + "end": 7254, + "name": "PUSH [tag]", + "source": 0, + "value": "96" + }, + { "begin": 7039, "end": 7254, "name": "JUMPI", "source": 0 }, + { + "begin": 7039, + "end": 7254, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7039, "end": 7254, "name": "DUP1", "source": 0 }, + { "begin": 7039, "end": 7254, "name": "REVERT", "source": 0 }, + { + "begin": 7039, + "end": 7254, + "name": "tag", + "source": 0, + "value": "96" + }, + { "begin": 7039, "end": 7254, "name": "JUMPDEST", "source": 0 }, + { "begin": 7039, "end": 7254, "name": "POP", "source": 0 }, + { + "begin": 7039, + "end": 7254, + "name": "PUSH [tag]", + "source": 0, + "value": "97" + }, + { + "begin": 7039, + "end": 7254, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 7039, "end": 7254, "name": "DUP1", "source": 0 }, + { + "begin": 7039, + "end": 7254, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 7039, "end": 7254, "name": "SUB", "source": 0 }, + { "begin": 7039, "end": 7254, "name": "DUP2", "source": 0 }, + { "begin": 7039, "end": 7254, "name": "ADD", "source": 0 }, + { "begin": 7039, "end": 7254, "name": "SWAP1", "source": 0 }, + { + "begin": 7039, + "end": 7254, + "name": "PUSH [tag]", + "source": 0, + "value": "98" + }, + { "begin": 7039, "end": 7254, "name": "SWAP2", "source": 0 }, + { "begin": 7039, "end": 7254, "name": "SWAP1", "source": 0 }, + { + "begin": 7039, + "end": 7254, + "name": "PUSH [tag]", + "source": 0, + "value": "79" + }, + { + "begin": 7039, + "end": 7254, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7039, + "end": 7254, + "name": "tag", + "source": 0, + "value": "98" + }, + { "begin": 7039, "end": 7254, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7039, + "end": 7254, + "name": "PUSH [tag]", + "source": 0, + "value": "99" + }, + { + "begin": 7039, + "end": 7254, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7039, + "end": 7254, + "name": "tag", + "source": 0, + "value": "97" + }, + { "begin": 7039, "end": 7254, "name": "JUMPDEST", "source": 0 }, + { "begin": 7039, "end": 7254, "name": "STOP", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "tag", + "source": 0, + "value": "16" + }, + { "begin": 9288, "end": 9425, "name": "JUMPDEST", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "CALLVALUE", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "DUP1", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "ISZERO", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "PUSH [tag]", + "source": 0, + "value": "100" + }, + { "begin": 9288, "end": 9425, "name": "JUMPI", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9288, "end": 9425, "name": "DUP1", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "REVERT", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "tag", + "source": 0, + "value": "100" + }, + { "begin": 9288, "end": 9425, "name": "JUMPDEST", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "POP", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "PUSH [tag]", + "source": 0, + "value": "101" + }, + { + "begin": 9288, + "end": 9425, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 9288, "end": 9425, "name": "DUP1", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 9288, "end": 9425, "name": "SUB", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "DUP2", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "ADD", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "SWAP1", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "PUSH [tag]", + "source": 0, + "value": "102" + }, + { "begin": 9288, "end": 9425, "name": "SWAP2", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "SWAP1", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "PUSH [tag]", + "source": 0, + "value": "79" + }, + { + "begin": 9288, + "end": 9425, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9288, + "end": 9425, + "name": "tag", + "source": 0, + "value": "102" + }, + { "begin": 9288, "end": 9425, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "PUSH [tag]", + "source": 0, + "value": "103" + }, + { + "begin": 9288, + "end": 9425, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9288, + "end": 9425, + "name": "tag", + "source": 0, + "value": "101" + }, + { "begin": 9288, "end": 9425, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9288, "end": 9425, "name": "MLOAD", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "PUSH [tag]", + "source": 0, + "value": "104" + }, + { "begin": 9288, "end": 9425, "name": "SWAP2", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "SWAP1", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 9288, + "end": 9425, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9288, + "end": 9425, + "name": "tag", + "source": 0, + "value": "104" + }, + { "begin": 9288, "end": 9425, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9288, "end": 9425, "name": "MLOAD", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "DUP1", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "SWAP2", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "SUB", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "SWAP1", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "RETURN", "source": 0 }, + { + "begin": 7627, + "end": 7836, + "name": "tag", + "source": 0, + "value": "17" + }, + { "begin": 7627, "end": 7836, "name": "JUMPDEST", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "CALLVALUE", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "DUP1", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "ISZERO", "source": 0 }, + { + "begin": 7627, + "end": 7836, + "name": "PUSH [tag]", + "source": 0, + "value": "105" + }, + { "begin": 7627, "end": 7836, "name": "JUMPI", "source": 0 }, + { + "begin": 7627, + "end": 7836, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7627, "end": 7836, "name": "DUP1", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "REVERT", "source": 0 }, + { + "begin": 7627, + "end": 7836, + "name": "tag", + "source": 0, + "value": "105" + }, + { "begin": 7627, "end": 7836, "name": "JUMPDEST", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "POP", "source": 0 }, + { + "begin": 7627, + "end": 7836, + "name": "PUSH [tag]", + "source": 0, + "value": "106" + }, + { + "begin": 7627, + "end": 7836, + "name": "PUSH [tag]", + "source": 0, + "value": "107" + }, + { + "begin": 7627, + "end": 7836, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7627, + "end": 7836, + "name": "tag", + "source": 0, + "value": "106" + }, + { "begin": 7627, "end": 7836, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7627, + "end": 7836, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7627, "end": 7836, "name": "MLOAD", "source": 0 }, + { + "begin": 7627, + "end": 7836, + "name": "PUSH [tag]", + "source": 0, + "value": "108" + }, + { "begin": 7627, "end": 7836, "name": "SWAP2", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "SWAP1", "source": 0 }, + { + "begin": 7627, + "end": 7836, + "name": "PUSH [tag]", + "source": 0, + "value": "43" + }, + { + "begin": 7627, + "end": 7836, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7627, + "end": 7836, + "name": "tag", + "source": 0, + "value": "108" + }, + { "begin": 7627, "end": 7836, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7627, + "end": 7836, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7627, "end": 7836, "name": "MLOAD", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "DUP1", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "SWAP2", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "SUB", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "SWAP1", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "RETURN", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "tag", + "source": 0, + "value": "18" + }, + { "begin": 6727, "end": 6843, "name": "JUMPDEST", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "CALLVALUE", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "DUP1", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "ISZERO", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH [tag]", + "source": 0, + "value": "109" + }, + { "begin": 6727, "end": 6843, "name": "JUMPI", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 6727, "end": 6843, "name": "DUP1", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "REVERT", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "tag", + "source": 0, + "value": "109" + }, + { "begin": 6727, "end": 6843, "name": "JUMPDEST", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "POP", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH [tag]", + "source": 0, + "value": "110" + }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH [tag]", + "source": 0, + "value": "111" + }, + { + "begin": 6727, + "end": 6843, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 6727, + "end": 6843, + "name": "tag", + "source": 0, + "value": "110" + }, + { "begin": 6727, "end": 6843, "name": "JUMPDEST", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 6727, "end": 6843, "name": "MLOAD", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH [tag]", + "source": 0, + "value": "112" + }, + { "begin": 6727, "end": 6843, "name": "SWAP2", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "SWAP1", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH [tag]", + "source": 0, + "value": "113" + }, + { + "begin": 6727, + "end": 6843, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 6727, + "end": 6843, + "name": "tag", + "source": 0, + "value": "112" + }, + { "begin": 6727, "end": 6843, "name": "JUMPDEST", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 6727, "end": 6843, "name": "MLOAD", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "DUP1", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "SWAP2", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "SUB", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "SWAP1", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "RETURN", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "tag", + "source": 0, + "value": "19" + }, + { "begin": 9125, "end": 9274, "name": "JUMPDEST", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "CALLVALUE", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "DUP1", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "ISZERO", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "PUSH [tag]", + "source": 0, + "value": "114" + }, + { "begin": 9125, "end": 9274, "name": "JUMPI", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9125, "end": 9274, "name": "DUP1", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "REVERT", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "tag", + "source": 0, + "value": "114" + }, + { "begin": 9125, "end": 9274, "name": "JUMPDEST", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "POP", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "PUSH [tag]", + "source": 0, + "value": "115" + }, + { + "begin": 9125, + "end": 9274, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 9125, "end": 9274, "name": "DUP1", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 9125, "end": 9274, "name": "SUB", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "DUP2", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "ADD", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "SWAP1", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "PUSH [tag]", + "source": 0, + "value": "116" + }, + { "begin": 9125, "end": 9274, "name": "SWAP2", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "SWAP1", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "PUSH [tag]", + "source": 0, + "value": "47" + }, + { + "begin": 9125, + "end": 9274, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9125, + "end": 9274, + "name": "tag", + "source": 0, + "value": "116" + }, + { "begin": 9125, "end": 9274, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "PUSH [tag]", + "source": 0, + "value": "117" + }, + { + "begin": 9125, + "end": 9274, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9125, + "end": 9274, + "name": "tag", + "source": 0, + "value": "115" + }, + { "begin": 9125, "end": 9274, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9125, "end": 9274, "name": "MLOAD", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "PUSH [tag]", + "source": 0, + "value": "118" + }, + { "begin": 9125, "end": 9274, "name": "SWAP2", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "SWAP1", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 9125, + "end": 9274, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9125, + "end": 9274, + "name": "tag", + "source": 0, + "value": "118" + }, + { "begin": 9125, "end": 9274, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9125, "end": 9274, "name": "MLOAD", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "DUP1", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "SWAP2", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "SUB", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "SWAP1", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "RETURN", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "tag", + "source": 0, + "value": "20" + }, + { "begin": 10616, "end": 10902, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "CALLVALUE", + "source": 0 + }, + { "begin": 10616, "end": 10902, "name": "DUP1", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "ISZERO", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "PUSH [tag]", + "source": 0, + "value": "119" + }, + { "begin": 10616, "end": 10902, "name": "JUMPI", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10616, "end": 10902, "name": "DUP1", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "REVERT", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "tag", + "source": 0, + "value": "119" + }, + { "begin": 10616, "end": 10902, "name": "JUMPDEST", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "POP", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "PUSH [tag]", + "source": 0, + "value": "120" + }, + { + "begin": 10616, + "end": 10902, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 10616, "end": 10902, "name": "DUP1", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 10616, "end": 10902, "name": "SUB", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "DUP2", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "ADD", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "SWAP1", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "PUSH [tag]", + "source": 0, + "value": "121" + }, + { "begin": 10616, "end": 10902, "name": "SWAP2", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "SWAP1", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "PUSH [tag]", + "source": 0, + "value": "47" + }, + { + "begin": 10616, + "end": 10902, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10616, + "end": 10902, + "name": "tag", + "source": 0, + "value": "121" + }, + { "begin": 10616, "end": 10902, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "PUSH [tag]", + "source": 0, + "value": "122" + }, + { + "begin": 10616, + "end": 10902, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10616, + "end": 10902, + "name": "tag", + "source": 0, + "value": "120" + }, + { "begin": 10616, "end": 10902, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10616, "end": 10902, "name": "MLOAD", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "PUSH [tag]", + "source": 0, + "value": "123" + }, + { "begin": 10616, "end": 10902, "name": "SWAP2", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "SWAP1", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 10616, + "end": 10902, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10616, + "end": 10902, + "name": "tag", + "source": 0, + "value": "123" + }, + { "begin": 10616, "end": 10902, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10616, "end": 10902, "name": "MLOAD", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "DUP1", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "SWAP2", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "SUB", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "SWAP1", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "RETURN", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "tag", + "source": 0, + "value": "21" + }, + { "begin": 8799, "end": 8952, "name": "JUMPDEST", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "CALLVALUE", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "DUP1", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "ISZERO", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "PUSH [tag]", + "source": 0, + "value": "124" + }, + { "begin": 8799, "end": 8952, "name": "JUMPI", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8799, "end": 8952, "name": "DUP1", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "REVERT", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "tag", + "source": 0, + "value": "124" + }, + { "begin": 8799, "end": 8952, "name": "JUMPDEST", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "POP", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "PUSH [tag]", + "source": 0, + "value": "125" + }, + { + "begin": 8799, + "end": 8952, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 8799, "end": 8952, "name": "DUP1", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 8799, "end": 8952, "name": "SUB", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "DUP2", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "ADD", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "SWAP1", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "PUSH [tag]", + "source": 0, + "value": "126" + }, + { "begin": 8799, "end": 8952, "name": "SWAP2", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "SWAP1", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "PUSH [tag]", + "source": 0, + "value": "47" + }, + { + "begin": 8799, + "end": 8952, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8799, + "end": 8952, + "name": "tag", + "source": 0, + "value": "126" + }, + { "begin": 8799, "end": 8952, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "PUSH [tag]", + "source": 0, + "value": "127" + }, + { + "begin": 8799, + "end": 8952, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8799, + "end": 8952, + "name": "tag", + "source": 0, + "value": "125" + }, + { "begin": 8799, "end": 8952, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8799, "end": 8952, "name": "MLOAD", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "PUSH [tag]", + "source": 0, + "value": "128" + }, + { "begin": 8799, "end": 8952, "name": "SWAP2", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "SWAP1", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 8799, + "end": 8952, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8799, + "end": 8952, + "name": "tag", + "source": 0, + "value": "128" + }, + { "begin": 8799, "end": 8952, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8799, "end": 8952, "name": "MLOAD", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "DUP1", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "SWAP2", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "SUB", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "SWAP1", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "RETURN", "source": 0 }, + { + "begin": 10459, + "end": 10590, + "name": "tag", + "source": 0, + "value": "22" + }, + { "begin": 10459, "end": 10590, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10459, + "end": 10590, + "name": "CALLVALUE", + "source": 0 + }, + { "begin": 10459, "end": 10590, "name": "DUP1", "source": 0 }, + { "begin": 10459, "end": 10590, "name": "ISZERO", "source": 0 }, + { + "begin": 10459, + "end": 10590, + "name": "PUSH [tag]", + "source": 0, + "value": "129" + }, + { "begin": 10459, "end": 10590, "name": "JUMPI", "source": 0 }, + { + "begin": 10459, + "end": 10590, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10459, "end": 10590, "name": "DUP1", "source": 0 }, + { "begin": 10459, "end": 10590, "name": "REVERT", "source": 0 }, + { + "begin": 10459, + "end": 10590, + "name": "tag", + "source": 0, + "value": "129" + }, + { "begin": 10459, "end": 10590, "name": "JUMPDEST", "source": 0 }, + { "begin": 10459, "end": 10590, "name": "POP", "source": 0 }, + { + "begin": 10459, + "end": 10590, + "name": "PUSH [tag]", + "source": 0, + "value": "130" + }, + { + "begin": 10459, + "end": 10590, + "name": "PUSH [tag]", + "source": 0, + "value": "131" + }, + { + "begin": 10459, + "end": 10590, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10459, + "end": 10590, + "name": "tag", + "source": 0, + "value": "130" + }, + { "begin": 10459, "end": 10590, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10459, + "end": 10590, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10459, "end": 10590, "name": "MLOAD", "source": 0 }, + { + "begin": 10459, + "end": 10590, + "name": "PUSH [tag]", + "source": 0, + "value": "132" + }, + { "begin": 10459, "end": 10590, "name": "SWAP2", "source": 0 }, + { "begin": 10459, "end": 10590, "name": "SWAP1", "source": 0 }, + { + "begin": 10459, + "end": 10590, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 10459, + "end": 10590, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10459, + "end": 10590, + "name": "tag", + "source": 0, + "value": "132" + }, + { "begin": 10459, "end": 10590, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10459, + "end": 10590, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10459, "end": 10590, "name": "MLOAD", "source": 0 }, + { "begin": 10459, "end": 10590, "name": "DUP1", "source": 0 }, + { "begin": 10459, "end": 10590, "name": "SWAP2", "source": 0 }, + { "begin": 10459, "end": 10590, "name": "SUB", "source": 0 }, + { "begin": 10459, "end": 10590, "name": "SWAP1", "source": 0 }, + { "begin": 10459, "end": 10590, "name": "RETURN", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "tag", + "source": 0, + "value": "23" + }, + { "begin": 8567, "end": 8785, "name": "JUMPDEST", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "CALLVALUE", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "DUP1", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "ISZERO", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "PUSH [tag]", + "source": 0, + "value": "133" + }, + { "begin": 8567, "end": 8785, "name": "JUMPI", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8567, "end": 8785, "name": "DUP1", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "REVERT", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "tag", + "source": 0, + "value": "133" + }, + { "begin": 8567, "end": 8785, "name": "JUMPDEST", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "POP", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "PUSH [tag]", + "source": 0, + "value": "134" + }, + { + "begin": 8567, + "end": 8785, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 8567, "end": 8785, "name": "DUP1", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 8567, "end": 8785, "name": "SUB", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "DUP2", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "ADD", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "SWAP1", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "PUSH [tag]", + "source": 0, + "value": "135" + }, + { "begin": 8567, "end": 8785, "name": "SWAP2", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "SWAP1", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "PUSH [tag]", + "source": 0, + "value": "136" + }, + { + "begin": 8567, + "end": 8785, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8567, + "end": 8785, + "name": "tag", + "source": 0, + "value": "135" + }, + { "begin": 8567, "end": 8785, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "PUSH [tag]", + "source": 0, + "value": "137" + }, + { + "begin": 8567, + "end": 8785, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8567, + "end": 8785, + "name": "tag", + "source": 0, + "value": "134" + }, + { "begin": 8567, "end": 8785, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8567, "end": 8785, "name": "MLOAD", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "PUSH [tag]", + "source": 0, + "value": "138" + }, + { "begin": 8567, "end": 8785, "name": "SWAP2", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "SWAP1", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "PUSH [tag]", + "source": 0, + "value": "55" + }, + { + "begin": 8567, + "end": 8785, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8567, + "end": 8785, + "name": "tag", + "source": 0, + "value": "138" + }, + { "begin": 8567, "end": 8785, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8567, "end": 8785, "name": "MLOAD", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "DUP1", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "SWAP2", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "SUB", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "SWAP1", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "RETURN", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "tag", + "source": 0, + "value": "24" + }, + { "begin": 10236, "end": 10445, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "CALLVALUE", + "source": 0 + }, + { "begin": 10236, "end": 10445, "name": "DUP1", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "ISZERO", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "PUSH [tag]", + "source": 0, + "value": "139" + }, + { "begin": 10236, "end": 10445, "name": "JUMPI", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10236, "end": 10445, "name": "DUP1", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "REVERT", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "tag", + "source": 0, + "value": "139" + }, + { "begin": 10236, "end": 10445, "name": "JUMPDEST", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "POP", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "PUSH [tag]", + "source": 0, + "value": "140" + }, + { + "begin": 10236, + "end": 10445, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 10236, "end": 10445, "name": "DUP1", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 10236, "end": 10445, "name": "SUB", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "DUP2", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "ADD", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "SWAP1", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "PUSH [tag]", + "source": 0, + "value": "141" + }, + { "begin": 10236, "end": 10445, "name": "SWAP2", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "SWAP1", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "PUSH [tag]", + "source": 0, + "value": "142" + }, + { + "begin": 10236, + "end": 10445, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10236, + "end": 10445, + "name": "tag", + "source": 0, + "value": "141" + }, + { "begin": 10236, "end": 10445, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "PUSH [tag]", + "source": 0, + "value": "143" + }, + { + "begin": 10236, + "end": 10445, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10236, + "end": 10445, + "name": "tag", + "source": 0, + "value": "140" + }, + { "begin": 10236, "end": 10445, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10236, "end": 10445, "name": "MLOAD", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "PUSH [tag]", + "source": 0, + "value": "144" + }, + { "begin": 10236, "end": 10445, "name": "SWAP2", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "SWAP1", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 10236, + "end": 10445, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10236, + "end": 10445, + "name": "tag", + "source": 0, + "value": "144" + }, + { "begin": 10236, "end": 10445, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10236, "end": 10445, "name": "MLOAD", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "DUP1", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "SWAP2", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "SUB", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "SWAP1", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "RETURN", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "tag", + "source": 0, + "value": "25" + }, + { "begin": 9864, "end": 10021, "name": "JUMPDEST", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "CALLVALUE", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "DUP1", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "ISZERO", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "PUSH [tag]", + "source": 0, + "value": "145" + }, + { "begin": 9864, "end": 10021, "name": "JUMPI", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9864, "end": 10021, "name": "DUP1", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "REVERT", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "tag", + "source": 0, + "value": "145" + }, + { "begin": 9864, "end": 10021, "name": "JUMPDEST", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "POP", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "PUSH [tag]", + "source": 0, + "value": "146" + }, + { + "begin": 9864, + "end": 10021, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 9864, "end": 10021, "name": "DUP1", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 9864, "end": 10021, "name": "SUB", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "DUP2", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "ADD", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "SWAP1", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "PUSH [tag]", + "source": 0, + "value": "147" + }, + { "begin": 9864, "end": 10021, "name": "SWAP2", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "SWAP1", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "PUSH [tag]", + "source": 0, + "value": "79" + }, + { + "begin": 9864, + "end": 10021, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9864, + "end": 10021, + "name": "tag", + "source": 0, + "value": "147" + }, + { "begin": 9864, "end": 10021, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "PUSH [tag]", + "source": 0, + "value": "148" + }, + { + "begin": 9864, + "end": 10021, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9864, + "end": 10021, + "name": "tag", + "source": 0, + "value": "146" + }, + { "begin": 9864, "end": 10021, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9864, "end": 10021, "name": "MLOAD", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "PUSH [tag]", + "source": 0, + "value": "149" + }, + { "begin": 9864, "end": 10021, "name": "SWAP2", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "SWAP1", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 9864, + "end": 10021, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9864, + "end": 10021, + "name": "tag", + "source": 0, + "value": "149" + }, + { "begin": 9864, "end": 10021, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9864, "end": 10021, "name": "MLOAD", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "DUP1", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "SWAP2", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "SUB", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "SWAP1", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "RETURN", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "tag", + "source": 0, + "value": "26" + }, + { "begin": 11099, "end": 11393, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "CALLVALUE", + "source": 0 + }, + { "begin": 11099, "end": 11393, "name": "DUP1", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "ISZERO", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "PUSH [tag]", + "source": 0, + "value": "150" + }, + { "begin": 11099, "end": 11393, "name": "JUMPI", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11099, "end": 11393, "name": "DUP1", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "REVERT", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "tag", + "source": 0, + "value": "150" + }, + { "begin": 11099, "end": 11393, "name": "JUMPDEST", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "POP", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "PUSH [tag]", + "source": 0, + "value": "151" + }, + { + "begin": 11099, + "end": 11393, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 11099, "end": 11393, "name": "DUP1", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 11099, "end": 11393, "name": "SUB", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "DUP2", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "ADD", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "SWAP1", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "PUSH [tag]", + "source": 0, + "value": "152" + }, + { "begin": 11099, "end": 11393, "name": "SWAP2", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "SWAP1", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "PUSH [tag]", + "source": 0, + "value": "47" + }, + { + "begin": 11099, + "end": 11393, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11099, + "end": 11393, + "name": "tag", + "source": 0, + "value": "152" + }, + { "begin": 11099, "end": 11393, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "PUSH [tag]", + "source": 0, + "value": "153" + }, + { + "begin": 11099, + "end": 11393, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11099, + "end": 11393, + "name": "tag", + "source": 0, + "value": "151" + }, + { "begin": 11099, "end": 11393, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11099, "end": 11393, "name": "MLOAD", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "PUSH [tag]", + "source": 0, + "value": "154" + }, + { "begin": 11099, "end": 11393, "name": "SWAP2", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "SWAP1", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 11099, + "end": 11393, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11099, + "end": 11393, + "name": "tag", + "source": 0, + "value": "154" + }, + { "begin": 11099, "end": 11393, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11099, "end": 11393, "name": "MLOAD", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "DUP1", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "SWAP2", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "SUB", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "SWAP1", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "RETURN", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "tag", + "source": 0, + "value": "27" + }, + { "begin": 10035, "end": 10222, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "CALLVALUE", + "source": 0 + }, + { "begin": 10035, "end": 10222, "name": "DUP1", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "ISZERO", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "PUSH [tag]", + "source": 0, + "value": "155" + }, + { "begin": 10035, "end": 10222, "name": "JUMPI", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10035, "end": 10222, "name": "DUP1", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "REVERT", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "tag", + "source": 0, + "value": "155" + }, + { "begin": 10035, "end": 10222, "name": "JUMPDEST", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "POP", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "PUSH [tag]", + "source": 0, + "value": "156" + }, + { + "begin": 10035, + "end": 10222, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 10035, "end": 10222, "name": "DUP1", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "CALLDATASIZE", + "source": 0 + }, + { "begin": 10035, "end": 10222, "name": "SUB", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "DUP2", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "ADD", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "SWAP1", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "PUSH [tag]", + "source": 0, + "value": "157" + }, + { "begin": 10035, "end": 10222, "name": "SWAP2", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "SWAP1", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "PUSH [tag]", + "source": 0, + "value": "158" + }, + { + "begin": 10035, + "end": 10222, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10035, + "end": 10222, + "name": "tag", + "source": 0, + "value": "157" + }, + { "begin": 10035, "end": 10222, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "PUSH [tag]", + "source": 0, + "value": "159" + }, + { + "begin": 10035, + "end": 10222, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10035, + "end": 10222, + "name": "tag", + "source": 0, + "value": "156" + }, + { "begin": 10035, "end": 10222, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10035, "end": 10222, "name": "MLOAD", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "PUSH [tag]", + "source": 0, + "value": "160" + }, + { "begin": 10035, "end": 10222, "name": "SWAP2", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "SWAP1", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "PUSH [tag]", + "source": 0, + "value": "50" + }, + { + "begin": 10035, + "end": 10222, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10035, + "end": 10222, + "name": "tag", + "source": 0, + "value": "160" + }, + { "begin": 10035, "end": 10222, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10035, "end": 10222, "name": "MLOAD", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "DUP1", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "SWAP2", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "SUB", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "SWAP1", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "RETURN", "source": 0 }, + { + "begin": 7268, + "end": 7382, + "name": "tag", + "source": 0, + "value": "36" + }, + { "begin": 7268, "end": 7382, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7311, + "end": 7318, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 7345, + "end": 7367, + "name": "PUSH", + "source": 0, + "value": "1" + }, + { + "begin": 7345, + "end": 7367, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7345, "end": 7367, "name": "SWAP1", "source": 0 }, + { "begin": 7345, "end": 7367, "name": "SLOAD", "source": 0 }, + { "begin": 7345, "end": 7367, "name": "SWAP1", "source": 0 }, + { + "begin": 7345, + "end": 7367, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 7345, "end": 7367, "name": "EXP", "source": 0 }, + { "begin": 7345, "end": 7367, "name": "SWAP1", "source": 0 }, + { "begin": 7345, "end": 7367, "name": "DIV", "source": 0 }, + { + "begin": 7345, + "end": 7367, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 7345, "end": 7367, "name": "AND", "source": 0 }, + { "begin": 7338, "end": 7367, "name": "SWAP1", "source": 0 }, + { "begin": 7338, "end": 7367, "name": "POP", "source": 0 }, + { "begin": 7268, "end": 7382, "name": "SWAP1", "source": 0 }, + { + "begin": 7268, + "end": 7382, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 7396, + "end": 7601, + "name": "tag", + "source": 0, + "value": "41" + }, + { "begin": 7396, "end": 7601, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7444, + "end": 7457, + "name": "PUSH", + "source": 0, + "value": "60" + }, + { + "begin": 7564, + "end": 7579, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7564, "end": 7579, "name": "DUP1", "source": 0 }, + { "begin": 7564, "end": 7579, "name": "SLOAD", "source": 0 }, + { "begin": 7564, "end": 7579, "name": "SWAP1", "source": 0 }, + { + "begin": 7564, + "end": 7579, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 7564, "end": 7579, "name": "EXP", "source": 0 }, + { "begin": 7564, "end": 7579, "name": "SWAP1", "source": 0 }, + { "begin": 7564, "end": 7579, "name": "DIV", "source": 0 }, + { + "begin": 7564, + "end": 7579, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 7564, "end": 7579, "name": "AND", "source": 0 }, + { + "begin": 7564, + "end": 7584, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 7564, "end": 7584, "name": "AND", "source": 0 }, + { + "begin": 7564, + "end": 7584, + "name": "PUSH", + "source": 0, + "value": "6FDDE03" + }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7564, "end": 7586, "name": "MLOAD", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "DUP2", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 7564, "end": 7586, "name": "AND", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 7564, "end": 7586, "name": "SHL", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "DUP2", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "MSTORE", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 7564, "end": 7586, "name": "ADD", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7564, "end": 7586, "name": "MLOAD", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "DUP1", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "DUP4", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "SUB", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "DUP2", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "DUP7", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "GAS", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "STATICCALL", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "ISZERO", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "DUP1", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "ISZERO", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH [tag]", + "source": 0, + "value": "164" + }, + { "begin": 7564, "end": 7586, "name": "JUMPI", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7564, "end": 7586, "name": "DUP1", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 7564, + "end": 7586, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7564, "end": 7586, "name": "REVERT", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "tag", + "source": 0, + "value": "164" + }, + { "begin": 7564, "end": 7586, "name": "JUMPDEST", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "POP", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "POP", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "POP", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "POP", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7564, "end": 7586, "name": "MLOAD", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7564, "end": 7586, "name": "DUP3", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 7564, + "end": 7586, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 7564, "end": 7586, "name": "NOT", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 7564, "end": 7586, "name": "DUP3", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "ADD", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "AND", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "DUP3", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "ADD", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "DUP1", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7564, "end": 7586, "name": "MSTORE", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "POP", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "DUP2", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "ADD", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "SWAP1", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH [tag]", + "source": 0, + "value": "165" + }, + { "begin": 7564, "end": 7586, "name": "SWAP2", "source": 0 }, + { "begin": 7564, "end": 7586, "name": "SWAP1", "source": 0 }, + { + "begin": 7564, + "end": 7586, + "name": "PUSH [tag]", + "source": 0, + "value": "166" + }, + { + "begin": 7564, + "end": 7586, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7564, + "end": 7586, + "name": "tag", + "source": 0, + "value": "165" + }, + { "begin": 7564, "end": 7586, "name": "JUMPDEST", "source": 0 }, + { "begin": 7557, "end": 7586, "name": "SWAP1", "source": 0 }, + { "begin": 7557, "end": 7586, "name": "POP", "source": 0 }, + { "begin": 7396, "end": 7601, "name": "SWAP1", "source": 0 }, + { + "begin": 7396, + "end": 7601, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 10928, + "end": 11085, + "name": "tag", + "source": 0, + "value": "48" + }, + { "begin": 10928, "end": 11085, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11004, + "end": 11008, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11031, "end": 11046, "name": "DUP1", "source": 0 }, + { + "begin": 11031, + "end": 11046, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11031, "end": 11046, "name": "SWAP1", "source": 0 }, + { "begin": 11031, "end": 11046, "name": "SLOAD", "source": 0 }, + { "begin": 11031, "end": 11046, "name": "SWAP1", "source": 0 }, + { + "begin": 11031, + "end": 11046, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 11031, "end": 11046, "name": "EXP", "source": 0 }, + { "begin": 11031, "end": 11046, "name": "SWAP1", "source": 0 }, + { "begin": 11031, "end": 11046, "name": "DIV", "source": 0 }, + { + "begin": 11031, + "end": 11046, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11031, "end": 11046, "name": "AND", "source": 0 }, + { + "begin": 11031, + "end": 11054, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11031, "end": 11054, "name": "AND", "source": 0 }, + { + "begin": 11031, + "end": 11054, + "name": "PUSH", + "source": 0, + "value": "95EA7B3" + }, + { "begin": 11055, "end": 11062, "name": "DUP5", "source": 0 }, + { "begin": 11064, "end": 11069, "name": "DUP5", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11031, "end": 11070, "name": "MLOAD", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "DUP4", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 11031, "end": 11070, "name": "AND", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 11031, "end": 11070, "name": "SHL", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "DUP2", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "MSTORE", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 11031, "end": 11070, "name": "ADD", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH [tag]", + "source": 0, + "value": "168" + }, + { "begin": 11031, "end": 11070, "name": "SWAP3", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "SWAP2", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "SWAP1", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH [tag]", + "source": 0, + "value": "169" + }, + { + "begin": 11031, + "end": 11070, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11031, + "end": 11070, + "name": "tag", + "source": 0, + "value": "168" + }, + { "begin": 11031, "end": 11070, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11031, "end": 11070, "name": "MLOAD", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "DUP1", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "DUP4", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "SUB", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "DUP2", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11031, "end": 11070, "name": "DUP8", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "GAS", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "CALL", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "ISZERO", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "DUP1", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "ISZERO", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH [tag]", + "source": 0, + "value": "171" + }, + { "begin": 11031, "end": 11070, "name": "JUMPI", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11031, "end": 11070, "name": "DUP1", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 11031, + "end": 11070, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11031, "end": 11070, "name": "REVERT", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "tag", + "source": 0, + "value": "171" + }, + { "begin": 11031, "end": 11070, "name": "JUMPDEST", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "POP", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "POP", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "POP", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "POP", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11031, "end": 11070, "name": "MLOAD", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 11031, "end": 11070, "name": "NOT", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 11031, "end": 11070, "name": "DUP3", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "ADD", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "AND", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "DUP3", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "ADD", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "DUP1", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11031, "end": 11070, "name": "MSTORE", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "POP", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "DUP2", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "ADD", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "SWAP1", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH [tag]", + "source": 0, + "value": "172" + }, + { "begin": 11031, "end": 11070, "name": "SWAP2", "source": 0 }, + { "begin": 11031, "end": 11070, "name": "SWAP1", "source": 0 }, + { + "begin": 11031, + "end": 11070, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 11031, + "end": 11070, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11031, + "end": 11070, + "name": "tag", + "source": 0, + "value": "172" + }, + { "begin": 11031, "end": 11070, "name": "JUMPDEST", "source": 0 }, + { "begin": 11024, "end": 11070, "name": "SWAP1", "source": 0 }, + { "begin": 11024, "end": 11070, "name": "POP", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "SWAP3", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "SWAP2", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "POP", "source": 0 }, + { "begin": 10928, "end": 11085, "name": "POP", "source": 0 }, + { + "begin": 10928, + "end": 11085, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 8081, + "end": 8293, + "name": "tag", + "source": 0, + "value": "53" + }, + { "begin": 8081, "end": 8293, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8136, + "end": 8143, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8249, "end": 8264, "name": "DUP1", "source": 0 }, + { + "begin": 8249, + "end": 8264, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8249, "end": 8264, "name": "SWAP1", "source": 0 }, + { "begin": 8249, "end": 8264, "name": "SLOAD", "source": 0 }, + { "begin": 8249, "end": 8264, "name": "SWAP1", "source": 0 }, + { + "begin": 8249, + "end": 8264, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 8249, "end": 8264, "name": "EXP", "source": 0 }, + { "begin": 8249, "end": 8264, "name": "SWAP1", "source": 0 }, + { "begin": 8249, "end": 8264, "name": "DIV", "source": 0 }, + { + "begin": 8249, + "end": 8264, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 8249, "end": 8264, "name": "AND", "source": 0 }, + { + "begin": 8249, + "end": 8276, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 8249, "end": 8276, "name": "AND", "source": 0 }, + { + "begin": 8249, + "end": 8276, + "name": "PUSH", + "source": 0, + "value": "18160DDD" + }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8249, "end": 8278, "name": "MLOAD", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "DUP2", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 8249, "end": 8278, "name": "AND", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 8249, "end": 8278, "name": "SHL", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "DUP2", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "MSTORE", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 8249, "end": 8278, "name": "ADD", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8249, "end": 8278, "name": "MLOAD", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "DUP1", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "DUP4", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "SUB", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "DUP2", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "DUP7", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "GAS", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "STATICCALL", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "ISZERO", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "DUP1", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "ISZERO", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH [tag]", + "source": 0, + "value": "176" + }, + { "begin": 8249, "end": 8278, "name": "JUMPI", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8249, "end": 8278, "name": "DUP1", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 8249, + "end": 8278, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8249, "end": 8278, "name": "REVERT", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "tag", + "source": 0, + "value": "176" + }, + { "begin": 8249, "end": 8278, "name": "JUMPDEST", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "POP", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "POP", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "POP", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "POP", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8249, "end": 8278, "name": "MLOAD", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 8249, "end": 8278, "name": "NOT", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 8249, "end": 8278, "name": "DUP3", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "ADD", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "AND", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "DUP3", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "ADD", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "DUP1", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8249, "end": 8278, "name": "MSTORE", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "POP", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "DUP2", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "ADD", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "SWAP1", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH [tag]", + "source": 0, + "value": "177" + }, + { "begin": 8249, "end": 8278, "name": "SWAP2", "source": 0 }, + { "begin": 8249, "end": 8278, "name": "SWAP1", "source": 0 }, + { + "begin": 8249, + "end": 8278, + "name": "PUSH [tag]", + "source": 0, + "value": "178" + }, + { + "begin": 8249, + "end": 8278, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8249, + "end": 8278, + "name": "tag", + "source": 0, + "value": "177" + }, + { "begin": 8249, "end": 8278, "name": "JUMPDEST", "source": 0 }, + { "begin": 8242, "end": 8278, "name": "SWAP1", "source": 0 }, + { "begin": 8242, "end": 8278, "name": "POP", "source": 0 }, + { "begin": 8081, "end": 8293, "name": "SWAP1", "source": 0 }, + { + "begin": 8081, + "end": 8293, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 9727, + "end": 9850, + "name": "tag", + "source": 0, + "value": "58" + }, + { "begin": 9727, "end": 9850, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9776, + "end": 9780, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9807, "end": 9822, "name": "DUP1", "source": 0 }, + { + "begin": 9807, + "end": 9822, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9807, "end": 9822, "name": "SWAP1", "source": 0 }, + { "begin": 9807, "end": 9822, "name": "SLOAD", "source": 0 }, + { "begin": 9807, "end": 9822, "name": "SWAP1", "source": 0 }, + { + "begin": 9807, + "end": 9822, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 9807, "end": 9822, "name": "EXP", "source": 0 }, + { "begin": 9807, "end": 9822, "name": "SWAP1", "source": 0 }, + { "begin": 9807, "end": 9822, "name": "DIV", "source": 0 }, + { + "begin": 9807, + "end": 9822, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9807, "end": 9822, "name": "AND", "source": 0 }, + { + "begin": 9807, + "end": 9833, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9807, "end": 9833, "name": "AND", "source": 0 }, + { + "begin": 9807, + "end": 9833, + "name": "PUSH", + "source": 0, + "value": "1CDDEC19" + }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9807, "end": 9835, "name": "MLOAD", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "DUP2", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 9807, "end": 9835, "name": "AND", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 9807, "end": 9835, "name": "SHL", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "DUP2", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "MSTORE", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 9807, "end": 9835, "name": "ADD", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9807, "end": 9835, "name": "MLOAD", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "DUP1", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "DUP4", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "SUB", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "DUP2", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9807, "end": 9835, "name": "DUP8", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "GAS", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "CALL", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "ISZERO", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "DUP1", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "ISZERO", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH [tag]", + "source": 0, + "value": "181" + }, + { "begin": 9807, "end": 9835, "name": "JUMPI", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9807, "end": 9835, "name": "DUP1", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 9807, + "end": 9835, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9807, "end": 9835, "name": "REVERT", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "tag", + "source": 0, + "value": "181" + }, + { "begin": 9807, "end": 9835, "name": "JUMPDEST", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "POP", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "POP", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "POP", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "POP", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9807, "end": 9835, "name": "MLOAD", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9807, "end": 9835, "name": "NOT", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9807, "end": 9835, "name": "DUP3", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "ADD", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "AND", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "DUP3", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "ADD", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "DUP1", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9807, "end": 9835, "name": "MSTORE", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "POP", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "DUP2", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "ADD", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "SWAP1", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH [tag]", + "source": 0, + "value": "182" + }, + { "begin": 9807, "end": 9835, "name": "SWAP2", "source": 0 }, + { "begin": 9807, "end": 9835, "name": "SWAP1", "source": 0 }, + { + "begin": 9807, + "end": 9835, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 9807, + "end": 9835, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9807, + "end": 9835, + "name": "tag", + "source": 0, + "value": "182" + }, + { "begin": 9807, "end": 9835, "name": "JUMPDEST", "source": 0 }, + { "begin": 9800, "end": 9835, "name": "SWAP1", "source": 0 }, + { "begin": 9800, "end": 9835, "name": "POP", "source": 0 }, + { "begin": 9727, "end": 9850, "name": "SWAP1", "source": 0 }, + { + "begin": 9727, + "end": 9850, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 11419, + "end": 11661, + "name": "tag", + "source": 0, + "value": "64" + }, + { "begin": 11419, "end": 11661, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11570, + "end": 11574, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11601, "end": 11616, "name": "DUP1", "source": 0 }, + { + "begin": 11601, + "end": 11616, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11601, "end": 11616, "name": "SWAP1", "source": 0 }, + { "begin": 11601, "end": 11616, "name": "SLOAD", "source": 0 }, + { "begin": 11601, "end": 11616, "name": "SWAP1", "source": 0 }, + { + "begin": 11601, + "end": 11616, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 11601, "end": 11616, "name": "EXP", "source": 0 }, + { "begin": 11601, "end": 11616, "name": "SWAP1", "source": 0 }, + { "begin": 11601, "end": 11616, "name": "DIV", "source": 0 }, + { + "begin": 11601, + "end": 11616, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11601, "end": 11616, "name": "AND", "source": 0 }, + { + "begin": 11601, + "end": 11629, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11601, "end": 11629, "name": "AND", "source": 0 }, + { + "begin": 11601, + "end": 11629, + "name": "PUSH", + "source": 0, + "value": "23B872DD" + }, + { "begin": 11630, "end": 11634, "name": "DUP6", "source": 0 }, + { "begin": 11636, "end": 11638, "name": "DUP6", "source": 0 }, + { "begin": 11640, "end": 11645, "name": "DUP6", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11601, "end": 11646, "name": "MLOAD", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "DUP5", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 11601, "end": 11646, "name": "AND", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 11601, "end": 11646, "name": "SHL", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "DUP2", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "MSTORE", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 11601, "end": 11646, "name": "ADD", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH [tag]", + "source": 0, + "value": "184" + }, + { "begin": 11601, "end": 11646, "name": "SWAP4", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "SWAP3", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "SWAP2", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "SWAP1", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH [tag]", + "source": 0, + "value": "185" + }, + { + "begin": 11601, + "end": 11646, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11601, + "end": 11646, + "name": "tag", + "source": 0, + "value": "184" + }, + { "begin": 11601, "end": 11646, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11601, "end": 11646, "name": "MLOAD", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "DUP1", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "DUP4", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "SUB", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "DUP2", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11601, "end": 11646, "name": "DUP8", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "GAS", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "CALL", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "ISZERO", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "DUP1", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "ISZERO", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH [tag]", + "source": 0, + "value": "187" + }, + { "begin": 11601, "end": 11646, "name": "JUMPI", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11601, "end": 11646, "name": "DUP1", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 11601, + "end": 11646, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11601, "end": 11646, "name": "REVERT", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "tag", + "source": 0, + "value": "187" + }, + { "begin": 11601, "end": 11646, "name": "JUMPDEST", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "POP", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "POP", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "POP", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "POP", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11601, "end": 11646, "name": "MLOAD", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 11601, "end": 11646, "name": "NOT", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 11601, "end": 11646, "name": "DUP3", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "ADD", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "AND", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "DUP3", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "ADD", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "DUP1", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11601, "end": 11646, "name": "MSTORE", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "POP", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "DUP2", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "ADD", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "SWAP1", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH [tag]", + "source": 0, + "value": "188" + }, + { "begin": 11601, "end": 11646, "name": "SWAP2", "source": 0 }, + { "begin": 11601, "end": 11646, "name": "SWAP1", "source": 0 }, + { + "begin": 11601, + "end": 11646, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 11601, + "end": 11646, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11601, + "end": 11646, + "name": "tag", + "source": 0, + "value": "188" + }, + { "begin": 11601, "end": 11646, "name": "JUMPDEST", "source": 0 }, + { "begin": 11594, "end": 11646, "name": "SWAP1", "source": 0 }, + { "begin": 11594, "end": 11646, "name": "POP", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "SWAP4", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "SWAP3", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "POP", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "POP", "source": 0 }, + { "begin": 11419, "end": 11661, "name": "POP", "source": 0 }, + { + "begin": 11419, + "end": 11661, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 7862, + "end": 8067, + "name": "tag", + "source": 0, + "value": "68" + }, + { "begin": 7862, "end": 8067, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7914, + "end": 7919, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8026, "end": 8041, "name": "DUP1", "source": 0 }, + { + "begin": 8026, + "end": 8041, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8026, "end": 8041, "name": "SWAP1", "source": 0 }, + { "begin": 8026, "end": 8041, "name": "SLOAD", "source": 0 }, + { "begin": 8026, "end": 8041, "name": "SWAP1", "source": 0 }, + { + "begin": 8026, + "end": 8041, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 8026, "end": 8041, "name": "EXP", "source": 0 }, + { "begin": 8026, "end": 8041, "name": "SWAP1", "source": 0 }, + { "begin": 8026, "end": 8041, "name": "DIV", "source": 0 }, + { + "begin": 8026, + "end": 8041, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 8026, "end": 8041, "name": "AND", "source": 0 }, + { + "begin": 8026, + "end": 8050, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 8026, "end": 8050, "name": "AND", "source": 0 }, + { + "begin": 8026, + "end": 8050, + "name": "PUSH", + "source": 0, + "value": "313CE567" + }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8026, "end": 8052, "name": "MLOAD", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "DUP2", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 8026, "end": 8052, "name": "AND", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 8026, "end": 8052, "name": "SHL", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "DUP2", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "MSTORE", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 8026, "end": 8052, "name": "ADD", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8026, "end": 8052, "name": "MLOAD", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "DUP1", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "DUP4", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "SUB", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "DUP2", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "DUP7", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "GAS", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "STATICCALL", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "ISZERO", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "DUP1", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "ISZERO", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH [tag]", + "source": 0, + "value": "191" + }, + { "begin": 8026, "end": 8052, "name": "JUMPI", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8026, "end": 8052, "name": "DUP1", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 8026, + "end": 8052, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8026, "end": 8052, "name": "REVERT", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "tag", + "source": 0, + "value": "191" + }, + { "begin": 8026, "end": 8052, "name": "JUMPDEST", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "POP", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "POP", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "POP", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "POP", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8026, "end": 8052, "name": "MLOAD", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 8026, "end": 8052, "name": "NOT", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 8026, "end": 8052, "name": "DUP3", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "ADD", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "AND", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "DUP3", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "ADD", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "DUP1", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8026, "end": 8052, "name": "MSTORE", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "POP", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "DUP2", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "ADD", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "SWAP1", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH [tag]", + "source": 0, + "value": "192" + }, + { "begin": 8026, "end": 8052, "name": "SWAP2", "source": 0 }, + { "begin": 8026, "end": 8052, "name": "SWAP1", "source": 0 }, + { + "begin": 8026, + "end": 8052, + "name": "PUSH [tag]", + "source": 0, + "value": "193" + }, + { + "begin": 8026, + "end": 8052, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8026, + "end": 8052, + "name": "tag", + "source": 0, + "value": "192" + }, + { "begin": 8026, "end": 8052, "name": "JUMPDEST", "source": 0 }, + { "begin": 8019, "end": 8052, "name": "SWAP1", "source": 0 }, + { "begin": 8019, "end": 8052, "name": "POP", "source": 0 }, + { "begin": 7862, "end": 8067, "name": "SWAP1", "source": 0 }, + { + "begin": 7862, + "end": 8067, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 8966, + "end": 9111, + "name": "tag", + "source": 0, + "value": "74" + }, + { "begin": 8966, "end": 9111, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9034, + "end": 9038, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9065, "end": 9080, "name": "DUP1", "source": 0 }, + { + "begin": 9065, + "end": 9080, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9065, "end": 9080, "name": "SWAP1", "source": 0 }, + { "begin": 9065, "end": 9080, "name": "SLOAD", "source": 0 }, + { "begin": 9065, "end": 9080, "name": "SWAP1", "source": 0 }, + { + "begin": 9065, + "end": 9080, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 9065, "end": 9080, "name": "EXP", "source": 0 }, + { "begin": 9065, "end": 9080, "name": "SWAP1", "source": 0 }, + { "begin": 9065, "end": 9080, "name": "DIV", "source": 0 }, + { + "begin": 9065, + "end": 9080, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9065, "end": 9080, "name": "AND", "source": 0 }, + { + "begin": 9065, + "end": 9085, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9065, "end": 9085, "name": "AND", "source": 0 }, + { + "begin": 9065, + "end": 9085, + "name": "PUSH", + "source": 0, + "value": "40C10F19" + }, + { "begin": 9086, "end": 9088, "name": "DUP5", "source": 0 }, + { "begin": 9090, "end": 9095, "name": "DUP5", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9065, "end": 9096, "name": "MLOAD", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "DUP4", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 9065, "end": 9096, "name": "AND", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 9065, "end": 9096, "name": "SHL", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "DUP2", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "MSTORE", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 9065, "end": 9096, "name": "ADD", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH [tag]", + "source": 0, + "value": "195" + }, + { "begin": 9065, "end": 9096, "name": "SWAP3", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "SWAP2", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "SWAP1", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH [tag]", + "source": 0, + "value": "169" + }, + { + "begin": 9065, + "end": 9096, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9065, + "end": 9096, + "name": "tag", + "source": 0, + "value": "195" + }, + { "begin": 9065, "end": 9096, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9065, "end": 9096, "name": "MLOAD", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "DUP1", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "DUP4", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "SUB", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "DUP2", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9065, "end": 9096, "name": "DUP8", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "GAS", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "CALL", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "ISZERO", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "DUP1", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "ISZERO", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH [tag]", + "source": 0, + "value": "197" + }, + { "begin": 9065, "end": 9096, "name": "JUMPI", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9065, "end": 9096, "name": "DUP1", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 9065, + "end": 9096, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9065, "end": 9096, "name": "REVERT", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "tag", + "source": 0, + "value": "197" + }, + { "begin": 9065, "end": 9096, "name": "JUMPDEST", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "POP", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "POP", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "POP", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "POP", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9065, "end": 9096, "name": "MLOAD", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9065, "end": 9096, "name": "NOT", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9065, "end": 9096, "name": "DUP3", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "ADD", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "AND", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "DUP3", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "ADD", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "DUP1", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9065, "end": 9096, "name": "MSTORE", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "POP", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "DUP2", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "ADD", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "SWAP1", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH [tag]", + "source": 0, + "value": "198" + }, + { "begin": 9065, "end": 9096, "name": "SWAP2", "source": 0 }, + { "begin": 9065, "end": 9096, "name": "SWAP1", "source": 0 }, + { + "begin": 9065, + "end": 9096, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 9065, + "end": 9096, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9065, + "end": 9096, + "name": "tag", + "source": 0, + "value": "198" + }, + { "begin": 9065, "end": 9096, "name": "JUMPDEST", "source": 0 }, + { "begin": 9058, "end": 9096, "name": "SWAP1", "source": 0 }, + { "begin": 9058, "end": 9096, "name": "POP", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "SWAP3", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "SWAP2", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "POP", "source": 0 }, + { "begin": 8966, "end": 9111, "name": "POP", "source": 0 }, + { + "begin": 8966, + "end": 9111, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 9439, + "end": 9572, + "name": "tag", + "source": 0, + "value": "80" + }, + { "begin": 9439, "end": 9572, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9497, + "end": 9501, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9528, "end": 9543, "name": "DUP1", "source": 0 }, + { + "begin": 9528, + "end": 9543, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9528, "end": 9543, "name": "SWAP1", "source": 0 }, + { "begin": 9528, "end": 9543, "name": "SLOAD", "source": 0 }, + { "begin": 9528, "end": 9543, "name": "SWAP1", "source": 0 }, + { + "begin": 9528, + "end": 9543, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 9528, "end": 9543, "name": "EXP", "source": 0 }, + { "begin": 9528, "end": 9543, "name": "SWAP1", "source": 0 }, + { "begin": 9528, "end": 9543, "name": "DIV", "source": 0 }, + { + "begin": 9528, + "end": 9543, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9528, "end": 9543, "name": "AND", "source": 0 }, + { + "begin": 9528, + "end": 9548, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9528, "end": 9548, "name": "AND", "source": 0 }, + { + "begin": 9528, + "end": 9548, + "name": "PUSH", + "source": 0, + "value": "5EA20216" + }, + { "begin": 9549, "end": 9556, "name": "DUP4", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9528, "end": 9557, "name": "MLOAD", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "DUP3", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 9528, "end": 9557, "name": "AND", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 9528, "end": 9557, "name": "SHL", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "DUP2", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "MSTORE", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 9528, "end": 9557, "name": "ADD", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH [tag]", + "source": 0, + "value": "200" + }, + { "begin": 9528, "end": 9557, "name": "SWAP2", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "SWAP1", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH [tag]", + "source": 0, + "value": "38" + }, + { + "begin": 9528, + "end": 9557, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9528, + "end": 9557, + "name": "tag", + "source": 0, + "value": "200" + }, + { "begin": 9528, "end": 9557, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9528, "end": 9557, "name": "MLOAD", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "DUP1", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "DUP4", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "SUB", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "DUP2", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9528, "end": 9557, "name": "DUP8", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "GAS", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "CALL", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "ISZERO", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "DUP1", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "ISZERO", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH [tag]", + "source": 0, + "value": "202" + }, + { "begin": 9528, "end": 9557, "name": "JUMPI", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9528, "end": 9557, "name": "DUP1", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 9528, + "end": 9557, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9528, "end": 9557, "name": "REVERT", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "tag", + "source": 0, + "value": "202" + }, + { "begin": 9528, "end": 9557, "name": "JUMPDEST", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "POP", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "POP", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "POP", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "POP", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9528, "end": 9557, "name": "MLOAD", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9528, "end": 9557, "name": "NOT", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9528, "end": 9557, "name": "DUP3", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "ADD", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "AND", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "DUP3", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "ADD", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "DUP1", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9528, "end": 9557, "name": "MSTORE", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "POP", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "DUP2", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "ADD", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "SWAP1", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH [tag]", + "source": 0, + "value": "203" + }, + { "begin": 9528, "end": 9557, "name": "SWAP2", "source": 0 }, + { "begin": 9528, "end": 9557, "name": "SWAP1", "source": 0 }, + { + "begin": 9528, + "end": 9557, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 9528, + "end": 9557, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9528, + "end": 9557, + "name": "tag", + "source": 0, + "value": "203" + }, + { "begin": 9528, "end": 9557, "name": "JUMPDEST", "source": 0 }, + { "begin": 9521, "end": 9557, "name": "SWAP1", "source": 0 }, + { "begin": 9521, "end": 9557, "name": "POP", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "SWAP2", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "SWAP1", "source": 0 }, + { "begin": 9439, "end": 9572, "name": "POP", "source": 0 }, + { + "begin": 9439, + "end": 9572, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 9586, + "end": 9713, + "name": "tag", + "source": 0, + "value": "84" + }, + { "begin": 9586, "end": 9713, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9637, + "end": 9641, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9668, "end": 9683, "name": "DUP1", "source": 0 }, + { + "begin": 9668, + "end": 9683, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9668, "end": 9683, "name": "SWAP1", "source": 0 }, + { "begin": 9668, "end": 9683, "name": "SLOAD", "source": 0 }, + { "begin": 9668, "end": 9683, "name": "SWAP1", "source": 0 }, + { + "begin": 9668, + "end": 9683, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 9668, "end": 9683, "name": "EXP", "source": 0 }, + { "begin": 9668, "end": 9683, "name": "SWAP1", "source": 0 }, + { "begin": 9668, "end": 9683, "name": "DIV", "source": 0 }, + { + "begin": 9668, + "end": 9683, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9668, "end": 9683, "name": "AND", "source": 0 }, + { + "begin": 9668, + "end": 9696, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9668, "end": 9696, "name": "AND", "source": 0 }, + { + "begin": 9668, + "end": 9696, + "name": "PUSH", + "source": 0, + "value": "6B8751C1" + }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9668, "end": 9698, "name": "MLOAD", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "DUP2", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 9668, "end": 9698, "name": "AND", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 9668, "end": 9698, "name": "SHL", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "DUP2", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "MSTORE", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 9668, "end": 9698, "name": "ADD", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9668, "end": 9698, "name": "MLOAD", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "DUP1", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "DUP4", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "SUB", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "DUP2", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9668, "end": 9698, "name": "DUP8", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "GAS", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "CALL", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "ISZERO", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "DUP1", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "ISZERO", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH [tag]", + "source": 0, + "value": "206" + }, + { "begin": 9668, "end": 9698, "name": "JUMPI", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9668, "end": 9698, "name": "DUP1", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 9668, + "end": 9698, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9668, "end": 9698, "name": "REVERT", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "tag", + "source": 0, + "value": "206" + }, + { "begin": 9668, "end": 9698, "name": "JUMPDEST", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "POP", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "POP", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "POP", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "POP", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9668, "end": 9698, "name": "MLOAD", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9668, "end": 9698, "name": "NOT", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9668, "end": 9698, "name": "DUP3", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "ADD", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "AND", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "DUP3", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "ADD", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "DUP1", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9668, "end": 9698, "name": "MSTORE", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "POP", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "DUP2", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "ADD", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "SWAP1", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH [tag]", + "source": 0, + "value": "207" + }, + { "begin": 9668, "end": 9698, "name": "SWAP2", "source": 0 }, + { "begin": 9668, "end": 9698, "name": "SWAP1", "source": 0 }, + { + "begin": 9668, + "end": 9698, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 9668, + "end": 9698, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9668, + "end": 9698, + "name": "tag", + "source": 0, + "value": "207" + }, + { "begin": 9668, "end": 9698, "name": "JUMPDEST", "source": 0 }, + { "begin": 9661, "end": 9698, "name": "SWAP1", "source": 0 }, + { "begin": 9661, "end": 9698, "name": "POP", "source": 0 }, + { "begin": 9586, "end": 9713, "name": "SWAP1", "source": 0 }, + { + "begin": 9586, + "end": 9713, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 8319, + "end": 8541, + "name": "tag", + "source": 0, + "value": "89" + }, + { "begin": 8319, "end": 8541, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8383, + "end": 8390, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8496, "end": 8511, "name": "DUP1", "source": 0 }, + { + "begin": 8496, + "end": 8511, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8496, "end": 8511, "name": "SWAP1", "source": 0 }, + { "begin": 8496, "end": 8511, "name": "SLOAD", "source": 0 }, + { "begin": 8496, "end": 8511, "name": "SWAP1", "source": 0 }, + { + "begin": 8496, + "end": 8511, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 8496, "end": 8511, "name": "EXP", "source": 0 }, + { "begin": 8496, "end": 8511, "name": "SWAP1", "source": 0 }, + { "begin": 8496, "end": 8511, "name": "DIV", "source": 0 }, + { + "begin": 8496, + "end": 8511, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 8496, "end": 8511, "name": "AND", "source": 0 }, + { + "begin": 8496, + "end": 8521, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 8496, "end": 8521, "name": "AND", "source": 0 }, + { + "begin": 8496, + "end": 8521, + "name": "PUSH", + "source": 0, + "value": "70A08231" + }, + { "begin": 8522, "end": 8525, "name": "DUP4", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8496, "end": 8526, "name": "MLOAD", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "DUP3", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 8496, "end": 8526, "name": "AND", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 8496, "end": 8526, "name": "SHL", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "DUP2", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "MSTORE", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 8496, "end": 8526, "name": "ADD", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH [tag]", + "source": 0, + "value": "209" + }, + { "begin": 8496, "end": 8526, "name": "SWAP2", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "SWAP1", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH [tag]", + "source": 0, + "value": "38" + }, + { + "begin": 8496, + "end": 8526, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8496, + "end": 8526, + "name": "tag", + "source": 0, + "value": "209" + }, + { "begin": 8496, "end": 8526, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8496, "end": 8526, "name": "MLOAD", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "DUP1", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "DUP4", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "SUB", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "DUP2", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "DUP7", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "GAS", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "STATICCALL", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "ISZERO", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "DUP1", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "ISZERO", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH [tag]", + "source": 0, + "value": "211" + }, + { "begin": 8496, "end": 8526, "name": "JUMPI", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8496, "end": 8526, "name": "DUP1", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 8496, + "end": 8526, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8496, "end": 8526, "name": "REVERT", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "tag", + "source": 0, + "value": "211" + }, + { "begin": 8496, "end": 8526, "name": "JUMPDEST", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "POP", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "POP", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "POP", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "POP", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8496, "end": 8526, "name": "MLOAD", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 8496, "end": 8526, "name": "NOT", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 8496, "end": 8526, "name": "DUP3", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "ADD", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "AND", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "DUP3", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "ADD", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "DUP1", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8496, "end": 8526, "name": "MSTORE", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "POP", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "DUP2", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "ADD", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "SWAP1", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH [tag]", + "source": 0, + "value": "212" + }, + { "begin": 8496, "end": 8526, "name": "SWAP2", "source": 0 }, + { "begin": 8496, "end": 8526, "name": "SWAP1", "source": 0 }, + { + "begin": 8496, + "end": 8526, + "name": "PUSH [tag]", + "source": 0, + "value": "178" + }, + { + "begin": 8496, + "end": 8526, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8496, + "end": 8526, + "name": "tag", + "source": 0, + "value": "212" + }, + { "begin": 8496, "end": 8526, "name": "JUMPDEST", "source": 0 }, + { "begin": 8489, "end": 8526, "name": "SWAP1", "source": 0 }, + { "begin": 8489, "end": 8526, "name": "POP", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "SWAP2", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "SWAP1", "source": 0 }, + { "begin": 8319, "end": 8541, "name": "POP", "source": 0 }, + { + "begin": 8319, + "end": 8541, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 11687, + "end": 12058, + "name": "tag", + "source": 0, + "value": "94" + }, + { "begin": 11687, "end": 12058, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11826, + "end": 11830, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11847, "end": 11858, "name": "DUP1", "source": 0 }, + { + "begin": 11860, + "end": 11877, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 11881, + "end": 11903, + "name": "PUSH", + "source": 0, + "value": "1" + }, + { + "begin": 11881, + "end": 11903, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11881, "end": 11903, "name": "SWAP1", "source": 0 }, + { "begin": 11881, "end": 11903, "name": "SLOAD", "source": 0 }, + { "begin": 11881, "end": 11903, "name": "SWAP1", "source": 0 }, + { + "begin": 11881, + "end": 11903, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 11881, "end": 11903, "name": "EXP", "source": 0 }, + { "begin": 11881, "end": 11903, "name": "SWAP1", "source": 0 }, + { "begin": 11881, "end": 11903, "name": "DIV", "source": 0 }, + { + "begin": 11881, + "end": 11903, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11881, "end": 11903, "name": "AND", "source": 0 }, + { + "begin": 11881, + "end": 11916, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11881, "end": 11916, "name": "AND", "source": 0 }, + { "begin": 11999, "end": 12003, "name": "DUP7", "source": 0 }, + { "begin": 12005, "end": 12007, "name": "DUP7", "source": 0 }, + { "begin": 12009, "end": 12014, "name": "DUP7", "source": 0 }, + { + "begin": 11934, + "end": 12015, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11934, "end": 12015, "name": "MLOAD", "source": 0 }, + { + "begin": 11934, + "end": 12015, + "name": "PUSH", + "source": 0, + "value": "24" + }, + { "begin": 11934, "end": 12015, "name": "ADD", "source": 0 }, + { + "begin": 11934, + "end": 12015, + "name": "PUSH [tag]", + "source": 0, + "value": "214" + }, + { "begin": 11934, "end": 12015, "name": "SWAP4", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "SWAP3", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "SWAP2", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "SWAP1", "source": 0 }, + { + "begin": 11934, + "end": 12015, + "name": "PUSH [tag]", + "source": 0, + "value": "185" + }, + { + "begin": 11934, + "end": 12015, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11934, + "end": 12015, + "name": "tag", + "source": 0, + "value": "214" + }, + { "begin": 11934, "end": 12015, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11934, + "end": 12015, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11934, "end": 12015, "name": "MLOAD", "source": 0 }, + { + "begin": 11934, + "end": 12015, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { "begin": 11934, "end": 12015, "name": "DUP2", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "DUP4", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "SUB", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "SUB", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "DUP2", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "MSTORE", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "SWAP1", "source": 0 }, + { + "begin": 11934, + "end": 12015, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11934, "end": 12015, "name": "MSTORE", "source": 0 }, + { + "begin": 11934, + "end": 12015, + "name": "PUSH", + "source": 0, + "value": "23B872DD00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 11934, + "end": 12015, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11934, "end": 12015, "name": "NOT", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "AND", "source": 0 }, + { + "begin": 11934, + "end": 12015, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { "begin": 11934, "end": 12015, "name": "DUP3", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "ADD", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "DUP1", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "MLOAD", "source": 0 }, + { + "begin": 11934, + "end": 12015, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11934, "end": 12015, "name": "DUP4", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "DUP2", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "DUP4", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "AND", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "OR", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "DUP4", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "MSTORE", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "POP", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "POP", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "POP", "source": 0 }, + { "begin": 11934, "end": 12015, "name": "POP", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11881, "end": 12016, "name": "MLOAD", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH [tag]", + "source": 0, + "value": "215" + }, + { "begin": 11881, "end": 12016, "name": "SWAP2", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "SWAP1", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH [tag]", + "source": 0, + "value": "216" + }, + { + "begin": 11881, + "end": 12016, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11881, + "end": 12016, + "name": "tag", + "source": 0, + "value": "215" + }, + { "begin": 11881, "end": 12016, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11881, "end": 12016, "name": "MLOAD", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "DUP1", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "DUP4", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "SUB", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "DUP2", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "DUP6", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "GAS", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "DELEGATECALL", + "source": 0 + }, + { "begin": 11881, "end": 12016, "name": "SWAP2", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "POP", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "POP", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "RETURNDATASIZE", + "source": 0 + }, + { "begin": 11881, "end": 12016, "name": "DUP1", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11881, "end": 12016, "name": "DUP2", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "EQ", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH [tag]", + "source": 0, + "value": "219" + }, + { "begin": 11881, "end": 12016, "name": "JUMPI", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11881, "end": 12016, "name": "MLOAD", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "SWAP2", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "POP", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 11881, "end": 12016, "name": "NOT", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH", + "source": 0, + "value": "3F" + }, + { + "begin": 11881, + "end": 12016, + "name": "RETURNDATASIZE", + "source": 0 + }, + { "begin": 11881, "end": 12016, "name": "ADD", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "AND", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "DUP3", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "ADD", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11881, "end": 12016, "name": "MSTORE", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "RETURNDATASIZE", + "source": 0 + }, + { "begin": 11881, "end": 12016, "name": "DUP3", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "MSTORE", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { "begin": 11881, "end": 12016, "name": "DUP5", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "ADD", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH [tag]", + "source": 0, + "value": "218" + }, + { "begin": 11881, "end": 12016, "name": "JUMP", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "tag", + "source": 0, + "value": "219" + }, + { "begin": 11881, "end": 12016, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "PUSH", + "source": 0, + "value": "60" + }, + { "begin": 11881, "end": 12016, "name": "SWAP2", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "POP", "source": 0 }, + { + "begin": 11881, + "end": 12016, + "name": "tag", + "source": 0, + "value": "218" + }, + { "begin": 11881, "end": 12016, "name": "JUMPDEST", "source": 0 }, + { "begin": 11881, "end": 12016, "name": "POP", "source": 0 }, + { "begin": 11846, "end": 12016, "name": "SWAP2", "source": 0 }, + { "begin": 11846, "end": 12016, "name": "POP", "source": 0 }, + { "begin": 11846, "end": 12016, "name": "SWAP2", "source": 0 }, + { "begin": 11846, "end": 12016, "name": "POP", "source": 0 }, + { "begin": 12037, "end": 12043, "name": "DUP2", "source": 0 }, + { "begin": 12030, "end": 12043, "name": "SWAP3", "source": 0 }, + { "begin": 12030, "end": 12043, "name": "POP", "source": 0 }, + { "begin": 12030, "end": 12043, "name": "POP", "source": 0 }, + { "begin": 12030, "end": 12043, "name": "POP", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "SWAP4", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "SWAP3", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "POP", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "POP", "source": 0 }, + { "begin": 11687, "end": 12058, "name": "POP", "source": 0 }, + { + "begin": 11687, + "end": 12058, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 7039, + "end": 7254, + "name": "tag", + "source": 0, + "value": "99" + }, + { "begin": 7039, "end": 7254, "name": "JUMPDEST", "source": 0 }, + { "begin": 7163, "end": 7179, "name": "DUP1", "source": 0 }, + { + "begin": 7121, + "end": 7136, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7121, "end": 7136, "name": "DUP1", "source": 0 }, + { + "begin": 7121, + "end": 7180, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 7121, "end": 7180, "name": "EXP", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "DUP2", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "SLOAD", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "DUP2", "source": 0 }, + { + "begin": 7121, + "end": 7180, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 7121, "end": 7180, "name": "MUL", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "NOT", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "AND", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "SWAP1", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "DUP4", "source": 0 }, + { + "begin": 7121, + "end": 7180, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 7121, "end": 7180, "name": "AND", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "MUL", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "OR", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "SWAP1", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "SSTORE", "source": 0 }, + { "begin": 7121, "end": 7180, "name": "POP", "source": 0 }, + { "begin": 7223, "end": 7239, "name": "DUP1", "source": 0 }, + { + "begin": 7198, + "end": 7220, + "name": "PUSH", + "source": 0, + "value": "1" + }, + { + "begin": 7198, + "end": 7220, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 7198, + "end": 7239, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 7198, "end": 7239, "name": "EXP", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "DUP2", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "SLOAD", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "DUP2", "source": 0 }, + { + "begin": 7198, + "end": 7239, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 7198, "end": 7239, "name": "MUL", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "NOT", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "AND", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "SWAP1", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "DUP4", "source": 0 }, + { + "begin": 7198, + "end": 7239, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 7198, "end": 7239, "name": "AND", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "MUL", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "OR", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "SWAP1", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "SSTORE", "source": 0 }, + { "begin": 7198, "end": 7239, "name": "POP", "source": 0 }, + { "begin": 7039, "end": 7254, "name": "POP", "source": 0 }, + { + "begin": 7039, + "end": 7254, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 9288, + "end": 9425, + "name": "tag", + "source": 0, + "value": "103" + }, + { "begin": 9288, "end": 9425, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9348, + "end": 9352, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9379, "end": 9394, "name": "DUP1", "source": 0 }, + { + "begin": 9379, + "end": 9394, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9379, "end": 9394, "name": "SWAP1", "source": 0 }, + { "begin": 9379, "end": 9394, "name": "SLOAD", "source": 0 }, + { "begin": 9379, "end": 9394, "name": "SWAP1", "source": 0 }, + { + "begin": 9379, + "end": 9394, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 9379, "end": 9394, "name": "EXP", "source": 0 }, + { "begin": 9379, "end": 9394, "name": "SWAP1", "source": 0 }, + { "begin": 9379, "end": 9394, "name": "DIV", "source": 0 }, + { + "begin": 9379, + "end": 9394, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9379, "end": 9394, "name": "AND", "source": 0 }, + { + "begin": 9379, + "end": 9401, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9379, "end": 9401, "name": "AND", "source": 0 }, + { + "begin": 9379, + "end": 9401, + "name": "PUSH", + "source": 0, + "value": "8D1FDF2F" + }, + { "begin": 9402, "end": 9409, "name": "DUP4", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9379, "end": 9410, "name": "MLOAD", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "DUP3", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 9379, "end": 9410, "name": "AND", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 9379, "end": 9410, "name": "SHL", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "DUP2", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "MSTORE", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 9379, "end": 9410, "name": "ADD", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH [tag]", + "source": 0, + "value": "222" + }, + { "begin": 9379, "end": 9410, "name": "SWAP2", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "SWAP1", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH [tag]", + "source": 0, + "value": "38" + }, + { + "begin": 9379, + "end": 9410, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9379, + "end": 9410, + "name": "tag", + "source": 0, + "value": "222" + }, + { "begin": 9379, "end": 9410, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9379, "end": 9410, "name": "MLOAD", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "DUP1", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "DUP4", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "SUB", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "DUP2", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9379, "end": 9410, "name": "DUP8", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "GAS", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "CALL", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "ISZERO", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "DUP1", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "ISZERO", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH [tag]", + "source": 0, + "value": "224" + }, + { "begin": 9379, "end": 9410, "name": "JUMPI", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9379, "end": 9410, "name": "DUP1", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 9379, + "end": 9410, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9379, "end": 9410, "name": "REVERT", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "tag", + "source": 0, + "value": "224" + }, + { "begin": 9379, "end": 9410, "name": "JUMPDEST", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "POP", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "POP", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "POP", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "POP", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9379, "end": 9410, "name": "MLOAD", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9379, "end": 9410, "name": "NOT", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9379, "end": 9410, "name": "DUP3", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "ADD", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "AND", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "DUP3", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "ADD", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "DUP1", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9379, "end": 9410, "name": "MSTORE", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "POP", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "DUP2", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "ADD", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "SWAP1", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH [tag]", + "source": 0, + "value": "225" + }, + { "begin": 9379, "end": 9410, "name": "SWAP2", "source": 0 }, + { "begin": 9379, "end": 9410, "name": "SWAP1", "source": 0 }, + { + "begin": 9379, + "end": 9410, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 9379, + "end": 9410, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9379, + "end": 9410, + "name": "tag", + "source": 0, + "value": "225" + }, + { "begin": 9379, "end": 9410, "name": "JUMPDEST", "source": 0 }, + { "begin": 9372, "end": 9410, "name": "SWAP1", "source": 0 }, + { "begin": 9372, "end": 9410, "name": "POP", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "SWAP2", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "SWAP1", "source": 0 }, + { "begin": 9288, "end": 9425, "name": "POP", "source": 0 }, + { + "begin": 9288, + "end": 9425, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 7627, + "end": 7836, + "name": "tag", + "source": 0, + "value": "107" + }, + { "begin": 7627, "end": 7836, "name": "JUMPDEST", "source": 0 }, + { + "begin": 7677, + "end": 7690, + "name": "PUSH", + "source": 0, + "value": "60" + }, + { + "begin": 7797, + "end": 7812, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7797, "end": 7812, "name": "DUP1", "source": 0 }, + { "begin": 7797, "end": 7812, "name": "SLOAD", "source": 0 }, + { "begin": 7797, "end": 7812, "name": "SWAP1", "source": 0 }, + { + "begin": 7797, + "end": 7812, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 7797, "end": 7812, "name": "EXP", "source": 0 }, + { "begin": 7797, "end": 7812, "name": "SWAP1", "source": 0 }, + { "begin": 7797, "end": 7812, "name": "DIV", "source": 0 }, + { + "begin": 7797, + "end": 7812, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 7797, "end": 7812, "name": "AND", "source": 0 }, + { + "begin": 7797, + "end": 7819, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 7797, "end": 7819, "name": "AND", "source": 0 }, + { + "begin": 7797, + "end": 7819, + "name": "PUSH", + "source": 0, + "value": "95D89B41" + }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7797, "end": 7821, "name": "MLOAD", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "DUP2", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 7797, "end": 7821, "name": "AND", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 7797, "end": 7821, "name": "SHL", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "DUP2", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "MSTORE", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 7797, "end": 7821, "name": "ADD", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7797, "end": 7821, "name": "MLOAD", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "DUP1", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "DUP4", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "SUB", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "DUP2", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "DUP7", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "GAS", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "STATICCALL", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "ISZERO", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "DUP1", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "ISZERO", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH [tag]", + "source": 0, + "value": "228" + }, + { "begin": 7797, "end": 7821, "name": "JUMPI", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7797, "end": 7821, "name": "DUP1", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 7797, + "end": 7821, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7797, "end": 7821, "name": "REVERT", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "tag", + "source": 0, + "value": "228" + }, + { "begin": 7797, "end": 7821, "name": "JUMPDEST", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "POP", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "POP", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "POP", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "POP", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7797, "end": 7821, "name": "MLOAD", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 7797, "end": 7821, "name": "DUP3", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 7797, + "end": 7821, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 7797, "end": 7821, "name": "NOT", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 7797, "end": 7821, "name": "DUP3", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "ADD", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "AND", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "DUP3", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "ADD", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "DUP1", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 7797, "end": 7821, "name": "MSTORE", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "POP", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "DUP2", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "ADD", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "SWAP1", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH [tag]", + "source": 0, + "value": "229" + }, + { "begin": 7797, "end": 7821, "name": "SWAP2", "source": 0 }, + { "begin": 7797, "end": 7821, "name": "SWAP1", "source": 0 }, + { + "begin": 7797, + "end": 7821, + "name": "PUSH [tag]", + "source": 0, + "value": "166" + }, + { + "begin": 7797, + "end": 7821, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 7797, + "end": 7821, + "name": "tag", + "source": 0, + "value": "229" + }, + { "begin": 7797, "end": 7821, "name": "JUMPDEST", "source": 0 }, + { "begin": 7790, "end": 7821, "name": "SWAP1", "source": 0 }, + { "begin": 7790, "end": 7821, "name": "POP", "source": 0 }, + { "begin": 7627, "end": 7836, "name": "SWAP1", "source": 0 }, + { + "begin": 7627, + "end": 7836, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 6727, + "end": 6843, + "name": "tag", + "source": 0, + "value": "111" + }, + { "begin": 6727, "end": 6843, "name": "JUMPDEST", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 6727, "end": 6843, "name": "DUP1", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "SLOAD", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "SWAP1", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 6727, "end": 6843, "name": "EXP", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "SWAP1", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "DIV", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 6727, "end": 6843, "name": "AND", "source": 0 }, + { "begin": 6727, "end": 6843, "name": "DUP2", "source": 0 }, + { + "begin": 6727, + "end": 6843, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 9125, + "end": 9274, + "name": "tag", + "source": 0, + "value": "117" + }, + { "begin": 9125, "end": 9274, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9195, + "end": 9199, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9226, "end": 9241, "name": "DUP1", "source": 0 }, + { + "begin": 9226, + "end": 9241, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9226, "end": 9241, "name": "SWAP1", "source": 0 }, + { "begin": 9226, "end": 9241, "name": "SLOAD", "source": 0 }, + { "begin": 9226, "end": 9241, "name": "SWAP1", "source": 0 }, + { + "begin": 9226, + "end": 9241, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 9226, "end": 9241, "name": "EXP", "source": 0 }, + { "begin": 9226, "end": 9241, "name": "SWAP1", "source": 0 }, + { "begin": 9226, "end": 9241, "name": "DIV", "source": 0 }, + { + "begin": 9226, + "end": 9241, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9226, "end": 9241, "name": "AND", "source": 0 }, + { + "begin": 9226, + "end": 9246, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9226, "end": 9246, "name": "AND", "source": 0 }, + { + "begin": 9226, + "end": 9246, + "name": "PUSH", + "source": 0, + "value": "9DC29FAC" + }, + { "begin": 9247, "end": 9251, "name": "DUP5", "source": 0 }, + { "begin": 9253, "end": 9258, "name": "DUP5", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9226, "end": 9259, "name": "MLOAD", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "DUP4", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 9226, "end": 9259, "name": "AND", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 9226, "end": 9259, "name": "SHL", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "DUP2", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "MSTORE", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 9226, "end": 9259, "name": "ADD", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH [tag]", + "source": 0, + "value": "231" + }, + { "begin": 9226, "end": 9259, "name": "SWAP3", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "SWAP2", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "SWAP1", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH [tag]", + "source": 0, + "value": "169" + }, + { + "begin": 9226, + "end": 9259, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9226, + "end": 9259, + "name": "tag", + "source": 0, + "value": "231" + }, + { "begin": 9226, "end": 9259, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9226, "end": 9259, "name": "MLOAD", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "DUP1", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "DUP4", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "SUB", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "DUP2", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9226, "end": 9259, "name": "DUP8", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "GAS", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "CALL", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "ISZERO", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "DUP1", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "ISZERO", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH [tag]", + "source": 0, + "value": "233" + }, + { "begin": 9226, "end": 9259, "name": "JUMPI", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9226, "end": 9259, "name": "DUP1", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 9226, + "end": 9259, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9226, "end": 9259, "name": "REVERT", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "tag", + "source": 0, + "value": "233" + }, + { "begin": 9226, "end": 9259, "name": "JUMPDEST", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "POP", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "POP", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "POP", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "POP", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9226, "end": 9259, "name": "MLOAD", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9226, "end": 9259, "name": "NOT", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9226, "end": 9259, "name": "DUP3", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "ADD", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "AND", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "DUP3", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "ADD", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "DUP1", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9226, "end": 9259, "name": "MSTORE", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "POP", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "DUP2", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "ADD", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "SWAP1", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH [tag]", + "source": 0, + "value": "234" + }, + { "begin": 9226, "end": 9259, "name": "SWAP2", "source": 0 }, + { "begin": 9226, "end": 9259, "name": "SWAP1", "source": 0 }, + { + "begin": 9226, + "end": 9259, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 9226, + "end": 9259, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9226, + "end": 9259, + "name": "tag", + "source": 0, + "value": "234" + }, + { "begin": 9226, "end": 9259, "name": "JUMPDEST", "source": 0 }, + { "begin": 9219, "end": 9259, "name": "SWAP1", "source": 0 }, + { "begin": 9219, "end": 9259, "name": "POP", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "SWAP3", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "SWAP2", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "POP", "source": 0 }, + { "begin": 9125, "end": 9274, "name": "POP", "source": 0 }, + { + "begin": 9125, + "end": 9274, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 10616, + "end": 10902, + "name": "tag", + "source": 0, + "value": "122" + }, + { "begin": 10616, "end": 10902, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10688, + "end": 10692, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10709, "end": 10720, "name": "DUP1", "source": 0 }, + { + "begin": 10722, + "end": 10739, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 10743, + "end": 10765, + "name": "PUSH", + "source": 0, + "value": "1" + }, + { + "begin": 10743, + "end": 10765, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10743, "end": 10765, "name": "SWAP1", "source": 0 }, + { "begin": 10743, "end": 10765, "name": "SLOAD", "source": 0 }, + { "begin": 10743, "end": 10765, "name": "SWAP1", "source": 0 }, + { + "begin": 10743, + "end": 10765, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 10743, "end": 10765, "name": "EXP", "source": 0 }, + { "begin": 10743, "end": 10765, "name": "SWAP1", "source": 0 }, + { "begin": 10743, "end": 10765, "name": "DIV", "source": 0 }, + { + "begin": 10743, + "end": 10765, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 10743, "end": 10765, "name": "AND", "source": 0 }, + { + "begin": 10743, + "end": 10778, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 10743, "end": 10778, "name": "AND", "source": 0 }, + { "begin": 10849, "end": 10851, "name": "DUP6", "source": 0 }, + { "begin": 10853, "end": 10858, "name": "DUP6", "source": 0 }, + { + "begin": 10796, + "end": 10859, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10796, "end": 10859, "name": "MLOAD", "source": 0 }, + { + "begin": 10796, + "end": 10859, + "name": "PUSH", + "source": 0, + "value": "24" + }, + { "begin": 10796, "end": 10859, "name": "ADD", "source": 0 }, + { + "begin": 10796, + "end": 10859, + "name": "PUSH [tag]", + "source": 0, + "value": "236" + }, + { "begin": 10796, "end": 10859, "name": "SWAP3", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "SWAP2", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "SWAP1", "source": 0 }, + { + "begin": 10796, + "end": 10859, + "name": "PUSH [tag]", + "source": 0, + "value": "169" + }, + { + "begin": 10796, + "end": 10859, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10796, + "end": 10859, + "name": "tag", + "source": 0, + "value": "236" + }, + { "begin": 10796, "end": 10859, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10796, + "end": 10859, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10796, "end": 10859, "name": "MLOAD", "source": 0 }, + { + "begin": 10796, + "end": 10859, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { "begin": 10796, "end": 10859, "name": "DUP2", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "DUP4", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "SUB", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "SUB", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "DUP2", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "MSTORE", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "SWAP1", "source": 0 }, + { + "begin": 10796, + "end": 10859, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10796, "end": 10859, "name": "MSTORE", "source": 0 }, + { + "begin": 10796, + "end": 10859, + "name": "PUSH", + "source": 0, + "value": "A9059CBB00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 10796, + "end": 10859, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 10796, "end": 10859, "name": "NOT", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "AND", "source": 0 }, + { + "begin": 10796, + "end": 10859, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { "begin": 10796, "end": 10859, "name": "DUP3", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "ADD", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "DUP1", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "MLOAD", "source": 0 }, + { + "begin": 10796, + "end": 10859, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 10796, "end": 10859, "name": "DUP4", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "DUP2", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "DUP4", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "AND", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "OR", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "DUP4", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "MSTORE", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "POP", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "POP", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "POP", "source": 0 }, + { "begin": 10796, "end": 10859, "name": "POP", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10743, "end": 10860, "name": "MLOAD", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH [tag]", + "source": 0, + "value": "237" + }, + { "begin": 10743, "end": 10860, "name": "SWAP2", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "SWAP1", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH [tag]", + "source": 0, + "value": "216" + }, + { + "begin": 10743, + "end": 10860, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10743, + "end": 10860, + "name": "tag", + "source": 0, + "value": "237" + }, + { "begin": 10743, "end": 10860, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10743, "end": 10860, "name": "MLOAD", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "DUP1", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "DUP4", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "SUB", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "DUP2", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "DUP6", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "GAS", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "DELEGATECALL", + "source": 0 + }, + { "begin": 10743, "end": 10860, "name": "SWAP2", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "POP", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "POP", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "RETURNDATASIZE", + "source": 0 + }, + { "begin": 10743, "end": 10860, "name": "DUP1", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10743, "end": 10860, "name": "DUP2", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "EQ", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH [tag]", + "source": 0, + "value": "240" + }, + { "begin": 10743, "end": 10860, "name": "JUMPI", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10743, "end": 10860, "name": "MLOAD", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "SWAP2", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "POP", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 10743, "end": 10860, "name": "NOT", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH", + "source": 0, + "value": "3F" + }, + { + "begin": 10743, + "end": 10860, + "name": "RETURNDATASIZE", + "source": 0 + }, + { "begin": 10743, "end": 10860, "name": "ADD", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "AND", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "DUP3", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "ADD", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10743, "end": 10860, "name": "MSTORE", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "RETURNDATASIZE", + "source": 0 + }, + { "begin": 10743, "end": 10860, "name": "DUP3", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "MSTORE", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { "begin": 10743, "end": 10860, "name": "DUP5", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "ADD", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH [tag]", + "source": 0, + "value": "239" + }, + { "begin": 10743, "end": 10860, "name": "JUMP", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "tag", + "source": 0, + "value": "240" + }, + { "begin": 10743, "end": 10860, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "PUSH", + "source": 0, + "value": "60" + }, + { "begin": 10743, "end": 10860, "name": "SWAP2", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "POP", "source": 0 }, + { + "begin": 10743, + "end": 10860, + "name": "tag", + "source": 0, + "value": "239" + }, + { "begin": 10743, "end": 10860, "name": "JUMPDEST", "source": 0 }, + { "begin": 10743, "end": 10860, "name": "POP", "source": 0 }, + { "begin": 10708, "end": 10860, "name": "SWAP2", "source": 0 }, + { "begin": 10708, "end": 10860, "name": "POP", "source": 0 }, + { "begin": 10708, "end": 10860, "name": "SWAP2", "source": 0 }, + { "begin": 10708, "end": 10860, "name": "POP", "source": 0 }, + { "begin": 10881, "end": 10887, "name": "DUP2", "source": 0 }, + { "begin": 10874, "end": 10887, "name": "SWAP3", "source": 0 }, + { "begin": 10874, "end": 10887, "name": "POP", "source": 0 }, + { "begin": 10874, "end": 10887, "name": "POP", "source": 0 }, + { "begin": 10874, "end": 10887, "name": "POP", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "SWAP3", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "SWAP2", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "POP", "source": 0 }, + { "begin": 10616, "end": 10902, "name": "POP", "source": 0 }, + { + "begin": 10616, + "end": 10902, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 8799, + "end": 8952, + "name": "tag", + "source": 0, + "value": "127" + }, + { "begin": 8799, "end": 8952, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8871, + "end": 8875, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8902, "end": 8917, "name": "DUP1", "source": 0 }, + { + "begin": 8902, + "end": 8917, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8902, "end": 8917, "name": "SWAP1", "source": 0 }, + { "begin": 8902, "end": 8917, "name": "SLOAD", "source": 0 }, + { "begin": 8902, "end": 8917, "name": "SWAP1", "source": 0 }, + { + "begin": 8902, + "end": 8917, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 8902, "end": 8917, "name": "EXP", "source": 0 }, + { "begin": 8902, "end": 8917, "name": "SWAP1", "source": 0 }, + { "begin": 8902, "end": 8917, "name": "DIV", "source": 0 }, + { + "begin": 8902, + "end": 8917, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 8902, "end": 8917, "name": "AND", "source": 0 }, + { + "begin": 8902, + "end": 8926, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 8902, "end": 8926, "name": "AND", "source": 0 }, + { + "begin": 8902, + "end": 8926, + "name": "PUSH", + "source": 0, + "value": "A9059CBB" + }, + { "begin": 8927, "end": 8929, "name": "DUP5", "source": 0 }, + { "begin": 8931, "end": 8936, "name": "DUP5", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8902, "end": 8937, "name": "MLOAD", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "DUP4", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 8902, "end": 8937, "name": "AND", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 8902, "end": 8937, "name": "SHL", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "DUP2", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "MSTORE", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 8902, "end": 8937, "name": "ADD", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH [tag]", + "source": 0, + "value": "242" + }, + { "begin": 8902, "end": 8937, "name": "SWAP3", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "SWAP2", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "SWAP1", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH [tag]", + "source": 0, + "value": "169" + }, + { + "begin": 8902, + "end": 8937, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8902, + "end": 8937, + "name": "tag", + "source": 0, + "value": "242" + }, + { "begin": 8902, "end": 8937, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8902, "end": 8937, "name": "MLOAD", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "DUP1", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "DUP4", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "SUB", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "DUP2", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8902, "end": 8937, "name": "DUP8", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "GAS", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "CALL", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "ISZERO", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "DUP1", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "ISZERO", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH [tag]", + "source": 0, + "value": "244" + }, + { "begin": 8902, "end": 8937, "name": "JUMPI", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8902, "end": 8937, "name": "DUP1", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 8902, + "end": 8937, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8902, "end": 8937, "name": "REVERT", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "tag", + "source": 0, + "value": "244" + }, + { "begin": 8902, "end": 8937, "name": "JUMPDEST", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "POP", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "POP", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "POP", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "POP", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8902, "end": 8937, "name": "MLOAD", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 8902, "end": 8937, "name": "NOT", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 8902, "end": 8937, "name": "DUP3", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "ADD", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "AND", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "DUP3", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "ADD", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "DUP1", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8902, "end": 8937, "name": "MSTORE", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "POP", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "DUP2", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "ADD", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "SWAP1", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH [tag]", + "source": 0, + "value": "245" + }, + { "begin": 8902, "end": 8937, "name": "SWAP2", "source": 0 }, + { "begin": 8902, "end": 8937, "name": "SWAP1", "source": 0 }, + { + "begin": 8902, + "end": 8937, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 8902, + "end": 8937, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8902, + "end": 8937, + "name": "tag", + "source": 0, + "value": "245" + }, + { "begin": 8902, "end": 8937, "name": "JUMPDEST", "source": 0 }, + { "begin": 8895, "end": 8937, "name": "SWAP1", "source": 0 }, + { "begin": 8895, "end": 8937, "name": "POP", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "SWAP3", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "SWAP2", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "POP", "source": 0 }, + { "begin": 8799, "end": 8952, "name": "POP", "source": 0 }, + { + "begin": 8799, + "end": 8952, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 10459, + "end": 10590, + "name": "tag", + "source": 0, + "value": "131" + }, + { "begin": 10459, "end": 10590, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10512, + "end": 10516, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10543, "end": 10558, "name": "DUP1", "source": 0 }, + { + "begin": 10543, + "end": 10558, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10543, "end": 10558, "name": "SWAP1", "source": 0 }, + { "begin": 10543, "end": 10558, "name": "SLOAD", "source": 0 }, + { "begin": 10543, "end": 10558, "name": "SWAP1", "source": 0 }, + { + "begin": 10543, + "end": 10558, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 10543, "end": 10558, "name": "EXP", "source": 0 }, + { "begin": 10543, "end": 10558, "name": "SWAP1", "source": 0 }, + { "begin": 10543, "end": 10558, "name": "DIV", "source": 0 }, + { + "begin": 10543, + "end": 10558, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 10543, "end": 10558, "name": "AND", "source": 0 }, + { + "begin": 10543, + "end": 10573, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 10543, "end": 10573, "name": "AND", "source": 0 }, + { + "begin": 10543, + "end": 10573, + "name": "PUSH", + "source": 0, + "value": "D3BA4B9E" + }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10543, "end": 10575, "name": "MLOAD", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "DUP2", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 10543, "end": 10575, "name": "AND", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 10543, "end": 10575, "name": "SHL", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "DUP2", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "MSTORE", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 10543, "end": 10575, "name": "ADD", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10543, "end": 10575, "name": "MLOAD", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "DUP1", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "DUP4", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "SUB", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "DUP2", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10543, "end": 10575, "name": "DUP8", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "GAS", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "CALL", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "ISZERO", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "DUP1", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "ISZERO", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH [tag]", + "source": 0, + "value": "248" + }, + { "begin": 10543, "end": 10575, "name": "JUMPI", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10543, "end": 10575, "name": "DUP1", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 10543, + "end": 10575, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10543, "end": 10575, "name": "REVERT", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "tag", + "source": 0, + "value": "248" + }, + { "begin": 10543, "end": 10575, "name": "JUMPDEST", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "POP", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "POP", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "POP", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "POP", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10543, "end": 10575, "name": "MLOAD", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 10543, "end": 10575, "name": "NOT", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 10543, "end": 10575, "name": "DUP3", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "ADD", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "AND", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "DUP3", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "ADD", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "DUP1", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10543, "end": 10575, "name": "MSTORE", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "POP", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "DUP2", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "ADD", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "SWAP1", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH [tag]", + "source": 0, + "value": "249" + }, + { "begin": 10543, "end": 10575, "name": "SWAP2", "source": 0 }, + { "begin": 10543, "end": 10575, "name": "SWAP1", "source": 0 }, + { + "begin": 10543, + "end": 10575, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 10543, + "end": 10575, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10543, + "end": 10575, + "name": "tag", + "source": 0, + "value": "249" + }, + { "begin": 10543, "end": 10575, "name": "JUMPDEST", "source": 0 }, + { "begin": 10536, "end": 10575, "name": "SWAP1", "source": 0 }, + { "begin": 10536, "end": 10575, "name": "POP", "source": 0 }, + { "begin": 10459, "end": 10590, "name": "SWAP1", "source": 0 }, + { + "begin": 10459, + "end": 10590, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 8567, + "end": 8785, + "name": "tag", + "source": 0, + "value": "137" + }, + { "begin": 8567, "end": 8785, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8696, + "end": 8703, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8729, "end": 8744, "name": "DUP1", "source": 0 }, + { + "begin": 8729, + "end": 8744, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8729, "end": 8744, "name": "SWAP1", "source": 0 }, + { "begin": 8729, "end": 8744, "name": "SLOAD", "source": 0 }, + { "begin": 8729, "end": 8744, "name": "SWAP1", "source": 0 }, + { + "begin": 8729, + "end": 8744, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 8729, "end": 8744, "name": "EXP", "source": 0 }, + { "begin": 8729, "end": 8744, "name": "SWAP1", "source": 0 }, + { "begin": 8729, "end": 8744, "name": "DIV", "source": 0 }, + { + "begin": 8729, + "end": 8744, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 8729, "end": 8744, "name": "AND", "source": 0 }, + { + "begin": 8729, + "end": 8754, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 8729, "end": 8754, "name": "AND", "source": 0 }, + { + "begin": 8729, + "end": 8754, + "name": "PUSH", + "source": 0, + "value": "DD62ED3E" + }, + { "begin": 8755, "end": 8760, "name": "DUP5", "source": 0 }, + { "begin": 8762, "end": 8769, "name": "DUP5", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8729, "end": 8770, "name": "MLOAD", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "DUP4", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 8729, "end": 8770, "name": "AND", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 8729, "end": 8770, "name": "SHL", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "DUP2", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "MSTORE", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 8729, "end": 8770, "name": "ADD", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH [tag]", + "source": 0, + "value": "251" + }, + { "begin": 8729, "end": 8770, "name": "SWAP3", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "SWAP2", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "SWAP1", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH [tag]", + "source": 0, + "value": "252" + }, + { + "begin": 8729, + "end": 8770, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8729, + "end": 8770, + "name": "tag", + "source": 0, + "value": "251" + }, + { "begin": 8729, "end": 8770, "name": "JUMPDEST", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8729, "end": 8770, "name": "MLOAD", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "DUP1", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "DUP4", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "SUB", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "DUP2", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "DUP7", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "GAS", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "STATICCALL", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "ISZERO", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "DUP1", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "ISZERO", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH [tag]", + "source": 0, + "value": "254" + }, + { "begin": 8729, "end": 8770, "name": "JUMPI", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8729, "end": 8770, "name": "DUP1", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 8729, + "end": 8770, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 8729, "end": 8770, "name": "REVERT", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "tag", + "source": 0, + "value": "254" + }, + { "begin": 8729, "end": 8770, "name": "JUMPDEST", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "POP", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "POP", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "POP", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "POP", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8729, "end": 8770, "name": "MLOAD", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 8729, "end": 8770, "name": "NOT", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 8729, "end": 8770, "name": "DUP3", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "ADD", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "AND", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "DUP3", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "ADD", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "DUP1", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 8729, "end": 8770, "name": "MSTORE", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "POP", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "DUP2", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "ADD", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "SWAP1", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH [tag]", + "source": 0, + "value": "255" + }, + { "begin": 8729, "end": 8770, "name": "SWAP2", "source": 0 }, + { "begin": 8729, "end": 8770, "name": "SWAP1", "source": 0 }, + { + "begin": 8729, + "end": 8770, + "name": "PUSH [tag]", + "source": 0, + "value": "178" + }, + { + "begin": 8729, + "end": 8770, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 8729, + "end": 8770, + "name": "tag", + "source": 0, + "value": "255" + }, + { "begin": 8729, "end": 8770, "name": "JUMPDEST", "source": 0 }, + { "begin": 8722, "end": 8770, "name": "SWAP1", "source": 0 }, + { "begin": 8722, "end": 8770, "name": "POP", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "SWAP3", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "SWAP2", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "POP", "source": 0 }, + { "begin": 8567, "end": 8785, "name": "POP", "source": 0 }, + { + "begin": 8567, + "end": 8785, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 10236, + "end": 10445, + "name": "tag", + "source": 0, + "value": "143" + }, + { "begin": 10236, "end": 10445, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10347, + "end": 10351, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10378, "end": 10393, "name": "DUP1", "source": 0 }, + { + "begin": 10378, + "end": 10393, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10378, "end": 10393, "name": "SWAP1", "source": 0 }, + { "begin": 10378, "end": 10393, "name": "SLOAD", "source": 0 }, + { "begin": 10378, "end": 10393, "name": "SWAP1", "source": 0 }, + { + "begin": 10378, + "end": 10393, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 10378, "end": 10393, "name": "EXP", "source": 0 }, + { "begin": 10378, "end": 10393, "name": "SWAP1", "source": 0 }, + { "begin": 10378, "end": 10393, "name": "DIV", "source": 0 }, + { + "begin": 10378, + "end": 10393, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 10378, "end": 10393, "name": "AND", "source": 0 }, + { + "begin": 10378, + "end": 10406, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 10378, "end": 10406, "name": "AND", "source": 0 }, + { + "begin": 10378, + "end": 10406, + "name": "PUSH", + "source": 0, + "value": "EE5DC1E4" + }, + { "begin": 10407, "end": 10411, "name": "DUP8", "source": 0 }, + { "begin": 10407, "end": 10411, "name": "DUP8", "source": 0 }, + { "begin": 10413, "end": 10419, "name": "DUP8", "source": 0 }, + { "begin": 10413, "end": 10419, "name": "DUP8", "source": 0 }, + { "begin": 10421, "end": 10429, "name": "DUP8", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10378, "end": 10430, "name": "MLOAD", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "DUP7", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 10378, "end": 10430, "name": "AND", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 10378, "end": 10430, "name": "SHL", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "DUP2", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "MSTORE", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 10378, "end": 10430, "name": "ADD", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH [tag]", + "source": 0, + "value": "257" + }, + { "begin": 10378, "end": 10430, "name": "SWAP6", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "SWAP5", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "SWAP4", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "SWAP3", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "SWAP2", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "SWAP1", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH [tag]", + "source": 0, + "value": "258" + }, + { + "begin": 10378, + "end": 10430, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10378, + "end": 10430, + "name": "tag", + "source": 0, + "value": "257" + }, + { "begin": 10378, "end": 10430, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10378, "end": 10430, "name": "MLOAD", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "DUP1", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "DUP4", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "SUB", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "DUP2", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10378, "end": 10430, "name": "DUP8", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "GAS", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "CALL", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "ISZERO", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "DUP1", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "ISZERO", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH [tag]", + "source": 0, + "value": "260" + }, + { "begin": 10378, "end": 10430, "name": "JUMPI", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10378, "end": 10430, "name": "DUP1", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 10378, + "end": 10430, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10378, "end": 10430, "name": "REVERT", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "tag", + "source": 0, + "value": "260" + }, + { "begin": 10378, "end": 10430, "name": "JUMPDEST", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "POP", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "POP", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "POP", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "POP", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10378, "end": 10430, "name": "MLOAD", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 10378, "end": 10430, "name": "NOT", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 10378, "end": 10430, "name": "DUP3", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "ADD", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "AND", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "DUP3", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "ADD", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "DUP1", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10378, "end": 10430, "name": "MSTORE", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "POP", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "DUP2", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "ADD", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "SWAP1", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH [tag]", + "source": 0, + "value": "261" + }, + { "begin": 10378, "end": 10430, "name": "SWAP2", "source": 0 }, + { "begin": 10378, "end": 10430, "name": "SWAP1", "source": 0 }, + { + "begin": 10378, + "end": 10430, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 10378, + "end": 10430, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10378, + "end": 10430, + "name": "tag", + "source": 0, + "value": "261" + }, + { "begin": 10378, "end": 10430, "name": "JUMPDEST", "source": 0 }, + { "begin": 10371, "end": 10430, "name": "SWAP1", "source": 0 }, + { "begin": 10371, "end": 10430, "name": "POP", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "SWAP6", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "SWAP5", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "POP", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "POP", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "POP", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "POP", "source": 0 }, + { "begin": 10236, "end": 10445, "name": "POP", "source": 0 }, + { + "begin": 10236, + "end": 10445, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 9864, + "end": 10021, + "name": "tag", + "source": 0, + "value": "148" + }, + { "begin": 9864, "end": 10021, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9934, + "end": 9938, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9965, "end": 9980, "name": "DUP1", "source": 0 }, + { + "begin": 9965, + "end": 9980, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9965, "end": 9980, "name": "SWAP1", "source": 0 }, + { "begin": 9965, "end": 9980, "name": "SLOAD", "source": 0 }, + { "begin": 9965, "end": 9980, "name": "SWAP1", "source": 0 }, + { + "begin": 9965, + "end": 9980, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 9965, "end": 9980, "name": "EXP", "source": 0 }, + { "begin": 9965, "end": 9980, "name": "SWAP1", "source": 0 }, + { "begin": 9965, "end": 9980, "name": "DIV", "source": 0 }, + { + "begin": 9965, + "end": 9980, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9965, "end": 9980, "name": "AND", "source": 0 }, + { + "begin": 9965, + "end": 9999, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 9965, "end": 9999, "name": "AND", "source": 0 }, + { + "begin": 9965, + "end": 9999, + "name": "PUSH", + "source": 0, + "value": "F0350C04" + }, + { "begin": 10000, "end": 10005, "name": "DUP4", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9965, "end": 10006, "name": "MLOAD", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "DUP3", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 9965, "end": 10006, "name": "AND", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 9965, "end": 10006, "name": "SHL", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "DUP2", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "MSTORE", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 9965, "end": 10006, "name": "ADD", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH [tag]", + "source": 0, + "value": "263" + }, + { "begin": 9965, "end": 10006, "name": "SWAP2", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "SWAP1", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH [tag]", + "source": 0, + "value": "38" + }, + { + "begin": 9965, + "end": 10006, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9965, + "end": 10006, + "name": "tag", + "source": 0, + "value": "263" + }, + { "begin": 9965, "end": 10006, "name": "JUMPDEST", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9965, "end": 10006, "name": "MLOAD", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "DUP1", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "DUP4", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "SUB", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "DUP2", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9965, "end": 10006, "name": "DUP8", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "GAS", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "CALL", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "ISZERO", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "DUP1", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "ISZERO", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH [tag]", + "source": 0, + "value": "265" + }, + { "begin": 9965, "end": 10006, "name": "JUMPI", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9965, "end": 10006, "name": "DUP1", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 9965, + "end": 10006, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 9965, "end": 10006, "name": "REVERT", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "tag", + "source": 0, + "value": "265" + }, + { "begin": 9965, "end": 10006, "name": "JUMPDEST", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "POP", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "POP", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "POP", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "POP", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9965, "end": 10006, "name": "MLOAD", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9965, "end": 10006, "name": "NOT", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 9965, "end": 10006, "name": "DUP3", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "ADD", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "AND", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "DUP3", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "ADD", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "DUP1", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 9965, "end": 10006, "name": "MSTORE", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "POP", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "DUP2", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "ADD", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "SWAP1", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH [tag]", + "source": 0, + "value": "266" + }, + { "begin": 9965, "end": 10006, "name": "SWAP2", "source": 0 }, + { "begin": 9965, "end": 10006, "name": "SWAP1", "source": 0 }, + { + "begin": 9965, + "end": 10006, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 9965, + "end": 10006, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 9965, + "end": 10006, + "name": "tag", + "source": 0, + "value": "266" + }, + { "begin": 9965, "end": 10006, "name": "JUMPDEST", "source": 0 }, + { "begin": 9958, "end": 10006, "name": "SWAP1", "source": 0 }, + { "begin": 9958, "end": 10006, "name": "POP", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "SWAP2", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "SWAP1", "source": 0 }, + { "begin": 9864, "end": 10021, "name": "POP", "source": 0 }, + { + "begin": 9864, + "end": 10021, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 11099, + "end": 11393, + "name": "tag", + "source": 0, + "value": "153" + }, + { "begin": 11099, "end": 11393, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11175, + "end": 11179, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11196, "end": 11207, "name": "DUP1", "source": 0 }, + { + "begin": 11209, + "end": 11226, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 11230, + "end": 11252, + "name": "PUSH", + "source": 0, + "value": "1" + }, + { + "begin": 11230, + "end": 11252, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11230, "end": 11252, "name": "SWAP1", "source": 0 }, + { "begin": 11230, "end": 11252, "name": "SLOAD", "source": 0 }, + { "begin": 11230, "end": 11252, "name": "SWAP1", "source": 0 }, + { + "begin": 11230, + "end": 11252, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 11230, "end": 11252, "name": "EXP", "source": 0 }, + { "begin": 11230, "end": 11252, "name": "SWAP1", "source": 0 }, + { "begin": 11230, "end": 11252, "name": "DIV", "source": 0 }, + { + "begin": 11230, + "end": 11252, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11230, "end": 11252, "name": "AND", "source": 0 }, + { + "begin": 11230, + "end": 11265, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11230, "end": 11265, "name": "AND", "source": 0 }, + { "begin": 11335, "end": 11342, "name": "DUP6", "source": 0 }, + { "begin": 11344, "end": 11349, "name": "DUP6", "source": 0 }, + { + "begin": 11283, + "end": 11350, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11283, "end": 11350, "name": "MLOAD", "source": 0 }, + { + "begin": 11283, + "end": 11350, + "name": "PUSH", + "source": 0, + "value": "24" + }, + { "begin": 11283, "end": 11350, "name": "ADD", "source": 0 }, + { + "begin": 11283, + "end": 11350, + "name": "PUSH [tag]", + "source": 0, + "value": "268" + }, + { "begin": 11283, "end": 11350, "name": "SWAP3", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "SWAP2", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "SWAP1", "source": 0 }, + { + "begin": 11283, + "end": 11350, + "name": "PUSH [tag]", + "source": 0, + "value": "169" + }, + { + "begin": 11283, + "end": 11350, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11283, + "end": 11350, + "name": "tag", + "source": 0, + "value": "268" + }, + { "begin": 11283, "end": 11350, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11283, + "end": 11350, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11283, "end": 11350, "name": "MLOAD", "source": 0 }, + { + "begin": 11283, + "end": 11350, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { "begin": 11283, "end": 11350, "name": "DUP2", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "DUP4", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "SUB", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "SUB", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "DUP2", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "MSTORE", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "SWAP1", "source": 0 }, + { + "begin": 11283, + "end": 11350, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11283, "end": 11350, "name": "MSTORE", "source": 0 }, + { + "begin": 11283, + "end": 11350, + "name": "PUSH", + "source": 0, + "value": "95EA7B300000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 11283, + "end": 11350, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11283, "end": 11350, "name": "NOT", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "AND", "source": 0 }, + { + "begin": 11283, + "end": 11350, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { "begin": 11283, "end": 11350, "name": "DUP3", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "ADD", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "DUP1", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "MLOAD", "source": 0 }, + { + "begin": 11283, + "end": 11350, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 11283, "end": 11350, "name": "DUP4", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "DUP2", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "DUP4", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "AND", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "OR", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "DUP4", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "MSTORE", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "POP", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "POP", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "POP", "source": 0 }, + { "begin": 11283, "end": 11350, "name": "POP", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11230, "end": 11351, "name": "MLOAD", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH [tag]", + "source": 0, + "value": "269" + }, + { "begin": 11230, "end": 11351, "name": "SWAP2", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "SWAP1", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH [tag]", + "source": 0, + "value": "216" + }, + { + "begin": 11230, + "end": 11351, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 11230, + "end": 11351, + "name": "tag", + "source": 0, + "value": "269" + }, + { "begin": 11230, "end": 11351, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11230, "end": 11351, "name": "MLOAD", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "DUP1", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "DUP4", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "SUB", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "DUP2", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "DUP6", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "GAS", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "DELEGATECALL", + "source": 0 + }, + { "begin": 11230, "end": 11351, "name": "SWAP2", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "POP", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "POP", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "RETURNDATASIZE", + "source": 0 + }, + { "begin": 11230, "end": 11351, "name": "DUP1", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 11230, "end": 11351, "name": "DUP2", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "EQ", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH [tag]", + "source": 0, + "value": "272" + }, + { "begin": 11230, "end": 11351, "name": "JUMPI", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11230, "end": 11351, "name": "MLOAD", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "SWAP2", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "POP", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 11230, "end": 11351, "name": "NOT", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH", + "source": 0, + "value": "3F" + }, + { + "begin": 11230, + "end": 11351, + "name": "RETURNDATASIZE", + "source": 0 + }, + { "begin": 11230, "end": 11351, "name": "ADD", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "AND", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "DUP3", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "ADD", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 11230, "end": 11351, "name": "MSTORE", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "RETURNDATASIZE", + "source": 0 + }, + { "begin": 11230, "end": 11351, "name": "DUP3", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "MSTORE", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { "begin": 11230, "end": 11351, "name": "DUP5", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "ADD", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH [tag]", + "source": 0, + "value": "271" + }, + { "begin": 11230, "end": 11351, "name": "JUMP", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "tag", + "source": 0, + "value": "272" + }, + { "begin": 11230, "end": 11351, "name": "JUMPDEST", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "PUSH", + "source": 0, + "value": "60" + }, + { "begin": 11230, "end": 11351, "name": "SWAP2", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "POP", "source": 0 }, + { + "begin": 11230, + "end": 11351, + "name": "tag", + "source": 0, + "value": "271" + }, + { "begin": 11230, "end": 11351, "name": "JUMPDEST", "source": 0 }, + { "begin": 11230, "end": 11351, "name": "POP", "source": 0 }, + { "begin": 11195, "end": 11351, "name": "SWAP2", "source": 0 }, + { "begin": 11195, "end": 11351, "name": "POP", "source": 0 }, + { "begin": 11195, "end": 11351, "name": "SWAP2", "source": 0 }, + { "begin": 11195, "end": 11351, "name": "POP", "source": 0 }, + { "begin": 11372, "end": 11378, "name": "DUP2", "source": 0 }, + { "begin": 11365, "end": 11378, "name": "SWAP3", "source": 0 }, + { "begin": 11365, "end": 11378, "name": "POP", "source": 0 }, + { "begin": 11365, "end": 11378, "name": "POP", "source": 0 }, + { "begin": 11365, "end": 11378, "name": "POP", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "SWAP3", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "SWAP2", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "POP", "source": 0 }, + { "begin": 11099, "end": 11393, "name": "POP", "source": 0 }, + { + "begin": 11099, + "end": 11393, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 10035, + "end": 10222, + "name": "tag", + "source": 0, + "value": "159" + }, + { "begin": 10035, "end": 10222, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10128, + "end": 10132, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10159, "end": 10174, "name": "DUP1", "source": 0 }, + { + "begin": 10159, + "end": 10174, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10159, "end": 10174, "name": "SWAP1", "source": 0 }, + { "begin": 10159, "end": 10174, "name": "SLOAD", "source": 0 }, + { "begin": 10159, "end": 10174, "name": "SWAP1", "source": 0 }, + { + "begin": 10159, + "end": 10174, + "name": "PUSH", + "source": 0, + "value": "100" + }, + { "begin": 10159, "end": 10174, "name": "EXP", "source": 0 }, + { "begin": 10159, "end": 10174, "name": "SWAP1", "source": 0 }, + { "begin": 10159, "end": 10174, "name": "DIV", "source": 0 }, + { + "begin": 10159, + "end": 10174, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 10159, "end": 10174, "name": "AND", "source": 0 }, + { + "begin": 10159, + "end": 10183, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 10159, "end": 10183, "name": "AND", "source": 0 }, + { + "begin": 10159, + "end": 10183, + "name": "PUSH", + "source": 0, + "value": "F8BF8E95" + }, + { "begin": 10184, "end": 10190, "name": "DUP6", "source": 0 }, + { "begin": 10192, "end": 10197, "name": "DUP6", "source": 0 }, + { "begin": 10199, "end": 10206, "name": "DUP6", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10159, "end": 10207, "name": "MLOAD", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "DUP5", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "FFFFFFFF" + }, + { "begin": 10159, "end": 10207, "name": "AND", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "E0" + }, + { "begin": 10159, "end": 10207, "name": "SHL", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "DUP2", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "MSTORE", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "4" + }, + { "begin": 10159, "end": 10207, "name": "ADD", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH [tag]", + "source": 0, + "value": "274" + }, + { "begin": 10159, "end": 10207, "name": "SWAP4", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "SWAP3", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "SWAP2", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "SWAP1", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH [tag]", + "source": 0, + "value": "275" + }, + { + "begin": 10159, + "end": 10207, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10159, + "end": 10207, + "name": "tag", + "source": 0, + "value": "274" + }, + { "begin": 10159, "end": 10207, "name": "JUMPDEST", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "20" + }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10159, "end": 10207, "name": "MLOAD", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "DUP1", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "DUP4", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "SUB", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "DUP2", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10159, "end": 10207, "name": "DUP8", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "GAS", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "CALL", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "ISZERO", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "DUP1", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "ISZERO", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH [tag]", + "source": 0, + "value": "277" + }, + { "begin": 10159, "end": 10207, "name": "JUMPI", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10159, "end": 10207, "name": "DUP1", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "RETURNDATACOPY", + "source": 0 + }, + { + "begin": 10159, + "end": 10207, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "0" + }, + { "begin": 10159, "end": 10207, "name": "REVERT", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "tag", + "source": 0, + "value": "277" + }, + { "begin": 10159, "end": 10207, "name": "JUMPDEST", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "POP", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "POP", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "POP", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "POP", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10159, "end": 10207, "name": "MLOAD", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "RETURNDATASIZE", + "source": 0 + }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 10159, "end": 10207, "name": "NOT", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "1F" + }, + { "begin": 10159, "end": 10207, "name": "DUP3", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "ADD", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "AND", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "DUP3", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "ADD", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "DUP1", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH", + "source": 0, + "value": "40" + }, + { "begin": 10159, "end": 10207, "name": "MSTORE", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "POP", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "DUP2", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "ADD", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "SWAP1", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH [tag]", + "source": 0, + "value": "278" + }, + { "begin": 10159, "end": 10207, "name": "SWAP2", "source": 0 }, + { "begin": 10159, "end": 10207, "name": "SWAP1", "source": 0 }, + { + "begin": 10159, + "end": 10207, + "name": "PUSH [tag]", + "source": 0, + "value": "173" + }, + { + "begin": 10159, + "end": 10207, + "name": "JUMP", + "source": 0, + "value": "[in]" + }, + { + "begin": 10159, + "end": 10207, + "name": "tag", + "source": 0, + "value": "278" + }, + { "begin": 10159, "end": 10207, "name": "JUMPDEST", "source": 0 }, + { "begin": 10152, "end": 10207, "name": "SWAP1", "source": 0 }, + { "begin": 10152, "end": 10207, "name": "POP", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "SWAP4", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "SWAP3", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "POP", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "POP", "source": 0 }, + { "begin": 10035, "end": 10222, "name": "POP", "source": 0 }, + { + "begin": 10035, + "end": 10222, + "name": "JUMP", + "source": 0, + "value": "[out]" + }, + { + "begin": 7, + "end": 133, + "name": "tag", + "source": 1, + "value": "279" + }, + { "begin": 7, "end": 133, "name": "JUMPDEST", "source": 1 }, + { + "begin": 44, + "end": 51, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 84, + "end": 126, + "name": "PUSH", + "source": 1, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { "begin": 77, "end": 82, "name": "DUP3", "source": 1 }, + { "begin": 73, "end": 127, "name": "AND", "source": 1 }, + { "begin": 62, "end": 127, "name": "SWAP1", "source": 1 }, + { "begin": 62, "end": 127, "name": "POP", "source": 1 }, + { "begin": 7, "end": 133, "name": "SWAP2", "source": 1 }, + { "begin": 7, "end": 133, "name": "SWAP1", "source": 1 }, + { "begin": 7, "end": 133, "name": "POP", "source": 1 }, + { + "begin": 7, + "end": 133, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 139, + "end": 235, + "name": "tag", + "source": 1, + "value": "280" + }, + { "begin": 139, "end": 235, "name": "JUMPDEST", "source": 1 }, + { + "begin": 176, + "end": 183, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 205, + "end": 229, + "name": "PUSH [tag]", + "source": 1, + "value": "330" + }, + { "begin": 223, "end": 228, "name": "DUP3", "source": 1 }, + { + "begin": 205, + "end": 229, + "name": "PUSH [tag]", + "source": 1, + "value": "279" + }, + { + "begin": 205, + "end": 229, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 205, + "end": 229, + "name": "tag", + "source": 1, + "value": "330" + }, + { "begin": 205, "end": 229, "name": "JUMPDEST", "source": 1 }, + { "begin": 194, "end": 229, "name": "SWAP1", "source": 1 }, + { "begin": 194, "end": 229, "name": "POP", "source": 1 }, + { "begin": 139, "end": 235, "name": "SWAP2", "source": 1 }, + { "begin": 139, "end": 235, "name": "SWAP1", "source": 1 }, + { "begin": 139, "end": 235, "name": "POP", "source": 1 }, + { + "begin": 139, + "end": 235, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 241, + "end": 359, + "name": "tag", + "source": 1, + "value": "281" + }, + { "begin": 241, "end": 359, "name": "JUMPDEST", "source": 1 }, + { + "begin": 328, + "end": 352, + "name": "PUSH [tag]", + "source": 1, + "value": "332" + }, + { "begin": 346, "end": 351, "name": "DUP2", "source": 1 }, + { + "begin": 328, + "end": 352, + "name": "PUSH [tag]", + "source": 1, + "value": "280" + }, + { + "begin": 328, + "end": 352, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 328, + "end": 352, + "name": "tag", + "source": 1, + "value": "332" + }, + { "begin": 328, "end": 352, "name": "JUMPDEST", "source": 1 }, + { "begin": 323, "end": 326, "name": "DUP3", "source": 1 }, + { "begin": 316, "end": 353, "name": "MSTORE", "source": 1 }, + { "begin": 241, "end": 359, "name": "POP", "source": 1 }, + { "begin": 241, "end": 359, "name": "POP", "source": 1 }, + { + "begin": 241, + "end": 359, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 365, + "end": 587, + "name": "tag", + "source": 1, + "value": "38" + }, + { "begin": 365, "end": 587, "name": "JUMPDEST", "source": 1 }, + { + "begin": 458, + "end": 462, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 496, + "end": 498, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 485, "end": 494, "name": "DUP3", "source": 1 }, + { "begin": 481, "end": 499, "name": "ADD", "source": 1 }, + { "begin": 473, "end": 499, "name": "SWAP1", "source": 1 }, + { "begin": 473, "end": 499, "name": "POP", "source": 1 }, + { + "begin": 509, + "end": 580, + "name": "PUSH [tag]", + "source": 1, + "value": "334" + }, + { + "begin": 577, + "end": 578, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 566, "end": 575, "name": "DUP4", "source": 1 }, + { "begin": 562, "end": 579, "name": "ADD", "source": 1 }, + { "begin": 553, "end": 559, "name": "DUP5", "source": 1 }, + { + "begin": 509, + "end": 580, + "name": "PUSH [tag]", + "source": 1, + "value": "281" + }, + { + "begin": 509, + "end": 580, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 509, + "end": 580, + "name": "tag", + "source": 1, + "value": "334" + }, + { "begin": 509, "end": 580, "name": "JUMPDEST", "source": 1 }, + { "begin": 365, "end": 587, "name": "SWAP3", "source": 1 }, + { "begin": 365, "end": 587, "name": "SWAP2", "source": 1 }, + { "begin": 365, "end": 587, "name": "POP", "source": 1 }, + { "begin": 365, "end": 587, "name": "POP", "source": 1 }, + { + "begin": 365, + "end": 587, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 593, + "end": 692, + "name": "tag", + "source": 1, + "value": "282" + }, + { "begin": 593, "end": 692, "name": "JUMPDEST", "source": 1 }, + { + "begin": 645, + "end": 651, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 679, "end": 684, "name": "DUP2", "source": 1 }, + { "begin": 673, "end": 685, "name": "MLOAD", "source": 1 }, + { "begin": 663, "end": 685, "name": "SWAP1", "source": 1 }, + { "begin": 663, "end": 685, "name": "POP", "source": 1 }, + { "begin": 593, "end": 692, "name": "SWAP2", "source": 1 }, + { "begin": 593, "end": 692, "name": "SWAP1", "source": 1 }, + { "begin": 593, "end": 692, "name": "POP", "source": 1 }, + { + "begin": 593, + "end": 692, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 698, + "end": 867, + "name": "tag", + "source": 1, + "value": "283" + }, + { "begin": 698, "end": 867, "name": "JUMPDEST", "source": 1 }, + { + "begin": 782, + "end": 793, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 816, "end": 822, "name": "DUP3", "source": 1 }, + { "begin": 811, "end": 814, "name": "DUP3", "source": 1 }, + { "begin": 804, "end": 823, "name": "MSTORE", "source": 1 }, + { + "begin": 856, + "end": 860, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 851, "end": 854, "name": "DUP3", "source": 1 }, + { "begin": 847, "end": 861, "name": "ADD", "source": 1 }, + { "begin": 832, "end": 861, "name": "SWAP1", "source": 1 }, + { "begin": 832, "end": 861, "name": "POP", "source": 1 }, + { "begin": 698, "end": 867, "name": "SWAP3", "source": 1 }, + { "begin": 698, "end": 867, "name": "SWAP2", "source": 1 }, + { "begin": 698, "end": 867, "name": "POP", "source": 1 }, + { "begin": 698, "end": 867, "name": "POP", "source": 1 }, + { + "begin": 698, + "end": 867, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 873, + "end": 1180, + "name": "tag", + "source": 1, + "value": "284" + }, + { "begin": 873, "end": 1180, "name": "JUMPDEST", "source": 1 }, + { + "begin": 941, + "end": 942, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 951, + "end": 1064, + "name": "tag", + "source": 1, + "value": "338" + }, + { "begin": 951, "end": 1064, "name": "JUMPDEST", "source": 1 }, + { "begin": 965, "end": 971, "name": "DUP4", "source": 1 }, + { "begin": 962, "end": 963, "name": "DUP2", "source": 1 }, + { "begin": 959, "end": 972, "name": "LT", "source": 1 }, + { "begin": 951, "end": 1064, "name": "ISZERO", "source": 1 }, + { + "begin": 951, + "end": 1064, + "name": "PUSH [tag]", + "source": 1, + "value": "340" + }, + { "begin": 951, "end": 1064, "name": "JUMPI", "source": 1 }, + { "begin": 1050, "end": 1051, "name": "DUP1", "source": 1 }, + { "begin": 1045, "end": 1048, "name": "DUP3", "source": 1 }, + { "begin": 1041, "end": 1052, "name": "ADD", "source": 1 }, + { "begin": 1035, "end": 1053, "name": "MLOAD", "source": 1 }, + { "begin": 1031, "end": 1032, "name": "DUP2", "source": 1 }, + { "begin": 1026, "end": 1029, "name": "DUP5", "source": 1 }, + { "begin": 1022, "end": 1033, "name": "ADD", "source": 1 }, + { "begin": 1015, "end": 1054, "name": "MSTORE", "source": 1 }, + { + "begin": 987, + "end": 989, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 984, "end": 985, "name": "DUP2", "source": 1 }, + { "begin": 980, "end": 990, "name": "ADD", "source": 1 }, + { "begin": 975, "end": 990, "name": "SWAP1", "source": 1 }, + { "begin": 975, "end": 990, "name": "POP", "source": 1 }, + { + "begin": 951, + "end": 1064, + "name": "PUSH [tag]", + "source": 1, + "value": "338" + }, + { "begin": 951, "end": 1064, "name": "JUMP", "source": 1 }, + { + "begin": 951, + "end": 1064, + "name": "tag", + "source": 1, + "value": "340" + }, + { "begin": 951, "end": 1064, "name": "JUMPDEST", "source": 1 }, + { "begin": 1082, "end": 1088, "name": "DUP4", "source": 1 }, + { "begin": 1079, "end": 1080, "name": "DUP2", "source": 1 }, + { "begin": 1076, "end": 1089, "name": "GT", "source": 1 }, + { "begin": 1073, "end": 1174, "name": "ISZERO", "source": 1 }, + { + "begin": 1073, + "end": 1174, + "name": "PUSH [tag]", + "source": 1, + "value": "341" + }, + { "begin": 1073, "end": 1174, "name": "JUMPI", "source": 1 }, + { + "begin": 1162, + "end": 1163, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 1153, "end": 1159, "name": "DUP5", "source": 1 }, + { "begin": 1148, "end": 1151, "name": "DUP5", "source": 1 }, + { "begin": 1144, "end": 1160, "name": "ADD", "source": 1 }, + { "begin": 1137, "end": 1164, "name": "MSTORE", "source": 1 }, + { + "begin": 1073, + "end": 1174, + "name": "tag", + "source": 1, + "value": "341" + }, + { "begin": 1073, "end": 1174, "name": "JUMPDEST", "source": 1 }, + { "begin": 922, "end": 1180, "name": "POP", "source": 1 }, + { "begin": 873, "end": 1180, "name": "POP", "source": 1 }, + { "begin": 873, "end": 1180, "name": "POP", "source": 1 }, + { "begin": 873, "end": 1180, "name": "POP", "source": 1 }, + { + "begin": 873, + "end": 1180, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 1186, + "end": 1288, + "name": "tag", + "source": 1, + "value": "285" + }, + { "begin": 1186, "end": 1288, "name": "JUMPDEST", "source": 1 }, + { + "begin": 1227, + "end": 1233, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 1278, + "end": 1280, + "name": "PUSH", + "source": 1, + "value": "1F" + }, + { "begin": 1274, "end": 1281, "name": "NOT", "source": 1 }, + { + "begin": 1269, + "end": 1271, + "name": "PUSH", + "source": 1, + "value": "1F" + }, + { "begin": 1262, "end": 1267, "name": "DUP4", "source": 1 }, + { "begin": 1258, "end": 1272, "name": "ADD", "source": 1 }, + { "begin": 1254, "end": 1282, "name": "AND", "source": 1 }, + { "begin": 1244, "end": 1282, "name": "SWAP1", "source": 1 }, + { "begin": 1244, "end": 1282, "name": "POP", "source": 1 }, + { "begin": 1186, "end": 1288, "name": "SWAP2", "source": 1 }, + { "begin": 1186, "end": 1288, "name": "SWAP1", "source": 1 }, + { "begin": 1186, "end": 1288, "name": "POP", "source": 1 }, + { + "begin": 1186, + "end": 1288, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 1294, + "end": 1658, + "name": "tag", + "source": 1, + "value": "286" + }, + { "begin": 1294, "end": 1658, "name": "JUMPDEST", "source": 1 }, + { + "begin": 1382, + "end": 1385, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 1410, + "end": 1449, + "name": "PUSH [tag]", + "source": 1, + "value": "344" + }, + { "begin": 1443, "end": 1448, "name": "DUP3", "source": 1 }, + { + "begin": 1410, + "end": 1449, + "name": "PUSH [tag]", + "source": 1, + "value": "282" + }, + { + "begin": 1410, + "end": 1449, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 1410, + "end": 1449, + "name": "tag", + "source": 1, + "value": "344" + }, + { "begin": 1410, "end": 1449, "name": "JUMPDEST", "source": 1 }, + { + "begin": 1465, + "end": 1536, + "name": "PUSH [tag]", + "source": 1, + "value": "345" + }, + { "begin": 1529, "end": 1535, "name": "DUP2", "source": 1 }, + { "begin": 1524, "end": 1527, "name": "DUP6", "source": 1 }, + { + "begin": 1465, + "end": 1536, + "name": "PUSH [tag]", + "source": 1, + "value": "283" + }, + { + "begin": 1465, + "end": 1536, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 1465, + "end": 1536, + "name": "tag", + "source": 1, + "value": "345" + }, + { "begin": 1465, "end": 1536, "name": "JUMPDEST", "source": 1 }, + { "begin": 1458, "end": 1536, "name": "SWAP4", "source": 1 }, + { "begin": 1458, "end": 1536, "name": "POP", "source": 1 }, + { + "begin": 1545, + "end": 1597, + "name": "PUSH [tag]", + "source": 1, + "value": "346" + }, + { "begin": 1590, "end": 1596, "name": "DUP2", "source": 1 }, + { "begin": 1585, "end": 1588, "name": "DUP6", "source": 1 }, + { + "begin": 1578, + "end": 1582, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 1571, "end": 1576, "name": "DUP7", "source": 1 }, + { "begin": 1567, "end": 1583, "name": "ADD", "source": 1 }, + { + "begin": 1545, + "end": 1597, + "name": "PUSH [tag]", + "source": 1, + "value": "284" + }, + { + "begin": 1545, + "end": 1597, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 1545, + "end": 1597, + "name": "tag", + "source": 1, + "value": "346" + }, + { "begin": 1545, "end": 1597, "name": "JUMPDEST", "source": 1 }, + { + "begin": 1622, + "end": 1651, + "name": "PUSH [tag]", + "source": 1, + "value": "347" + }, + { "begin": 1644, "end": 1650, "name": "DUP2", "source": 1 }, + { + "begin": 1622, + "end": 1651, + "name": "PUSH [tag]", + "source": 1, + "value": "285" + }, + { + "begin": 1622, + "end": 1651, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 1622, + "end": 1651, + "name": "tag", + "source": 1, + "value": "347" + }, + { "begin": 1622, "end": 1651, "name": "JUMPDEST", "source": 1 }, + { "begin": 1617, "end": 1620, "name": "DUP5", "source": 1 }, + { "begin": 1613, "end": 1652, "name": "ADD", "source": 1 }, + { "begin": 1606, "end": 1652, "name": "SWAP2", "source": 1 }, + { "begin": 1606, "end": 1652, "name": "POP", "source": 1 }, + { "begin": 1386, "end": 1658, "name": "POP", "source": 1 }, + { "begin": 1294, "end": 1658, "name": "SWAP3", "source": 1 }, + { "begin": 1294, "end": 1658, "name": "SWAP2", "source": 1 }, + { "begin": 1294, "end": 1658, "name": "POP", "source": 1 }, + { "begin": 1294, "end": 1658, "name": "POP", "source": 1 }, + { + "begin": 1294, + "end": 1658, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 1664, + "end": 1977, + "name": "tag", + "source": 1, + "value": "43" + }, + { "begin": 1664, "end": 1977, "name": "JUMPDEST", "source": 1 }, + { + "begin": 1777, + "end": 1781, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 1815, + "end": 1817, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 1804, "end": 1813, "name": "DUP3", "source": 1 }, + { "begin": 1800, "end": 1818, "name": "ADD", "source": 1 }, + { "begin": 1792, "end": 1818, "name": "SWAP1", "source": 1 }, + { "begin": 1792, "end": 1818, "name": "POP", "source": 1 }, + { "begin": 1864, "end": 1873, "name": "DUP2", "source": 1 }, + { "begin": 1858, "end": 1862, "name": "DUP2", "source": 1 }, + { "begin": 1854, "end": 1874, "name": "SUB", "source": 1 }, + { + "begin": 1850, + "end": 1851, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 1839, "end": 1848, "name": "DUP4", "source": 1 }, + { "begin": 1835, "end": 1852, "name": "ADD", "source": 1 }, + { "begin": 1828, "end": 1875, "name": "MSTORE", "source": 1 }, + { + "begin": 1892, + "end": 1970, + "name": "PUSH [tag]", + "source": 1, + "value": "349" + }, + { "begin": 1965, "end": 1969, "name": "DUP2", "source": 1 }, + { "begin": 1956, "end": 1962, "name": "DUP5", "source": 1 }, + { + "begin": 1892, + "end": 1970, + "name": "PUSH [tag]", + "source": 1, + "value": "286" + }, + { + "begin": 1892, + "end": 1970, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 1892, + "end": 1970, + "name": "tag", + "source": 1, + "value": "349" + }, + { "begin": 1892, "end": 1970, "name": "JUMPDEST", "source": 1 }, + { "begin": 1884, "end": 1970, "name": "SWAP1", "source": 1 }, + { "begin": 1884, "end": 1970, "name": "POP", "source": 1 }, + { "begin": 1664, "end": 1977, "name": "SWAP3", "source": 1 }, + { "begin": 1664, "end": 1977, "name": "SWAP2", "source": 1 }, + { "begin": 1664, "end": 1977, "name": "POP", "source": 1 }, + { "begin": 1664, "end": 1977, "name": "POP", "source": 1 }, + { + "begin": 1664, + "end": 1977, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 1983, + "end": 2058, + "name": "tag", + "source": 1, + "value": "287" + }, + { "begin": 1983, "end": 2058, "name": "JUMPDEST", "source": 1 }, + { + "begin": 2016, + "end": 2022, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 2049, + "end": 2051, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { "begin": 2043, "end": 2052, "name": "MLOAD", "source": 1 }, + { "begin": 2033, "end": 2052, "name": "SWAP1", "source": 1 }, + { "begin": 2033, "end": 2052, "name": "POP", "source": 1 }, + { "begin": 1983, "end": 2058, "name": "SWAP1", "source": 1 }, + { + "begin": 1983, + "end": 2058, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 2064, + "end": 2181, + "name": "tag", + "source": 1, + "value": "288" + }, + { "begin": 2064, "end": 2181, "name": "JUMPDEST", "source": 1 }, + { + "begin": 2173, + "end": 2174, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 2170, "end": 2171, "name": "DUP1", "source": 1 }, + { "begin": 2163, "end": 2175, "name": "REVERT", "source": 1 }, + { + "begin": 2187, + "end": 2304, + "name": "tag", + "source": 1, + "value": "289" + }, + { "begin": 2187, "end": 2304, "name": "JUMPDEST", "source": 1 }, + { + "begin": 2296, + "end": 2297, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 2293, "end": 2294, "name": "DUP1", "source": 1 }, + { "begin": 2286, "end": 2298, "name": "REVERT", "source": 1 }, + { + "begin": 2310, + "end": 2432, + "name": "tag", + "source": 1, + "value": "290" + }, + { "begin": 2310, "end": 2432, "name": "JUMPDEST", "source": 1 }, + { + "begin": 2383, + "end": 2407, + "name": "PUSH [tag]", + "source": 1, + "value": "354" + }, + { "begin": 2401, "end": 2406, "name": "DUP2", "source": 1 }, + { + "begin": 2383, + "end": 2407, + "name": "PUSH [tag]", + "source": 1, + "value": "280" + }, + { + "begin": 2383, + "end": 2407, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 2383, + "end": 2407, + "name": "tag", + "source": 1, + "value": "354" + }, + { "begin": 2383, "end": 2407, "name": "JUMPDEST", "source": 1 }, + { "begin": 2376, "end": 2381, "name": "DUP2", "source": 1 }, + { "begin": 2373, "end": 2408, "name": "EQ", "source": 1 }, + { + "begin": 2363, + "end": 2426, + "name": "PUSH [tag]", + "source": 1, + "value": "355" + }, + { "begin": 2363, "end": 2426, "name": "JUMPI", "source": 1 }, + { + "begin": 2422, + "end": 2423, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 2419, "end": 2420, "name": "DUP1", "source": 1 }, + { "begin": 2412, "end": 2424, "name": "REVERT", "source": 1 }, + { + "begin": 2363, + "end": 2426, + "name": "tag", + "source": 1, + "value": "355" + }, + { "begin": 2363, "end": 2426, "name": "JUMPDEST", "source": 1 }, + { "begin": 2310, "end": 2432, "name": "POP", "source": 1 }, + { + "begin": 2310, + "end": 2432, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 2438, + "end": 2577, + "name": "tag", + "source": 1, + "value": "291" + }, + { "begin": 2438, "end": 2577, "name": "JUMPDEST", "source": 1 }, + { + "begin": 2484, + "end": 2489, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 2522, "end": 2528, "name": "DUP2", "source": 1 }, + { + "begin": 2509, + "end": 2529, + "name": "CALLDATALOAD", + "source": 1 + }, + { "begin": 2500, "end": 2529, "name": "SWAP1", "source": 1 }, + { "begin": 2500, "end": 2529, "name": "POP", "source": 1 }, + { + "begin": 2538, + "end": 2571, + "name": "PUSH [tag]", + "source": 1, + "value": "357" + }, + { "begin": 2565, "end": 2570, "name": "DUP2", "source": 1 }, + { + "begin": 2538, + "end": 2571, + "name": "PUSH [tag]", + "source": 1, + "value": "290" + }, + { + "begin": 2538, + "end": 2571, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 2538, + "end": 2571, + "name": "tag", + "source": 1, + "value": "357" + }, + { "begin": 2538, "end": 2571, "name": "JUMPDEST", "source": 1 }, + { "begin": 2438, "end": 2577, "name": "SWAP3", "source": 1 }, + { "begin": 2438, "end": 2577, "name": "SWAP2", "source": 1 }, + { "begin": 2438, "end": 2577, "name": "POP", "source": 1 }, + { "begin": 2438, "end": 2577, "name": "POP", "source": 1 }, + { + "begin": 2438, + "end": 2577, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 2583, + "end": 2660, + "name": "tag", + "source": 1, + "value": "292" + }, + { "begin": 2583, "end": 2660, "name": "JUMPDEST", "source": 1 }, + { + "begin": 2620, + "end": 2627, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 2649, "end": 2654, "name": "DUP2", "source": 1 }, + { "begin": 2638, "end": 2654, "name": "SWAP1", "source": 1 }, + { "begin": 2638, "end": 2654, "name": "POP", "source": 1 }, + { "begin": 2583, "end": 2660, "name": "SWAP2", "source": 1 }, + { "begin": 2583, "end": 2660, "name": "SWAP1", "source": 1 }, + { "begin": 2583, "end": 2660, "name": "POP", "source": 1 }, + { + "begin": 2583, + "end": 2660, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 2666, + "end": 2788, + "name": "tag", + "source": 1, + "value": "293" + }, + { "begin": 2666, "end": 2788, "name": "JUMPDEST", "source": 1 }, + { + "begin": 2739, + "end": 2763, + "name": "PUSH [tag]", + "source": 1, + "value": "360" + }, + { "begin": 2757, "end": 2762, "name": "DUP2", "source": 1 }, + { + "begin": 2739, + "end": 2763, + "name": "PUSH [tag]", + "source": 1, + "value": "292" + }, + { + "begin": 2739, + "end": 2763, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 2739, + "end": 2763, + "name": "tag", + "source": 1, + "value": "360" + }, + { "begin": 2739, "end": 2763, "name": "JUMPDEST", "source": 1 }, + { "begin": 2732, "end": 2737, "name": "DUP2", "source": 1 }, + { "begin": 2729, "end": 2764, "name": "EQ", "source": 1 }, + { + "begin": 2719, + "end": 2782, + "name": "PUSH [tag]", + "source": 1, + "value": "361" + }, + { "begin": 2719, "end": 2782, "name": "JUMPI", "source": 1 }, + { + "begin": 2778, + "end": 2779, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 2775, "end": 2776, "name": "DUP1", "source": 1 }, + { "begin": 2768, "end": 2780, "name": "REVERT", "source": 1 }, + { + "begin": 2719, + "end": 2782, + "name": "tag", + "source": 1, + "value": "361" + }, + { "begin": 2719, "end": 2782, "name": "JUMPDEST", "source": 1 }, + { "begin": 2666, "end": 2788, "name": "POP", "source": 1 }, + { + "begin": 2666, + "end": 2788, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 2794, + "end": 2933, + "name": "tag", + "source": 1, + "value": "294" + }, + { "begin": 2794, "end": 2933, "name": "JUMPDEST", "source": 1 }, + { + "begin": 2840, + "end": 2845, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 2878, "end": 2884, "name": "DUP2", "source": 1 }, + { + "begin": 2865, + "end": 2885, + "name": "CALLDATALOAD", + "source": 1 + }, + { "begin": 2856, "end": 2885, "name": "SWAP1", "source": 1 }, + { "begin": 2856, "end": 2885, "name": "POP", "source": 1 }, + { + "begin": 2894, + "end": 2927, + "name": "PUSH [tag]", + "source": 1, + "value": "363" + }, + { "begin": 2921, "end": 2926, "name": "DUP2", "source": 1 }, + { + "begin": 2894, + "end": 2927, + "name": "PUSH [tag]", + "source": 1, + "value": "293" + }, + { + "begin": 2894, + "end": 2927, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 2894, + "end": 2927, + "name": "tag", + "source": 1, + "value": "363" + }, + { "begin": 2894, "end": 2927, "name": "JUMPDEST", "source": 1 }, + { "begin": 2794, "end": 2933, "name": "SWAP3", "source": 1 }, + { "begin": 2794, "end": 2933, "name": "SWAP2", "source": 1 }, + { "begin": 2794, "end": 2933, "name": "POP", "source": 1 }, + { "begin": 2794, "end": 2933, "name": "POP", "source": 1 }, + { + "begin": 2794, + "end": 2933, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 2939, + "end": 3413, + "name": "tag", + "source": 1, + "value": "47" + }, + { "begin": 2939, "end": 3413, "name": "JUMPDEST", "source": 1 }, + { + "begin": 3007, + "end": 3013, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 3015, "end": 3021, "name": "DUP1", "source": 1 }, + { + "begin": 3064, + "end": 3066, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { "begin": 3052, "end": 3061, "name": "DUP4", "source": 1 }, + { "begin": 3043, "end": 3050, "name": "DUP6", "source": 1 }, + { "begin": 3039, "end": 3062, "name": "SUB", "source": 1 }, + { "begin": 3035, "end": 3067, "name": "SLT", "source": 1 }, + { "begin": 3032, "end": 3151, "name": "ISZERO", "source": 1 }, + { + "begin": 3032, + "end": 3151, + "name": "PUSH [tag]", + "source": 1, + "value": "365" + }, + { "begin": 3032, "end": 3151, "name": "JUMPI", "source": 1 }, + { + "begin": 3070, + "end": 3149, + "name": "PUSH [tag]", + "source": 1, + "value": "366" + }, + { + "begin": 3070, + "end": 3149, + "name": "PUSH [tag]", + "source": 1, + "value": "288" + }, + { + "begin": 3070, + "end": 3149, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 3070, + "end": 3149, + "name": "tag", + "source": 1, + "value": "366" + }, + { "begin": 3070, "end": 3149, "name": "JUMPDEST", "source": 1 }, + { + "begin": 3032, + "end": 3151, + "name": "tag", + "source": 1, + "value": "365" + }, + { "begin": 3032, "end": 3151, "name": "JUMPDEST", "source": 1 }, + { + "begin": 3190, + "end": 3191, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 3215, + "end": 3268, + "name": "PUSH [tag]", + "source": 1, + "value": "367" + }, + { "begin": 3260, "end": 3267, "name": "DUP6", "source": 1 }, + { "begin": 3251, "end": 3257, "name": "DUP3", "source": 1 }, + { "begin": 3240, "end": 3249, "name": "DUP7", "source": 1 }, + { "begin": 3236, "end": 3258, "name": "ADD", "source": 1 }, + { + "begin": 3215, + "end": 3268, + "name": "PUSH [tag]", + "source": 1, + "value": "291" + }, + { + "begin": 3215, + "end": 3268, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 3215, + "end": 3268, + "name": "tag", + "source": 1, + "value": "367" + }, + { "begin": 3215, "end": 3268, "name": "JUMPDEST", "source": 1 }, + { "begin": 3205, "end": 3268, "name": "SWAP3", "source": 1 }, + { "begin": 3205, "end": 3268, "name": "POP", "source": 1 }, + { "begin": 3161, "end": 3278, "name": "POP", "source": 1 }, + { + "begin": 3317, + "end": 3319, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { + "begin": 3343, + "end": 3396, + "name": "PUSH [tag]", + "source": 1, + "value": "368" + }, + { "begin": 3388, "end": 3395, "name": "DUP6", "source": 1 }, + { "begin": 3379, "end": 3385, "name": "DUP3", "source": 1 }, + { "begin": 3368, "end": 3377, "name": "DUP7", "source": 1 }, + { "begin": 3364, "end": 3386, "name": "ADD", "source": 1 }, + { + "begin": 3343, + "end": 3396, + "name": "PUSH [tag]", + "source": 1, + "value": "294" + }, + { + "begin": 3343, + "end": 3396, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 3343, + "end": 3396, + "name": "tag", + "source": 1, + "value": "368" + }, + { "begin": 3343, "end": 3396, "name": "JUMPDEST", "source": 1 }, + { "begin": 3333, "end": 3396, "name": "SWAP2", "source": 1 }, + { "begin": 3333, "end": 3396, "name": "POP", "source": 1 }, + { "begin": 3288, "end": 3406, "name": "POP", "source": 1 }, + { "begin": 2939, "end": 3413, "name": "SWAP3", "source": 1 }, + { "begin": 2939, "end": 3413, "name": "POP", "source": 1 }, + { "begin": 2939, "end": 3413, "name": "SWAP3", "source": 1 }, + { "begin": 2939, "end": 3413, "name": "SWAP1", "source": 1 }, + { "begin": 2939, "end": 3413, "name": "POP", "source": 1 }, + { + "begin": 2939, + "end": 3413, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 3419, + "end": 3509, + "name": "tag", + "source": 1, + "value": "295" + }, + { "begin": 3419, "end": 3509, "name": "JUMPDEST", "source": 1 }, + { + "begin": 3453, + "end": 3460, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 3496, "end": 3501, "name": "DUP2", "source": 1 }, + { "begin": 3489, "end": 3502, "name": "ISZERO", "source": 1 }, + { "begin": 3482, "end": 3503, "name": "ISZERO", "source": 1 }, + { "begin": 3471, "end": 3503, "name": "SWAP1", "source": 1 }, + { "begin": 3471, "end": 3503, "name": "POP", "source": 1 }, + { "begin": 3419, "end": 3509, "name": "SWAP2", "source": 1 }, + { "begin": 3419, "end": 3509, "name": "SWAP1", "source": 1 }, + { "begin": 3419, "end": 3509, "name": "POP", "source": 1 }, + { + "begin": 3419, + "end": 3509, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 3515, + "end": 3624, + "name": "tag", + "source": 1, + "value": "296" + }, + { "begin": 3515, "end": 3624, "name": "JUMPDEST", "source": 1 }, + { + "begin": 3596, + "end": 3617, + "name": "PUSH [tag]", + "source": 1, + "value": "371" + }, + { "begin": 3611, "end": 3616, "name": "DUP2", "source": 1 }, + { + "begin": 3596, + "end": 3617, + "name": "PUSH [tag]", + "source": 1, + "value": "295" + }, + { + "begin": 3596, + "end": 3617, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 3596, + "end": 3617, + "name": "tag", + "source": 1, + "value": "371" + }, + { "begin": 3596, "end": 3617, "name": "JUMPDEST", "source": 1 }, + { "begin": 3591, "end": 3594, "name": "DUP3", "source": 1 }, + { "begin": 3584, "end": 3618, "name": "MSTORE", "source": 1 }, + { "begin": 3515, "end": 3624, "name": "POP", "source": 1 }, + { "begin": 3515, "end": 3624, "name": "POP", "source": 1 }, + { + "begin": 3515, + "end": 3624, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 3630, + "end": 3840, + "name": "tag", + "source": 1, + "value": "50" + }, + { "begin": 3630, "end": 3840, "name": "JUMPDEST", "source": 1 }, + { + "begin": 3717, + "end": 3721, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 3755, + "end": 3757, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 3744, "end": 3753, "name": "DUP3", "source": 1 }, + { "begin": 3740, "end": 3758, "name": "ADD", "source": 1 }, + { "begin": 3732, "end": 3758, "name": "SWAP1", "source": 1 }, + { "begin": 3732, "end": 3758, "name": "POP", "source": 1 }, + { + "begin": 3768, + "end": 3833, + "name": "PUSH [tag]", + "source": 1, + "value": "373" + }, + { + "begin": 3830, + "end": 3831, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 3819, "end": 3828, "name": "DUP4", "source": 1 }, + { "begin": 3815, "end": 3832, "name": "ADD", "source": 1 }, + { "begin": 3806, "end": 3812, "name": "DUP5", "source": 1 }, + { + "begin": 3768, + "end": 3833, + "name": "PUSH [tag]", + "source": 1, + "value": "296" + }, + { + "begin": 3768, + "end": 3833, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 3768, + "end": 3833, + "name": "tag", + "source": 1, + "value": "373" + }, + { "begin": 3768, "end": 3833, "name": "JUMPDEST", "source": 1 }, + { "begin": 3630, "end": 3840, "name": "SWAP3", "source": 1 }, + { "begin": 3630, "end": 3840, "name": "SWAP2", "source": 1 }, + { "begin": 3630, "end": 3840, "name": "POP", "source": 1 }, + { "begin": 3630, "end": 3840, "name": "POP", "source": 1 }, + { + "begin": 3630, + "end": 3840, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 3846, + "end": 3964, + "name": "tag", + "source": 1, + "value": "297" + }, + { "begin": 3846, "end": 3964, "name": "JUMPDEST", "source": 1 }, + { + "begin": 3933, + "end": 3957, + "name": "PUSH [tag]", + "source": 1, + "value": "375" + }, + { "begin": 3951, "end": 3956, "name": "DUP2", "source": 1 }, + { + "begin": 3933, + "end": 3957, + "name": "PUSH [tag]", + "source": 1, + "value": "292" + }, + { + "begin": 3933, + "end": 3957, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 3933, + "end": 3957, + "name": "tag", + "source": 1, + "value": "375" + }, + { "begin": 3933, "end": 3957, "name": "JUMPDEST", "source": 1 }, + { "begin": 3928, "end": 3931, "name": "DUP3", "source": 1 }, + { "begin": 3921, "end": 3958, "name": "MSTORE", "source": 1 }, + { "begin": 3846, "end": 3964, "name": "POP", "source": 1 }, + { "begin": 3846, "end": 3964, "name": "POP", "source": 1 }, + { + "begin": 3846, + "end": 3964, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 3970, + "end": 4192, + "name": "tag", + "source": 1, + "value": "55" + }, + { "begin": 3970, "end": 4192, "name": "JUMPDEST", "source": 1 }, + { + "begin": 4063, + "end": 4067, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 4101, + "end": 4103, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 4090, "end": 4099, "name": "DUP3", "source": 1 }, + { "begin": 4086, "end": 4104, "name": "ADD", "source": 1 }, + { "begin": 4078, "end": 4104, "name": "SWAP1", "source": 1 }, + { "begin": 4078, "end": 4104, "name": "POP", "source": 1 }, + { + "begin": 4114, + "end": 4185, + "name": "PUSH [tag]", + "source": 1, + "value": "377" + }, + { + "begin": 4182, + "end": 4183, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 4171, "end": 4180, "name": "DUP4", "source": 1 }, + { "begin": 4167, "end": 4184, "name": "ADD", "source": 1 }, + { "begin": 4158, "end": 4164, "name": "DUP5", "source": 1 }, + { + "begin": 4114, + "end": 4185, + "name": "PUSH [tag]", + "source": 1, + "value": "297" + }, + { + "begin": 4114, + "end": 4185, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 4114, + "end": 4185, + "name": "tag", + "source": 1, + "value": "377" + }, + { "begin": 4114, "end": 4185, "name": "JUMPDEST", "source": 1 }, + { "begin": 3970, "end": 4192, "name": "SWAP3", "source": 1 }, + { "begin": 3970, "end": 4192, "name": "SWAP2", "source": 1 }, + { "begin": 3970, "end": 4192, "name": "POP", "source": 1 }, + { "begin": 3970, "end": 4192, "name": "POP", "source": 1 }, + { + "begin": 3970, + "end": 4192, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 4198, + "end": 4817, + "name": "tag", + "source": 1, + "value": "63" + }, + { "begin": 4198, "end": 4817, "name": "JUMPDEST", "source": 1 }, + { + "begin": 4275, + "end": 4281, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 4283, "end": 4289, "name": "DUP1", "source": 1 }, + { + "begin": 4291, + "end": 4297, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 4340, + "end": 4342, + "name": "PUSH", + "source": 1, + "value": "60" + }, + { "begin": 4328, "end": 4337, "name": "DUP5", "source": 1 }, + { "begin": 4319, "end": 4326, "name": "DUP7", "source": 1 }, + { "begin": 4315, "end": 4338, "name": "SUB", "source": 1 }, + { "begin": 4311, "end": 4343, "name": "SLT", "source": 1 }, + { "begin": 4308, "end": 4427, "name": "ISZERO", "source": 1 }, + { + "begin": 4308, + "end": 4427, + "name": "PUSH [tag]", + "source": 1, + "value": "379" + }, + { "begin": 4308, "end": 4427, "name": "JUMPI", "source": 1 }, + { + "begin": 4346, + "end": 4425, + "name": "PUSH [tag]", + "source": 1, + "value": "380" + }, + { + "begin": 4346, + "end": 4425, + "name": "PUSH [tag]", + "source": 1, + "value": "288" + }, + { + "begin": 4346, + "end": 4425, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 4346, + "end": 4425, + "name": "tag", + "source": 1, + "value": "380" + }, + { "begin": 4346, "end": 4425, "name": "JUMPDEST", "source": 1 }, + { + "begin": 4308, + "end": 4427, + "name": "tag", + "source": 1, + "value": "379" + }, + { "begin": 4308, "end": 4427, "name": "JUMPDEST", "source": 1 }, + { + "begin": 4466, + "end": 4467, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 4491, + "end": 4544, + "name": "PUSH [tag]", + "source": 1, + "value": "381" + }, + { "begin": 4536, "end": 4543, "name": "DUP7", "source": 1 }, + { "begin": 4527, "end": 4533, "name": "DUP3", "source": 1 }, + { "begin": 4516, "end": 4525, "name": "DUP8", "source": 1 }, + { "begin": 4512, "end": 4534, "name": "ADD", "source": 1 }, + { + "begin": 4491, + "end": 4544, + "name": "PUSH [tag]", + "source": 1, + "value": "291" + }, + { + "begin": 4491, + "end": 4544, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 4491, + "end": 4544, + "name": "tag", + "source": 1, + "value": "381" + }, + { "begin": 4491, "end": 4544, "name": "JUMPDEST", "source": 1 }, + { "begin": 4481, "end": 4544, "name": "SWAP4", "source": 1 }, + { "begin": 4481, "end": 4544, "name": "POP", "source": 1 }, + { "begin": 4437, "end": 4554, "name": "POP", "source": 1 }, + { + "begin": 4593, + "end": 4595, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { + "begin": 4619, + "end": 4672, + "name": "PUSH [tag]", + "source": 1, + "value": "382" + }, + { "begin": 4664, "end": 4671, "name": "DUP7", "source": 1 }, + { "begin": 4655, "end": 4661, "name": "DUP3", "source": 1 }, + { "begin": 4644, "end": 4653, "name": "DUP8", "source": 1 }, + { "begin": 4640, "end": 4662, "name": "ADD", "source": 1 }, + { + "begin": 4619, + "end": 4672, + "name": "PUSH [tag]", + "source": 1, + "value": "291" + }, + { + "begin": 4619, + "end": 4672, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 4619, + "end": 4672, + "name": "tag", + "source": 1, + "value": "382" + }, + { "begin": 4619, "end": 4672, "name": "JUMPDEST", "source": 1 }, + { "begin": 4609, "end": 4672, "name": "SWAP3", "source": 1 }, + { "begin": 4609, "end": 4672, "name": "POP", "source": 1 }, + { "begin": 4564, "end": 4682, "name": "POP", "source": 1 }, + { + "begin": 4721, + "end": 4723, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 4747, + "end": 4800, + "name": "PUSH [tag]", + "source": 1, + "value": "383" + }, + { "begin": 4792, "end": 4799, "name": "DUP7", "source": 1 }, + { "begin": 4783, "end": 4789, "name": "DUP3", "source": 1 }, + { "begin": 4772, "end": 4781, "name": "DUP8", "source": 1 }, + { "begin": 4768, "end": 4790, "name": "ADD", "source": 1 }, + { + "begin": 4747, + "end": 4800, + "name": "PUSH [tag]", + "source": 1, + "value": "294" + }, + { + "begin": 4747, + "end": 4800, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 4747, + "end": 4800, + "name": "tag", + "source": 1, + "value": "383" + }, + { "begin": 4747, "end": 4800, "name": "JUMPDEST", "source": 1 }, + { "begin": 4737, "end": 4800, "name": "SWAP2", "source": 1 }, + { "begin": 4737, "end": 4800, "name": "POP", "source": 1 }, + { "begin": 4692, "end": 4810, "name": "POP", "source": 1 }, + { "begin": 4198, "end": 4817, "name": "SWAP3", "source": 1 }, + { "begin": 4198, "end": 4817, "name": "POP", "source": 1 }, + { "begin": 4198, "end": 4817, "name": "SWAP3", "source": 1 }, + { "begin": 4198, "end": 4817, "name": "POP", "source": 1 }, + { "begin": 4198, "end": 4817, "name": "SWAP3", "source": 1 }, + { + "begin": 4198, + "end": 4817, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 4823, + "end": 4909, + "name": "tag", + "source": 1, + "value": "298" + }, + { "begin": 4823, "end": 4909, "name": "JUMPDEST", "source": 1 }, + { + "begin": 4858, + "end": 4865, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 4898, + "end": 4902, + "name": "PUSH", + "source": 1, + "value": "FF" + }, + { "begin": 4891, "end": 4896, "name": "DUP3", "source": 1 }, + { "begin": 4887, "end": 4903, "name": "AND", "source": 1 }, + { "begin": 4876, "end": 4903, "name": "SWAP1", "source": 1 }, + { "begin": 4876, "end": 4903, "name": "POP", "source": 1 }, + { "begin": 4823, "end": 4909, "name": "SWAP2", "source": 1 }, + { "begin": 4823, "end": 4909, "name": "SWAP1", "source": 1 }, + { "begin": 4823, "end": 4909, "name": "POP", "source": 1 }, + { + "begin": 4823, + "end": 4909, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 4915, + "end": 5027, + "name": "tag", + "source": 1, + "value": "299" + }, + { "begin": 4915, "end": 5027, "name": "JUMPDEST", "source": 1 }, + { + "begin": 4998, + "end": 5020, + "name": "PUSH [tag]", + "source": 1, + "value": "386" + }, + { "begin": 5014, "end": 5019, "name": "DUP2", "source": 1 }, + { + "begin": 4998, + "end": 5020, + "name": "PUSH [tag]", + "source": 1, + "value": "298" + }, + { + "begin": 4998, + "end": 5020, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 4998, + "end": 5020, + "name": "tag", + "source": 1, + "value": "386" + }, + { "begin": 4998, "end": 5020, "name": "JUMPDEST", "source": 1 }, + { "begin": 4993, "end": 4996, "name": "DUP3", "source": 1 }, + { "begin": 4986, "end": 5021, "name": "MSTORE", "source": 1 }, + { "begin": 4915, "end": 5027, "name": "POP", "source": 1 }, + { "begin": 4915, "end": 5027, "name": "POP", "source": 1 }, + { + "begin": 4915, + "end": 5027, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 5033, + "end": 5247, + "name": "tag", + "source": 1, + "value": "70" + }, + { "begin": 5033, "end": 5247, "name": "JUMPDEST", "source": 1 }, + { + "begin": 5122, + "end": 5126, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 5160, + "end": 5162, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 5149, "end": 5158, "name": "DUP3", "source": 1 }, + { "begin": 5145, "end": 5163, "name": "ADD", "source": 1 }, + { "begin": 5137, "end": 5163, "name": "SWAP1", "source": 1 }, + { "begin": 5137, "end": 5163, "name": "POP", "source": 1 }, + { + "begin": 5173, + "end": 5240, + "name": "PUSH [tag]", + "source": 1, + "value": "388" + }, + { + "begin": 5237, + "end": 5238, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 5226, "end": 5235, "name": "DUP4", "source": 1 }, + { "begin": 5222, "end": 5239, "name": "ADD", "source": 1 }, + { "begin": 5213, "end": 5219, "name": "DUP5", "source": 1 }, + { + "begin": 5173, + "end": 5240, + "name": "PUSH [tag]", + "source": 1, + "value": "299" + }, + { + "begin": 5173, + "end": 5240, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 5173, + "end": 5240, + "name": "tag", + "source": 1, + "value": "388" + }, + { "begin": 5173, "end": 5240, "name": "JUMPDEST", "source": 1 }, + { "begin": 5033, "end": 5247, "name": "SWAP3", "source": 1 }, + { "begin": 5033, "end": 5247, "name": "SWAP2", "source": 1 }, + { "begin": 5033, "end": 5247, "name": "POP", "source": 1 }, + { "begin": 5033, "end": 5247, "name": "POP", "source": 1 }, + { + "begin": 5033, + "end": 5247, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 5253, + "end": 5582, + "name": "tag", + "source": 1, + "value": "79" + }, + { "begin": 5253, "end": 5582, "name": "JUMPDEST", "source": 1 }, + { + "begin": 5312, + "end": 5318, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 5361, + "end": 5363, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 5349, "end": 5358, "name": "DUP3", "source": 1 }, + { "begin": 5340, "end": 5347, "name": "DUP5", "source": 1 }, + { "begin": 5336, "end": 5359, "name": "SUB", "source": 1 }, + { "begin": 5332, "end": 5364, "name": "SLT", "source": 1 }, + { "begin": 5329, "end": 5448, "name": "ISZERO", "source": 1 }, + { + "begin": 5329, + "end": 5448, + "name": "PUSH [tag]", + "source": 1, + "value": "390" + }, + { "begin": 5329, "end": 5448, "name": "JUMPI", "source": 1 }, + { + "begin": 5367, + "end": 5446, + "name": "PUSH [tag]", + "source": 1, + "value": "391" + }, + { + "begin": 5367, + "end": 5446, + "name": "PUSH [tag]", + "source": 1, + "value": "288" + }, + { + "begin": 5367, + "end": 5446, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 5367, + "end": 5446, + "name": "tag", + "source": 1, + "value": "391" + }, + { "begin": 5367, "end": 5446, "name": "JUMPDEST", "source": 1 }, + { + "begin": 5329, + "end": 5448, + "name": "tag", + "source": 1, + "value": "390" + }, + { "begin": 5329, "end": 5448, "name": "JUMPDEST", "source": 1 }, + { + "begin": 5487, + "end": 5488, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 5512, + "end": 5565, + "name": "PUSH [tag]", + "source": 1, + "value": "392" + }, + { "begin": 5557, "end": 5564, "name": "DUP5", "source": 1 }, + { "begin": 5548, "end": 5554, "name": "DUP3", "source": 1 }, + { "begin": 5537, "end": 5546, "name": "DUP6", "source": 1 }, + { "begin": 5533, "end": 5555, "name": "ADD", "source": 1 }, + { + "begin": 5512, + "end": 5565, + "name": "PUSH [tag]", + "source": 1, + "value": "291" + }, + { + "begin": 5512, + "end": 5565, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 5512, + "end": 5565, + "name": "tag", + "source": 1, + "value": "392" + }, + { "begin": 5512, "end": 5565, "name": "JUMPDEST", "source": 1 }, + { "begin": 5502, "end": 5565, "name": "SWAP2", "source": 1 }, + { "begin": 5502, "end": 5565, "name": "POP", "source": 1 }, + { "begin": 5458, "end": 5575, "name": "POP", "source": 1 }, + { "begin": 5253, "end": 5582, "name": "SWAP3", "source": 1 }, + { "begin": 5253, "end": 5582, "name": "SWAP2", "source": 1 }, + { "begin": 5253, "end": 5582, "name": "POP", "source": 1 }, + { "begin": 5253, "end": 5582, "name": "POP", "source": 1 }, + { + "begin": 5253, + "end": 5582, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 5588, + "end": 5648, + "name": "tag", + "source": 1, + "value": "300" + }, + { "begin": 5588, "end": 5648, "name": "JUMPDEST", "source": 1 }, + { + "begin": 5616, + "end": 5619, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 5637, "end": 5642, "name": "DUP2", "source": 1 }, + { "begin": 5630, "end": 5642, "name": "SWAP1", "source": 1 }, + { "begin": 5630, "end": 5642, "name": "POP", "source": 1 }, + { "begin": 5588, "end": 5648, "name": "SWAP2", "source": 1 }, + { "begin": 5588, "end": 5648, "name": "SWAP1", "source": 1 }, + { "begin": 5588, "end": 5648, "name": "POP", "source": 1 }, + { + "begin": 5588, + "end": 5648, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 5654, + "end": 5796, + "name": "tag", + "source": 1, + "value": "301" + }, + { "begin": 5654, "end": 5796, "name": "JUMPDEST", "source": 1 }, + { + "begin": 5704, + "end": 5713, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 5737, + "end": 5790, + "name": "PUSH [tag]", + "source": 1, + "value": "395" + }, + { + "begin": 5755, + "end": 5789, + "name": "PUSH [tag]", + "source": 1, + "value": "396" + }, + { + "begin": 5764, + "end": 5788, + "name": "PUSH [tag]", + "source": 1, + "value": "397" + }, + { "begin": 5782, "end": 5787, "name": "DUP5", "source": 1 }, + { + "begin": 5764, + "end": 5788, + "name": "PUSH [tag]", + "source": 1, + "value": "279" + }, + { + "begin": 5764, + "end": 5788, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 5764, + "end": 5788, + "name": "tag", + "source": 1, + "value": "397" + }, + { "begin": 5764, "end": 5788, "name": "JUMPDEST", "source": 1 }, + { + "begin": 5755, + "end": 5789, + "name": "PUSH [tag]", + "source": 1, + "value": "300" + }, + { + "begin": 5755, + "end": 5789, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 5755, + "end": 5789, + "name": "tag", + "source": 1, + "value": "396" + }, + { "begin": 5755, "end": 5789, "name": "JUMPDEST", "source": 1 }, + { + "begin": 5737, + "end": 5790, + "name": "PUSH [tag]", + "source": 1, + "value": "279" + }, + { + "begin": 5737, + "end": 5790, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 5737, + "end": 5790, + "name": "tag", + "source": 1, + "value": "395" + }, + { "begin": 5737, "end": 5790, "name": "JUMPDEST", "source": 1 }, + { "begin": 5724, "end": 5790, "name": "SWAP1", "source": 1 }, + { "begin": 5724, "end": 5790, "name": "POP", "source": 1 }, + { "begin": 5654, "end": 5796, "name": "SWAP2", "source": 1 }, + { "begin": 5654, "end": 5796, "name": "SWAP1", "source": 1 }, + { "begin": 5654, "end": 5796, "name": "POP", "source": 1 }, + { + "begin": 5654, + "end": 5796, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 5802, + "end": 5928, + "name": "tag", + "source": 1, + "value": "302" + }, + { "begin": 5802, "end": 5928, "name": "JUMPDEST", "source": 1 }, + { + "begin": 5852, + "end": 5861, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 5885, + "end": 5922, + "name": "PUSH [tag]", + "source": 1, + "value": "399" + }, + { "begin": 5916, "end": 5921, "name": "DUP3", "source": 1 }, + { + "begin": 5885, + "end": 5922, + "name": "PUSH [tag]", + "source": 1, + "value": "301" + }, + { + "begin": 5885, + "end": 5922, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 5885, + "end": 5922, + "name": "tag", + "source": 1, + "value": "399" + }, + { "begin": 5885, "end": 5922, "name": "JUMPDEST", "source": 1 }, + { "begin": 5872, "end": 5922, "name": "SWAP1", "source": 1 }, + { "begin": 5872, "end": 5922, "name": "POP", "source": 1 }, + { "begin": 5802, "end": 5928, "name": "SWAP2", "source": 1 }, + { "begin": 5802, "end": 5928, "name": "SWAP1", "source": 1 }, + { "begin": 5802, "end": 5928, "name": "POP", "source": 1 }, + { + "begin": 5802, + "end": 5928, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 5934, + "end": 6091, + "name": "tag", + "source": 1, + "value": "303" + }, + { "begin": 5934, "end": 6091, "name": "JUMPDEST", "source": 1 }, + { + "begin": 6015, + "end": 6024, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 6048, + "end": 6085, + "name": "PUSH [tag]", + "source": 1, + "value": "401" + }, + { "begin": 6079, "end": 6084, "name": "DUP3", "source": 1 }, + { + "begin": 6048, + "end": 6085, + "name": "PUSH [tag]", + "source": 1, + "value": "302" + }, + { + "begin": 6048, + "end": 6085, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 6048, + "end": 6085, + "name": "tag", + "source": 1, + "value": "401" + }, + { "begin": 6048, "end": 6085, "name": "JUMPDEST", "source": 1 }, + { "begin": 6035, "end": 6085, "name": "SWAP1", "source": 1 }, + { "begin": 6035, "end": 6085, "name": "POP", "source": 1 }, + { "begin": 5934, "end": 6091, "name": "SWAP2", "source": 1 }, + { "begin": 5934, "end": 6091, "name": "SWAP1", "source": 1 }, + { "begin": 5934, "end": 6091, "name": "POP", "source": 1 }, + { + "begin": 5934, + "end": 6091, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 6097, + "end": 6290, + "name": "tag", + "source": 1, + "value": "304" + }, + { "begin": 6097, "end": 6290, "name": "JUMPDEST", "source": 1 }, + { + "begin": 6215, + "end": 6283, + "name": "PUSH [tag]", + "source": 1, + "value": "403" + }, + { "begin": 6277, "end": 6282, "name": "DUP2", "source": 1 }, + { + "begin": 6215, + "end": 6283, + "name": "PUSH [tag]", + "source": 1, + "value": "303" + }, + { + "begin": 6215, + "end": 6283, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 6215, + "end": 6283, + "name": "tag", + "source": 1, + "value": "403" + }, + { "begin": 6215, "end": 6283, "name": "JUMPDEST", "source": 1 }, + { "begin": 6210, "end": 6213, "name": "DUP3", "source": 1 }, + { "begin": 6203, "end": 6284, "name": "MSTORE", "source": 1 }, + { "begin": 6097, "end": 6290, "name": "POP", "source": 1 }, + { "begin": 6097, "end": 6290, "name": "POP", "source": 1 }, + { + "begin": 6097, + "end": 6290, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 6296, + "end": 6580, + "name": "tag", + "source": 1, + "value": "113" + }, + { "begin": 6296, "end": 6580, "name": "JUMPDEST", "source": 1 }, + { + "begin": 6420, + "end": 6424, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 6458, + "end": 6460, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 6447, "end": 6456, "name": "DUP3", "source": 1 }, + { "begin": 6443, "end": 6461, "name": "ADD", "source": 1 }, + { "begin": 6435, "end": 6461, "name": "SWAP1", "source": 1 }, + { "begin": 6435, "end": 6461, "name": "POP", "source": 1 }, + { + "begin": 6471, + "end": 6573, + "name": "PUSH [tag]", + "source": 1, + "value": "405" + }, + { + "begin": 6570, + "end": 6571, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 6559, "end": 6568, "name": "DUP4", "source": 1 }, + { "begin": 6555, "end": 6572, "name": "ADD", "source": 1 }, + { "begin": 6546, "end": 6552, "name": "DUP5", "source": 1 }, + { + "begin": 6471, + "end": 6573, + "name": "PUSH [tag]", + "source": 1, + "value": "304" + }, + { + "begin": 6471, + "end": 6573, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 6471, + "end": 6573, + "name": "tag", + "source": 1, + "value": "405" + }, + { "begin": 6471, "end": 6573, "name": "JUMPDEST", "source": 1 }, + { "begin": 6296, "end": 6580, "name": "SWAP3", "source": 1 }, + { "begin": 6296, "end": 6580, "name": "SWAP2", "source": 1 }, + { "begin": 6296, "end": 6580, "name": "POP", "source": 1 }, + { "begin": 6296, "end": 6580, "name": "POP", "source": 1 }, + { + "begin": 6296, + "end": 6580, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 6586, + "end": 7060, + "name": "tag", + "source": 1, + "value": "136" + }, + { "begin": 6586, "end": 7060, "name": "JUMPDEST", "source": 1 }, + { + "begin": 6654, + "end": 6660, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 6662, "end": 6668, "name": "DUP1", "source": 1 }, + { + "begin": 6711, + "end": 6713, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { "begin": 6699, "end": 6708, "name": "DUP4", "source": 1 }, + { "begin": 6690, "end": 6697, "name": "DUP6", "source": 1 }, + { "begin": 6686, "end": 6709, "name": "SUB", "source": 1 }, + { "begin": 6682, "end": 6714, "name": "SLT", "source": 1 }, + { "begin": 6679, "end": 6798, "name": "ISZERO", "source": 1 }, + { + "begin": 6679, + "end": 6798, + "name": "PUSH [tag]", + "source": 1, + "value": "407" + }, + { "begin": 6679, "end": 6798, "name": "JUMPI", "source": 1 }, + { + "begin": 6717, + "end": 6796, + "name": "PUSH [tag]", + "source": 1, + "value": "408" + }, + { + "begin": 6717, + "end": 6796, + "name": "PUSH [tag]", + "source": 1, + "value": "288" + }, + { + "begin": 6717, + "end": 6796, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 6717, + "end": 6796, + "name": "tag", + "source": 1, + "value": "408" + }, + { "begin": 6717, "end": 6796, "name": "JUMPDEST", "source": 1 }, + { + "begin": 6679, + "end": 6798, + "name": "tag", + "source": 1, + "value": "407" + }, + { "begin": 6679, "end": 6798, "name": "JUMPDEST", "source": 1 }, + { + "begin": 6837, + "end": 6838, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 6862, + "end": 6915, + "name": "PUSH [tag]", + "source": 1, + "value": "409" + }, + { "begin": 6907, "end": 6914, "name": "DUP6", "source": 1 }, + { "begin": 6898, "end": 6904, "name": "DUP3", "source": 1 }, + { "begin": 6887, "end": 6896, "name": "DUP7", "source": 1 }, + { "begin": 6883, "end": 6905, "name": "ADD", "source": 1 }, + { + "begin": 6862, + "end": 6915, + "name": "PUSH [tag]", + "source": 1, + "value": "291" + }, + { + "begin": 6862, + "end": 6915, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 6862, + "end": 6915, + "name": "tag", + "source": 1, + "value": "409" + }, + { "begin": 6862, "end": 6915, "name": "JUMPDEST", "source": 1 }, + { "begin": 6852, "end": 6915, "name": "SWAP3", "source": 1 }, + { "begin": 6852, "end": 6915, "name": "POP", "source": 1 }, + { "begin": 6808, "end": 6925, "name": "POP", "source": 1 }, + { + "begin": 6964, + "end": 6966, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { + "begin": 6990, + "end": 7043, + "name": "PUSH [tag]", + "source": 1, + "value": "410" + }, + { "begin": 7035, "end": 7042, "name": "DUP6", "source": 1 }, + { "begin": 7026, "end": 7032, "name": "DUP3", "source": 1 }, + { "begin": 7015, "end": 7024, "name": "DUP7", "source": 1 }, + { "begin": 7011, "end": 7033, "name": "ADD", "source": 1 }, + { + "begin": 6990, + "end": 7043, + "name": "PUSH [tag]", + "source": 1, + "value": "291" + }, + { + "begin": 6990, + "end": 7043, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 6990, + "end": 7043, + "name": "tag", + "source": 1, + "value": "410" + }, + { "begin": 6990, "end": 7043, "name": "JUMPDEST", "source": 1 }, + { "begin": 6980, "end": 7043, "name": "SWAP2", "source": 1 }, + { "begin": 6980, "end": 7043, "name": "POP", "source": 1 }, + { "begin": 6935, "end": 7053, "name": "POP", "source": 1 }, + { "begin": 6586, "end": 7060, "name": "SWAP3", "source": 1 }, + { "begin": 6586, "end": 7060, "name": "POP", "source": 1 }, + { "begin": 6586, "end": 7060, "name": "SWAP3", "source": 1 }, + { "begin": 6586, "end": 7060, "name": "SWAP1", "source": 1 }, + { "begin": 6586, "end": 7060, "name": "POP", "source": 1 }, + { + "begin": 6586, + "end": 7060, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 7066, + "end": 7183, + "name": "tag", + "source": 1, + "value": "305" + }, + { "begin": 7066, "end": 7183, "name": "JUMPDEST", "source": 1 }, + { + "begin": 7175, + "end": 7176, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 7172, "end": 7173, "name": "DUP1", "source": 1 }, + { "begin": 7165, "end": 7177, "name": "REVERT", "source": 1 }, + { + "begin": 7189, + "end": 7306, + "name": "tag", + "source": 1, + "value": "306" + }, + { "begin": 7189, "end": 7306, "name": "JUMPDEST", "source": 1 }, + { + "begin": 7298, + "end": 7299, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 7295, "end": 7296, "name": "DUP1", "source": 1 }, + { "begin": 7288, "end": 7300, "name": "REVERT", "source": 1 }, + { + "begin": 7312, + "end": 7429, + "name": "tag", + "source": 1, + "value": "307" + }, + { "begin": 7312, "end": 7429, "name": "JUMPDEST", "source": 1 }, + { + "begin": 7421, + "end": 7422, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 7418, "end": 7419, "name": "DUP1", "source": 1 }, + { "begin": 7411, "end": 7423, "name": "REVERT", "source": 1 }, + { + "begin": 7449, + "end": 8002, + "name": "tag", + "source": 1, + "value": "308" + }, + { "begin": 7449, "end": 8002, "name": "JUMPDEST", "source": 1 }, + { + "begin": 7507, + "end": 7515, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 7517, "end": 7523, "name": "DUP1", "source": 1 }, + { "begin": 7567, "end": 7570, "name": "DUP4", "source": 1 }, + { + "begin": 7560, + "end": 7564, + "name": "PUSH", + "source": 1, + "value": "1F" + }, + { "begin": 7552, "end": 7558, "name": "DUP5", "source": 1 }, + { "begin": 7548, "end": 7565, "name": "ADD", "source": 1 }, + { "begin": 7544, "end": 7571, "name": "SLT", "source": 1 }, + { + "begin": 7534, + "end": 7656, + "name": "PUSH [tag]", + "source": 1, + "value": "415" + }, + { "begin": 7534, "end": 7656, "name": "JUMPI", "source": 1 }, + { + "begin": 7575, + "end": 7654, + "name": "PUSH [tag]", + "source": 1, + "value": "416" + }, + { + "begin": 7575, + "end": 7654, + "name": "PUSH [tag]", + "source": 1, + "value": "305" + }, + { + "begin": 7575, + "end": 7654, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 7575, + "end": 7654, + "name": "tag", + "source": 1, + "value": "416" + }, + { "begin": 7575, "end": 7654, "name": "JUMPDEST", "source": 1 }, + { + "begin": 7534, + "end": 7656, + "name": "tag", + "source": 1, + "value": "415" + }, + { "begin": 7534, "end": 7656, "name": "JUMPDEST", "source": 1 }, + { "begin": 7688, "end": 7694, "name": "DUP3", "source": 1 }, + { + "begin": 7675, + "end": 7695, + "name": "CALLDATALOAD", + "source": 1 + }, + { "begin": 7665, "end": 7695, "name": "SWAP1", "source": 1 }, + { "begin": 7665, "end": 7695, "name": "POP", "source": 1 }, + { + "begin": 7718, + "end": 7736, + "name": "PUSH", + "source": 1, + "value": "FFFFFFFFFFFFFFFF" + }, + { "begin": 7710, "end": 7716, "name": "DUP2", "source": 1 }, + { "begin": 7707, "end": 7737, "name": "GT", "source": 1 }, + { "begin": 7704, "end": 7821, "name": "ISZERO", "source": 1 }, + { + "begin": 7704, + "end": 7821, + "name": "PUSH [tag]", + "source": 1, + "value": "417" + }, + { "begin": 7704, "end": 7821, "name": "JUMPI", "source": 1 }, + { + "begin": 7740, + "end": 7819, + "name": "PUSH [tag]", + "source": 1, + "value": "418" + }, + { + "begin": 7740, + "end": 7819, + "name": "PUSH [tag]", + "source": 1, + "value": "306" + }, + { + "begin": 7740, + "end": 7819, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 7740, + "end": 7819, + "name": "tag", + "source": 1, + "value": "418" + }, + { "begin": 7740, "end": 7819, "name": "JUMPDEST", "source": 1 }, + { + "begin": 7704, + "end": 7821, + "name": "tag", + "source": 1, + "value": "417" + }, + { "begin": 7704, "end": 7821, "name": "JUMPDEST", "source": 1 }, + { + "begin": 7854, + "end": 7858, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 7846, "end": 7852, "name": "DUP4", "source": 1 }, + { "begin": 7842, "end": 7859, "name": "ADD", "source": 1 }, + { "begin": 7830, "end": 7859, "name": "SWAP2", "source": 1 }, + { "begin": 7830, "end": 7859, "name": "POP", "source": 1 }, + { "begin": 7908, "end": 7911, "name": "DUP4", "source": 1 }, + { + "begin": 7900, + "end": 7904, + "name": "PUSH", + "source": 1, + "value": "1" + }, + { "begin": 7892, "end": 7898, "name": "DUP3", "source": 1 }, + { "begin": 7888, "end": 7905, "name": "MUL", "source": 1 }, + { "begin": 7878, "end": 7886, "name": "DUP4", "source": 1 }, + { "begin": 7874, "end": 7906, "name": "ADD", "source": 1 }, + { "begin": 7871, "end": 7912, "name": "GT", "source": 1 }, + { "begin": 7868, "end": 7996, "name": "ISZERO", "source": 1 }, + { + "begin": 7868, + "end": 7996, + "name": "PUSH [tag]", + "source": 1, + "value": "419" + }, + { "begin": 7868, "end": 7996, "name": "JUMPI", "source": 1 }, + { + "begin": 7915, + "end": 7994, + "name": "PUSH [tag]", + "source": 1, + "value": "420" + }, + { + "begin": 7915, + "end": 7994, + "name": "PUSH [tag]", + "source": 1, + "value": "307" + }, + { + "begin": 7915, + "end": 7994, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 7915, + "end": 7994, + "name": "tag", + "source": 1, + "value": "420" + }, + { "begin": 7915, "end": 7994, "name": "JUMPDEST", "source": 1 }, + { + "begin": 7868, + "end": 7996, + "name": "tag", + "source": 1, + "value": "419" + }, + { "begin": 7868, "end": 7996, "name": "JUMPDEST", "source": 1 }, + { "begin": 7449, "end": 8002, "name": "SWAP3", "source": 1 }, + { "begin": 7449, "end": 8002, "name": "POP", "source": 1 }, + { "begin": 7449, "end": 8002, "name": "SWAP3", "source": 1 }, + { "begin": 7449, "end": 8002, "name": "SWAP1", "source": 1 }, + { "begin": 7449, "end": 8002, "name": "POP", "source": 1 }, + { + "begin": 7449, + "end": 8002, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 8008, + "end": 8126, + "name": "tag", + "source": 1, + "value": "309" + }, + { "begin": 8008, "end": 8126, "name": "JUMPDEST", "source": 1 }, + { + "begin": 8079, + "end": 8101, + "name": "PUSH [tag]", + "source": 1, + "value": "422" + }, + { "begin": 8095, "end": 8100, "name": "DUP2", "source": 1 }, + { + "begin": 8079, + "end": 8101, + "name": "PUSH [tag]", + "source": 1, + "value": "298" + }, + { + "begin": 8079, + "end": 8101, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 8079, + "end": 8101, + "name": "tag", + "source": 1, + "value": "422" + }, + { "begin": 8079, "end": 8101, "name": "JUMPDEST", "source": 1 }, + { "begin": 8072, "end": 8077, "name": "DUP2", "source": 1 }, + { "begin": 8069, "end": 8102, "name": "EQ", "source": 1 }, + { + "begin": 8059, + "end": 8120, + "name": "PUSH [tag]", + "source": 1, + "value": "423" + }, + { "begin": 8059, "end": 8120, "name": "JUMPI", "source": 1 }, + { + "begin": 8116, + "end": 8117, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 8113, "end": 8114, "name": "DUP1", "source": 1 }, + { "begin": 8106, "end": 8118, "name": "REVERT", "source": 1 }, + { + "begin": 8059, + "end": 8120, + "name": "tag", + "source": 1, + "value": "423" + }, + { "begin": 8059, "end": 8120, "name": "JUMPDEST", "source": 1 }, + { "begin": 8008, "end": 8126, "name": "POP", "source": 1 }, + { + "begin": 8008, + "end": 8126, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 8132, + "end": 8267, + "name": "tag", + "source": 1, + "value": "310" + }, + { "begin": 8132, "end": 8267, "name": "JUMPDEST", "source": 1 }, + { + "begin": 8176, + "end": 8181, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 8214, "end": 8220, "name": "DUP2", "source": 1 }, + { + "begin": 8201, + "end": 8221, + "name": "CALLDATALOAD", + "source": 1 + }, + { "begin": 8192, "end": 8221, "name": "SWAP1", "source": 1 }, + { "begin": 8192, "end": 8221, "name": "POP", "source": 1 }, + { + "begin": 8230, + "end": 8261, + "name": "PUSH [tag]", + "source": 1, + "value": "425" + }, + { "begin": 8255, "end": 8260, "name": "DUP2", "source": 1 }, + { + "begin": 8230, + "end": 8261, + "name": "PUSH [tag]", + "source": 1, + "value": "309" + }, + { + "begin": 8230, + "end": 8261, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 8230, + "end": 8261, + "name": "tag", + "source": 1, + "value": "425" + }, + { "begin": 8230, "end": 8261, "name": "JUMPDEST", "source": 1 }, + { "begin": 8132, "end": 8267, "name": "SWAP3", "source": 1 }, + { "begin": 8132, "end": 8267, "name": "SWAP2", "source": 1 }, + { "begin": 8132, "end": 8267, "name": "POP", "source": 1 }, + { "begin": 8132, "end": 8267, "name": "POP", "source": 1 }, + { + "begin": 8132, + "end": 8267, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 8273, + "end": 9288, + "name": "tag", + "source": 1, + "value": "142" + }, + { "begin": 8273, "end": 9288, "name": "JUMPDEST", "source": 1 }, + { + "begin": 8372, + "end": 8378, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 8380, "end": 8386, "name": "DUP1", "source": 1 }, + { + "begin": 8388, + "end": 8394, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 8396, "end": 8402, "name": "DUP1", "source": 1 }, + { + "begin": 8404, + "end": 8410, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 8453, + "end": 8455, + "name": "PUSH", + "source": 1, + "value": "60" + }, + { "begin": 8441, "end": 8450, "name": "DUP7", "source": 1 }, + { "begin": 8432, "end": 8439, "name": "DUP9", "source": 1 }, + { "begin": 8428, "end": 8451, "name": "SUB", "source": 1 }, + { "begin": 8424, "end": 8456, "name": "SLT", "source": 1 }, + { "begin": 8421, "end": 8540, "name": "ISZERO", "source": 1 }, + { + "begin": 8421, + "end": 8540, + "name": "PUSH [tag]", + "source": 1, + "value": "427" + }, + { "begin": 8421, "end": 8540, "name": "JUMPI", "source": 1 }, + { + "begin": 8459, + "end": 8538, + "name": "PUSH [tag]", + "source": 1, + "value": "428" + }, + { + "begin": 8459, + "end": 8538, + "name": "PUSH [tag]", + "source": 1, + "value": "288" + }, + { + "begin": 8459, + "end": 8538, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 8459, + "end": 8538, + "name": "tag", + "source": 1, + "value": "428" + }, + { "begin": 8459, "end": 8538, "name": "JUMPDEST", "source": 1 }, + { + "begin": 8421, + "end": 8540, + "name": "tag", + "source": 1, + "value": "427" + }, + { "begin": 8421, "end": 8540, "name": "JUMPDEST", "source": 1 }, + { + "begin": 8607, + "end": 8608, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 8596, "end": 8605, "name": "DUP7", "source": 1 }, + { "begin": 8592, "end": 8609, "name": "ADD", "source": 1 }, + { + "begin": 8579, + "end": 8610, + "name": "CALLDATALOAD", + "source": 1 + }, + { + "begin": 8637, + "end": 8655, + "name": "PUSH", + "source": 1, + "value": "FFFFFFFFFFFFFFFF" + }, + { "begin": 8629, "end": 8635, "name": "DUP2", "source": 1 }, + { "begin": 8626, "end": 8656, "name": "GT", "source": 1 }, + { "begin": 8623, "end": 8740, "name": "ISZERO", "source": 1 }, + { + "begin": 8623, + "end": 8740, + "name": "PUSH [tag]", + "source": 1, + "value": "429" + }, + { "begin": 8623, "end": 8740, "name": "JUMPI", "source": 1 }, + { + "begin": 8659, + "end": 8738, + "name": "PUSH [tag]", + "source": 1, + "value": "430" + }, + { + "begin": 8659, + "end": 8738, + "name": "PUSH [tag]", + "source": 1, + "value": "289" + }, + { + "begin": 8659, + "end": 8738, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 8659, + "end": 8738, + "name": "tag", + "source": 1, + "value": "430" + }, + { "begin": 8659, "end": 8738, "name": "JUMPDEST", "source": 1 }, + { + "begin": 8623, + "end": 8740, + "name": "tag", + "source": 1, + "value": "429" + }, + { "begin": 8623, "end": 8740, "name": "JUMPDEST", "source": 1 }, + { + "begin": 8772, + "end": 8837, + "name": "PUSH [tag]", + "source": 1, + "value": "431" + }, + { "begin": 8829, "end": 8836, "name": "DUP9", "source": 1 }, + { "begin": 8820, "end": 8826, "name": "DUP3", "source": 1 }, + { "begin": 8809, "end": 8818, "name": "DUP10", "source": 1 }, + { "begin": 8805, "end": 8827, "name": "ADD", "source": 1 }, + { + "begin": 8772, + "end": 8837, + "name": "PUSH [tag]", + "source": 1, + "value": "308" + }, + { + "begin": 8772, + "end": 8837, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 8772, + "end": 8837, + "name": "tag", + "source": 1, + "value": "431" + }, + { "begin": 8772, "end": 8837, "name": "JUMPDEST", "source": 1 }, + { "begin": 8754, "end": 8837, "name": "SWAP6", "source": 1 }, + { "begin": 8754, "end": 8837, "name": "POP", "source": 1 }, + { "begin": 8754, "end": 8837, "name": "SWAP6", "source": 1 }, + { "begin": 8754, "end": 8837, "name": "POP", "source": 1 }, + { "begin": 8550, "end": 8847, "name": "POP", "source": 1 }, + { + "begin": 8914, + "end": 8916, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 8903, "end": 8912, "name": "DUP7", "source": 1 }, + { "begin": 8899, "end": 8917, "name": "ADD", "source": 1 }, + { + "begin": 8886, + "end": 8918, + "name": "CALLDATALOAD", + "source": 1 + }, + { + "begin": 8945, + "end": 8963, + "name": "PUSH", + "source": 1, + "value": "FFFFFFFFFFFFFFFF" + }, + { "begin": 8937, "end": 8943, "name": "DUP2", "source": 1 }, + { "begin": 8934, "end": 8964, "name": "GT", "source": 1 }, + { "begin": 8931, "end": 9048, "name": "ISZERO", "source": 1 }, + { + "begin": 8931, + "end": 9048, + "name": "PUSH [tag]", + "source": 1, + "value": "432" + }, + { "begin": 8931, "end": 9048, "name": "JUMPI", "source": 1 }, + { + "begin": 8967, + "end": 9046, + "name": "PUSH [tag]", + "source": 1, + "value": "433" + }, + { + "begin": 8967, + "end": 9046, + "name": "PUSH [tag]", + "source": 1, + "value": "289" + }, + { + "begin": 8967, + "end": 9046, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 8967, + "end": 9046, + "name": "tag", + "source": 1, + "value": "433" + }, + { "begin": 8967, "end": 9046, "name": "JUMPDEST", "source": 1 }, + { + "begin": 8931, + "end": 9048, + "name": "tag", + "source": 1, + "value": "432" + }, + { "begin": 8931, "end": 9048, "name": "JUMPDEST", "source": 1 }, + { + "begin": 9080, + "end": 9145, + "name": "PUSH [tag]", + "source": 1, + "value": "434" + }, + { "begin": 9137, "end": 9144, "name": "DUP9", "source": 1 }, + { "begin": 9128, "end": 9134, "name": "DUP3", "source": 1 }, + { "begin": 9117, "end": 9126, "name": "DUP10", "source": 1 }, + { "begin": 9113, "end": 9135, "name": "ADD", "source": 1 }, + { + "begin": 9080, + "end": 9145, + "name": "PUSH [tag]", + "source": 1, + "value": "308" + }, + { + "begin": 9080, + "end": 9145, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 9080, + "end": 9145, + "name": "tag", + "source": 1, + "value": "434" + }, + { "begin": 9080, "end": 9145, "name": "JUMPDEST", "source": 1 }, + { "begin": 9062, "end": 9145, "name": "SWAP4", "source": 1 }, + { "begin": 9062, "end": 9145, "name": "POP", "source": 1 }, + { "begin": 9062, "end": 9145, "name": "SWAP4", "source": 1 }, + { "begin": 9062, "end": 9145, "name": "POP", "source": 1 }, + { "begin": 8857, "end": 9155, "name": "POP", "source": 1 }, + { + "begin": 9194, + "end": 9196, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 9220, + "end": 9271, + "name": "PUSH [tag]", + "source": 1, + "value": "435" + }, + { "begin": 9263, "end": 9270, "name": "DUP9", "source": 1 }, + { "begin": 9254, "end": 9260, "name": "DUP3", "source": 1 }, + { "begin": 9243, "end": 9252, "name": "DUP10", "source": 1 }, + { "begin": 9239, "end": 9261, "name": "ADD", "source": 1 }, + { + "begin": 9220, + "end": 9271, + "name": "PUSH [tag]", + "source": 1, + "value": "310" + }, + { + "begin": 9220, + "end": 9271, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 9220, + "end": 9271, + "name": "tag", + "source": 1, + "value": "435" + }, + { "begin": 9220, "end": 9271, "name": "JUMPDEST", "source": 1 }, + { "begin": 9210, "end": 9271, "name": "SWAP2", "source": 1 }, + { "begin": 9210, "end": 9271, "name": "POP", "source": 1 }, + { "begin": 9165, "end": 9281, "name": "POP", "source": 1 }, + { "begin": 8273, "end": 9288, "name": "SWAP3", "source": 1 }, + { "begin": 8273, "end": 9288, "name": "SWAP6", "source": 1 }, + { "begin": 8273, "end": 9288, "name": "POP", "source": 1 }, + { "begin": 8273, "end": 9288, "name": "SWAP3", "source": 1 }, + { "begin": 8273, "end": 9288, "name": "SWAP6", "source": 1 }, + { "begin": 8273, "end": 9288, "name": "SWAP1", "source": 1 }, + { "begin": 8273, "end": 9288, "name": "SWAP4", "source": 1 }, + { "begin": 8273, "end": 9288, "name": "POP", "source": 1 }, + { + "begin": 8273, + "end": 9288, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 9294, + "end": 9913, + "name": "tag", + "source": 1, + "value": "158" + }, + { "begin": 9294, "end": 9913, "name": "JUMPDEST", "source": 1 }, + { + "begin": 9371, + "end": 9377, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 9379, "end": 9385, "name": "DUP1", "source": 1 }, + { + "begin": 9387, + "end": 9393, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 9436, + "end": 9438, + "name": "PUSH", + "source": 1, + "value": "60" + }, + { "begin": 9424, "end": 9433, "name": "DUP5", "source": 1 }, + { "begin": 9415, "end": 9422, "name": "DUP7", "source": 1 }, + { "begin": 9411, "end": 9434, "name": "SUB", "source": 1 }, + { "begin": 9407, "end": 9439, "name": "SLT", "source": 1 }, + { "begin": 9404, "end": 9523, "name": "ISZERO", "source": 1 }, + { + "begin": 9404, + "end": 9523, + "name": "PUSH [tag]", + "source": 1, + "value": "437" + }, + { "begin": 9404, "end": 9523, "name": "JUMPI", "source": 1 }, + { + "begin": 9442, + "end": 9521, + "name": "PUSH [tag]", + "source": 1, + "value": "438" + }, + { + "begin": 9442, + "end": 9521, + "name": "PUSH [tag]", + "source": 1, + "value": "288" + }, + { + "begin": 9442, + "end": 9521, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 9442, + "end": 9521, + "name": "tag", + "source": 1, + "value": "438" + }, + { "begin": 9442, "end": 9521, "name": "JUMPDEST", "source": 1 }, + { + "begin": 9404, + "end": 9523, + "name": "tag", + "source": 1, + "value": "437" + }, + { "begin": 9404, "end": 9523, "name": "JUMPDEST", "source": 1 }, + { + "begin": 9562, + "end": 9563, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 9587, + "end": 9640, + "name": "PUSH [tag]", + "source": 1, + "value": "439" + }, + { "begin": 9632, "end": 9639, "name": "DUP7", "source": 1 }, + { "begin": 9623, "end": 9629, "name": "DUP3", "source": 1 }, + { "begin": 9612, "end": 9621, "name": "DUP8", "source": 1 }, + { "begin": 9608, "end": 9630, "name": "ADD", "source": 1 }, + { + "begin": 9587, + "end": 9640, + "name": "PUSH [tag]", + "source": 1, + "value": "291" + }, + { + "begin": 9587, + "end": 9640, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 9587, + "end": 9640, + "name": "tag", + "source": 1, + "value": "439" + }, + { "begin": 9587, "end": 9640, "name": "JUMPDEST", "source": 1 }, + { "begin": 9577, "end": 9640, "name": "SWAP4", "source": 1 }, + { "begin": 9577, "end": 9640, "name": "POP", "source": 1 }, + { "begin": 9533, "end": 9650, "name": "POP", "source": 1 }, + { + "begin": 9689, + "end": 9691, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { + "begin": 9715, + "end": 9768, + "name": "PUSH [tag]", + "source": 1, + "value": "440" + }, + { "begin": 9760, "end": 9767, "name": "DUP7", "source": 1 }, + { "begin": 9751, "end": 9757, "name": "DUP3", "source": 1 }, + { "begin": 9740, "end": 9749, "name": "DUP8", "source": 1 }, + { "begin": 9736, "end": 9758, "name": "ADD", "source": 1 }, + { + "begin": 9715, + "end": 9768, + "name": "PUSH [tag]", + "source": 1, + "value": "291" + }, + { + "begin": 9715, + "end": 9768, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 9715, + "end": 9768, + "name": "tag", + "source": 1, + "value": "440" + }, + { "begin": 9715, "end": 9768, "name": "JUMPDEST", "source": 1 }, + { "begin": 9705, "end": 9768, "name": "SWAP3", "source": 1 }, + { "begin": 9705, "end": 9768, "name": "POP", "source": 1 }, + { "begin": 9660, "end": 9778, "name": "POP", "source": 1 }, + { + "begin": 9817, + "end": 9819, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 9843, + "end": 9896, + "name": "PUSH [tag]", + "source": 1, + "value": "441" + }, + { "begin": 9888, "end": 9895, "name": "DUP7", "source": 1 }, + { "begin": 9879, "end": 9885, "name": "DUP3", "source": 1 }, + { "begin": 9868, "end": 9877, "name": "DUP8", "source": 1 }, + { "begin": 9864, "end": 9886, "name": "ADD", "source": 1 }, + { + "begin": 9843, + "end": 9896, + "name": "PUSH [tag]", + "source": 1, + "value": "291" + }, + { + "begin": 9843, + "end": 9896, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 9843, + "end": 9896, + "name": "tag", + "source": 1, + "value": "441" + }, + { "begin": 9843, "end": 9896, "name": "JUMPDEST", "source": 1 }, + { "begin": 9833, "end": 9896, "name": "SWAP2", "source": 1 }, + { "begin": 9833, "end": 9896, "name": "POP", "source": 1 }, + { "begin": 9788, "end": 9906, "name": "POP", "source": 1 }, + { "begin": 9294, "end": 9913, "name": "SWAP3", "source": 1 }, + { "begin": 9294, "end": 9913, "name": "POP", "source": 1 }, + { "begin": 9294, "end": 9913, "name": "SWAP3", "source": 1 }, + { "begin": 9294, "end": 9913, "name": "POP", "source": 1 }, + { "begin": 9294, "end": 9913, "name": "SWAP3", "source": 1 }, + { + "begin": 9294, + "end": 9913, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 9919, + "end": 10036, + "name": "tag", + "source": 1, + "value": "311" + }, + { "begin": 9919, "end": 10036, "name": "JUMPDEST", "source": 1 }, + { + "begin": 10028, + "end": 10029, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 10025, "end": 10026, "name": "DUP1", "source": 1 }, + { "begin": 10018, "end": 10030, "name": "REVERT", "source": 1 }, + { + "begin": 10042, + "end": 10222, + "name": "tag", + "source": 1, + "value": "312" + }, + { "begin": 10042, "end": 10222, "name": "JUMPDEST", "source": 1 }, + { + "begin": 10090, + "end": 10167, + "name": "PUSH", + "source": 1, + "value": "4E487B7100000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 10087, + "end": 10088, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 10080, "end": 10168, "name": "MSTORE", "source": 1 }, + { + "begin": 10187, + "end": 10191, + "name": "PUSH", + "source": 1, + "value": "41" + }, + { + "begin": 10184, + "end": 10185, + "name": "PUSH", + "source": 1, + "value": "4" + }, + { "begin": 10177, "end": 10192, "name": "MSTORE", "source": 1 }, + { + "begin": 10211, + "end": 10215, + "name": "PUSH", + "source": 1, + "value": "24" + }, + { + "begin": 10208, + "end": 10209, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 10201, "end": 10216, "name": "REVERT", "source": 1 }, + { + "begin": 10228, + "end": 10509, + "name": "tag", + "source": 1, + "value": "313" + }, + { "begin": 10228, "end": 10509, "name": "JUMPDEST", "source": 1 }, + { + "begin": 10311, + "end": 10338, + "name": "PUSH [tag]", + "source": 1, + "value": "445" + }, + { "begin": 10333, "end": 10337, "name": "DUP3", "source": 1 }, + { + "begin": 10311, + "end": 10338, + "name": "PUSH [tag]", + "source": 1, + "value": "285" + }, + { + "begin": 10311, + "end": 10338, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 10311, + "end": 10338, + "name": "tag", + "source": 1, + "value": "445" + }, + { "begin": 10311, "end": 10338, "name": "JUMPDEST", "source": 1 }, + { "begin": 10303, "end": 10309, "name": "DUP2", "source": 1 }, + { "begin": 10299, "end": 10339, "name": "ADD", "source": 1 }, + { "begin": 10441, "end": 10447, "name": "DUP2", "source": 1 }, + { "begin": 10429, "end": 10439, "name": "DUP2", "source": 1 }, + { "begin": 10426, "end": 10448, "name": "LT", "source": 1 }, + { + "begin": 10405, + "end": 10423, + "name": "PUSH", + "source": 1, + "value": "FFFFFFFFFFFFFFFF" + }, + { "begin": 10393, "end": 10403, "name": "DUP3", "source": 1 }, + { "begin": 10390, "end": 10424, "name": "GT", "source": 1 }, + { "begin": 10387, "end": 10449, "name": "OR", "source": 1 }, + { "begin": 10384, "end": 10472, "name": "ISZERO", "source": 1 }, + { + "begin": 10384, + "end": 10472, + "name": "PUSH [tag]", + "source": 1, + "value": "446" + }, + { "begin": 10384, "end": 10472, "name": "JUMPI", "source": 1 }, + { + "begin": 10452, + "end": 10470, + "name": "PUSH [tag]", + "source": 1, + "value": "447" + }, + { + "begin": 10452, + "end": 10470, + "name": "PUSH [tag]", + "source": 1, + "value": "312" + }, + { + "begin": 10452, + "end": 10470, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 10452, + "end": 10470, + "name": "tag", + "source": 1, + "value": "447" + }, + { "begin": 10452, "end": 10470, "name": "JUMPDEST", "source": 1 }, + { + "begin": 10384, + "end": 10472, + "name": "tag", + "source": 1, + "value": "446" + }, + { "begin": 10384, "end": 10472, "name": "JUMPDEST", "source": 1 }, + { "begin": 10492, "end": 10502, "name": "DUP1", "source": 1 }, + { + "begin": 10488, + "end": 10490, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { "begin": 10481, "end": 10503, "name": "MSTORE", "source": 1 }, + { "begin": 10271, "end": 10509, "name": "POP", "source": 1 }, + { "begin": 10228, "end": 10509, "name": "POP", "source": 1 }, + { "begin": 10228, "end": 10509, "name": "POP", "source": 1 }, + { + "begin": 10228, + "end": 10509, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 10515, + "end": 10644, + "name": "tag", + "source": 1, + "value": "314" + }, + { "begin": 10515, "end": 10644, "name": "JUMPDEST", "source": 1 }, + { + "begin": 10549, + "end": 10555, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 10576, + "end": 10596, + "name": "PUSH [tag]", + "source": 1, + "value": "449" + }, + { + "begin": 10576, + "end": 10596, + "name": "PUSH [tag]", + "source": 1, + "value": "287" + }, + { + "begin": 10576, + "end": 10596, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 10576, + "end": 10596, + "name": "tag", + "source": 1, + "value": "449" + }, + { "begin": 10576, "end": 10596, "name": "JUMPDEST", "source": 1 }, + { "begin": 10566, "end": 10596, "name": "SWAP1", "source": 1 }, + { "begin": 10566, "end": 10596, "name": "POP", "source": 1 }, + { + "begin": 10605, + "end": 10638, + "name": "PUSH [tag]", + "source": 1, + "value": "450" + }, + { "begin": 10633, "end": 10637, "name": "DUP3", "source": 1 }, + { "begin": 10625, "end": 10631, "name": "DUP3", "source": 1 }, + { + "begin": 10605, + "end": 10638, + "name": "PUSH [tag]", + "source": 1, + "value": "313" + }, + { + "begin": 10605, + "end": 10638, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 10605, + "end": 10638, + "name": "tag", + "source": 1, + "value": "450" + }, + { "begin": 10605, "end": 10638, "name": "JUMPDEST", "source": 1 }, + { "begin": 10515, "end": 10644, "name": "SWAP2", "source": 1 }, + { "begin": 10515, "end": 10644, "name": "SWAP1", "source": 1 }, + { "begin": 10515, "end": 10644, "name": "POP", "source": 1 }, + { + "begin": 10515, + "end": 10644, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 10650, + "end": 10958, + "name": "tag", + "source": 1, + "value": "315" + }, + { "begin": 10650, "end": 10958, "name": "JUMPDEST", "source": 1 }, + { + "begin": 10712, + "end": 10716, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 10802, + "end": 10820, + "name": "PUSH", + "source": 1, + "value": "FFFFFFFFFFFFFFFF" + }, + { "begin": 10794, "end": 10800, "name": "DUP3", "source": 1 }, + { "begin": 10791, "end": 10821, "name": "GT", "source": 1 }, + { "begin": 10788, "end": 10844, "name": "ISZERO", "source": 1 }, + { + "begin": 10788, + "end": 10844, + "name": "PUSH [tag]", + "source": 1, + "value": "452" + }, + { "begin": 10788, "end": 10844, "name": "JUMPI", "source": 1 }, + { + "begin": 10824, + "end": 10842, + "name": "PUSH [tag]", + "source": 1, + "value": "453" + }, + { + "begin": 10824, + "end": 10842, + "name": "PUSH [tag]", + "source": 1, + "value": "312" + }, + { + "begin": 10824, + "end": 10842, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 10824, + "end": 10842, + "name": "tag", + "source": 1, + "value": "453" + }, + { "begin": 10824, "end": 10842, "name": "JUMPDEST", "source": 1 }, + { + "begin": 10788, + "end": 10844, + "name": "tag", + "source": 1, + "value": "452" + }, + { "begin": 10788, "end": 10844, "name": "JUMPDEST", "source": 1 }, + { + "begin": 10862, + "end": 10891, + "name": "PUSH [tag]", + "source": 1, + "value": "454" + }, + { "begin": 10884, "end": 10890, "name": "DUP3", "source": 1 }, + { + "begin": 10862, + "end": 10891, + "name": "PUSH [tag]", + "source": 1, + "value": "285" + }, + { + "begin": 10862, + "end": 10891, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 10862, + "end": 10891, + "name": "tag", + "source": 1, + "value": "454" + }, + { "begin": 10862, "end": 10891, "name": "JUMPDEST", "source": 1 }, + { "begin": 10854, "end": 10891, "name": "SWAP1", "source": 1 }, + { "begin": 10854, "end": 10891, "name": "POP", "source": 1 }, + { + "begin": 10946, + "end": 10950, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 10940, "end": 10944, "name": "DUP2", "source": 1 }, + { "begin": 10936, "end": 10951, "name": "ADD", "source": 1 }, + { "begin": 10928, "end": 10951, "name": "SWAP1", "source": 1 }, + { "begin": 10928, "end": 10951, "name": "POP", "source": 1 }, + { "begin": 10650, "end": 10958, "name": "SWAP2", "source": 1 }, + { "begin": 10650, "end": 10958, "name": "SWAP1", "source": 1 }, + { "begin": 10650, "end": 10958, "name": "POP", "source": 1 }, + { + "begin": 10650, + "end": 10958, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 10964, + "end": 11385, + "name": "tag", + "source": 1, + "value": "316" + }, + { "begin": 10964, "end": 11385, "name": "JUMPDEST", "source": 1 }, + { + "begin": 11053, + "end": 11058, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 11078, + "end": 11144, + "name": "PUSH [tag]", + "source": 1, + "value": "456" + }, + { + "begin": 11094, + "end": 11143, + "name": "PUSH [tag]", + "source": 1, + "value": "457" + }, + { "begin": 11136, "end": 11142, "name": "DUP5", "source": 1 }, + { + "begin": 11094, + "end": 11143, + "name": "PUSH [tag]", + "source": 1, + "value": "315" + }, + { + "begin": 11094, + "end": 11143, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 11094, + "end": 11143, + "name": "tag", + "source": 1, + "value": "457" + }, + { "begin": 11094, "end": 11143, "name": "JUMPDEST", "source": 1 }, + { + "begin": 11078, + "end": 11144, + "name": "PUSH [tag]", + "source": 1, + "value": "314" + }, + { + "begin": 11078, + "end": 11144, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 11078, + "end": 11144, + "name": "tag", + "source": 1, + "value": "456" + }, + { "begin": 11078, "end": 11144, "name": "JUMPDEST", "source": 1 }, + { "begin": 11069, "end": 11144, "name": "SWAP1", "source": 1 }, + { "begin": 11069, "end": 11144, "name": "POP", "source": 1 }, + { "begin": 11167, "end": 11173, "name": "DUP3", "source": 1 }, + { "begin": 11160, "end": 11165, "name": "DUP2", "source": 1 }, + { "begin": 11153, "end": 11174, "name": "MSTORE", "source": 1 }, + { + "begin": 11205, + "end": 11209, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 11198, "end": 11203, "name": "DUP2", "source": 1 }, + { "begin": 11194, "end": 11210, "name": "ADD", "source": 1 }, + { "begin": 11243, "end": 11246, "name": "DUP5", "source": 1 }, + { "begin": 11234, "end": 11240, "name": "DUP5", "source": 1 }, + { "begin": 11229, "end": 11232, "name": "DUP5", "source": 1 }, + { "begin": 11225, "end": 11241, "name": "ADD", "source": 1 }, + { "begin": 11222, "end": 11247, "name": "GT", "source": 1 }, + { "begin": 11219, "end": 11331, "name": "ISZERO", "source": 1 }, + { + "begin": 11219, + "end": 11331, + "name": "PUSH [tag]", + "source": 1, + "value": "458" + }, + { "begin": 11219, "end": 11331, "name": "JUMPI", "source": 1 }, + { + "begin": 11250, + "end": 11329, + "name": "PUSH [tag]", + "source": 1, + "value": "459" + }, + { + "begin": 11250, + "end": 11329, + "name": "PUSH [tag]", + "source": 1, + "value": "311" + }, + { + "begin": 11250, + "end": 11329, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 11250, + "end": 11329, + "name": "tag", + "source": 1, + "value": "459" + }, + { "begin": 11250, "end": 11329, "name": "JUMPDEST", "source": 1 }, + { + "begin": 11219, + "end": 11331, + "name": "tag", + "source": 1, + "value": "458" + }, + { "begin": 11219, "end": 11331, "name": "JUMPDEST", "source": 1 }, + { + "begin": 11340, + "end": 11379, + "name": "PUSH [tag]", + "source": 1, + "value": "460" + }, + { "begin": 11372, "end": 11378, "name": "DUP5", "source": 1 }, + { "begin": 11367, "end": 11370, "name": "DUP3", "source": 1 }, + { "begin": 11362, "end": 11365, "name": "DUP6", "source": 1 }, + { + "begin": 11340, + "end": 11379, + "name": "PUSH [tag]", + "source": 1, + "value": "284" + }, + { + "begin": 11340, + "end": 11379, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 11340, + "end": 11379, + "name": "tag", + "source": 1, + "value": "460" + }, + { "begin": 11340, "end": 11379, "name": "JUMPDEST", "source": 1 }, + { "begin": 11059, "end": 11385, "name": "POP", "source": 1 }, + { "begin": 10964, "end": 11385, "name": "SWAP4", "source": 1 }, + { "begin": 10964, "end": 11385, "name": "SWAP3", "source": 1 }, + { "begin": 10964, "end": 11385, "name": "POP", "source": 1 }, + { "begin": 10964, "end": 11385, "name": "POP", "source": 1 }, + { "begin": 10964, "end": 11385, "name": "POP", "source": 1 }, + { + "begin": 10964, + "end": 11385, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 11405, + "end": 11760, + "name": "tag", + "source": 1, + "value": "317" + }, + { "begin": 11405, "end": 11760, "name": "JUMPDEST", "source": 1 }, + { + "begin": 11472, + "end": 11477, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 11521, "end": 11524, "name": "DUP3", "source": 1 }, + { + "begin": 11514, + "end": 11518, + "name": "PUSH", + "source": 1, + "value": "1F" + }, + { "begin": 11506, "end": 11512, "name": "DUP4", "source": 1 }, + { "begin": 11502, "end": 11519, "name": "ADD", "source": 1 }, + { "begin": 11498, "end": 11525, "name": "SLT", "source": 1 }, + { + "begin": 11488, + "end": 11610, + "name": "PUSH [tag]", + "source": 1, + "value": "462" + }, + { "begin": 11488, "end": 11610, "name": "JUMPI", "source": 1 }, + { + "begin": 11529, + "end": 11608, + "name": "PUSH [tag]", + "source": 1, + "value": "463" + }, + { + "begin": 11529, + "end": 11608, + "name": "PUSH [tag]", + "source": 1, + "value": "305" + }, + { + "begin": 11529, + "end": 11608, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 11529, + "end": 11608, + "name": "tag", + "source": 1, + "value": "463" + }, + { "begin": 11529, "end": 11608, "name": "JUMPDEST", "source": 1 }, + { + "begin": 11488, + "end": 11610, + "name": "tag", + "source": 1, + "value": "462" + }, + { "begin": 11488, "end": 11610, "name": "JUMPDEST", "source": 1 }, + { "begin": 11639, "end": 11645, "name": "DUP2", "source": 1 }, + { "begin": 11633, "end": 11646, "name": "MLOAD", "source": 1 }, + { + "begin": 11664, + "end": 11754, + "name": "PUSH [tag]", + "source": 1, + "value": "464" + }, + { "begin": 11750, "end": 11753, "name": "DUP5", "source": 1 }, + { "begin": 11742, "end": 11748, "name": "DUP3", "source": 1 }, + { + "begin": 11735, + "end": 11739, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 11727, "end": 11733, "name": "DUP7", "source": 1 }, + { "begin": 11723, "end": 11740, "name": "ADD", "source": 1 }, + { + "begin": 11664, + "end": 11754, + "name": "PUSH [tag]", + "source": 1, + "value": "316" + }, + { + "begin": 11664, + "end": 11754, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 11664, + "end": 11754, + "name": "tag", + "source": 1, + "value": "464" + }, + { "begin": 11664, "end": 11754, "name": "JUMPDEST", "source": 1 }, + { "begin": 11655, "end": 11754, "name": "SWAP2", "source": 1 }, + { "begin": 11655, "end": 11754, "name": "POP", "source": 1 }, + { "begin": 11478, "end": 11760, "name": "POP", "source": 1 }, + { "begin": 11405, "end": 11760, "name": "SWAP3", "source": 1 }, + { "begin": 11405, "end": 11760, "name": "SWAP2", "source": 1 }, + { "begin": 11405, "end": 11760, "name": "POP", "source": 1 }, + { "begin": 11405, "end": 11760, "name": "POP", "source": 1 }, + { + "begin": 11405, + "end": 11760, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 11766, + "end": 12290, + "name": "tag", + "source": 1, + "value": "166" + }, + { "begin": 11766, "end": 12290, "name": "JUMPDEST", "source": 1 }, + { + "begin": 11846, + "end": 11852, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 11895, + "end": 11897, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 11883, "end": 11892, "name": "DUP3", "source": 1 }, + { "begin": 11874, "end": 11881, "name": "DUP5", "source": 1 }, + { "begin": 11870, "end": 11893, "name": "SUB", "source": 1 }, + { "begin": 11866, "end": 11898, "name": "SLT", "source": 1 }, + { "begin": 11863, "end": 11982, "name": "ISZERO", "source": 1 }, + { + "begin": 11863, + "end": 11982, + "name": "PUSH [tag]", + "source": 1, + "value": "466" + }, + { "begin": 11863, "end": 11982, "name": "JUMPI", "source": 1 }, + { + "begin": 11901, + "end": 11980, + "name": "PUSH [tag]", + "source": 1, + "value": "467" + }, + { + "begin": 11901, + "end": 11980, + "name": "PUSH [tag]", + "source": 1, + "value": "288" + }, + { + "begin": 11901, + "end": 11980, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 11901, + "end": 11980, + "name": "tag", + "source": 1, + "value": "467" + }, + { "begin": 11901, "end": 11980, "name": "JUMPDEST", "source": 1 }, + { + "begin": 11863, + "end": 11982, + "name": "tag", + "source": 1, + "value": "466" + }, + { "begin": 11863, "end": 11982, "name": "JUMPDEST", "source": 1 }, + { + "begin": 12042, + "end": 12043, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 12031, "end": 12040, "name": "DUP3", "source": 1 }, + { "begin": 12027, "end": 12044, "name": "ADD", "source": 1 }, + { "begin": 12021, "end": 12045, "name": "MLOAD", "source": 1 }, + { + "begin": 12072, + "end": 12090, + "name": "PUSH", + "source": 1, + "value": "FFFFFFFFFFFFFFFF" + }, + { "begin": 12064, "end": 12070, "name": "DUP2", "source": 1 }, + { "begin": 12061, "end": 12091, "name": "GT", "source": 1 }, + { "begin": 12058, "end": 12175, "name": "ISZERO", "source": 1 }, + { + "begin": 12058, + "end": 12175, + "name": "PUSH [tag]", + "source": 1, + "value": "468" + }, + { "begin": 12058, "end": 12175, "name": "JUMPI", "source": 1 }, + { + "begin": 12094, + "end": 12173, + "name": "PUSH [tag]", + "source": 1, + "value": "469" + }, + { + "begin": 12094, + "end": 12173, + "name": "PUSH [tag]", + "source": 1, + "value": "289" + }, + { + "begin": 12094, + "end": 12173, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 12094, + "end": 12173, + "name": "tag", + "source": 1, + "value": "469" + }, + { "begin": 12094, "end": 12173, "name": "JUMPDEST", "source": 1 }, + { + "begin": 12058, + "end": 12175, + "name": "tag", + "source": 1, + "value": "468" + }, + { "begin": 12058, "end": 12175, "name": "JUMPDEST", "source": 1 }, + { + "begin": 12199, + "end": 12273, + "name": "PUSH [tag]", + "source": 1, + "value": "470" + }, + { "begin": 12265, "end": 12272, "name": "DUP5", "source": 1 }, + { "begin": 12256, "end": 12262, "name": "DUP3", "source": 1 }, + { "begin": 12245, "end": 12254, "name": "DUP6", "source": 1 }, + { "begin": 12241, "end": 12263, "name": "ADD", "source": 1 }, + { + "begin": 12199, + "end": 12273, + "name": "PUSH [tag]", + "source": 1, + "value": "317" + }, + { + "begin": 12199, + "end": 12273, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 12199, + "end": 12273, + "name": "tag", + "source": 1, + "value": "470" + }, + { "begin": 12199, "end": 12273, "name": "JUMPDEST", "source": 1 }, + { "begin": 12189, "end": 12273, "name": "SWAP2", "source": 1 }, + { "begin": 12189, "end": 12273, "name": "POP", "source": 1 }, + { "begin": 11992, "end": 12283, "name": "POP", "source": 1 }, + { "begin": 11766, "end": 12290, "name": "SWAP3", "source": 1 }, + { "begin": 11766, "end": 12290, "name": "SWAP2", "source": 1 }, + { "begin": 11766, "end": 12290, "name": "POP", "source": 1 }, + { "begin": 11766, "end": 12290, "name": "POP", "source": 1 }, + { + "begin": 11766, + "end": 12290, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 12296, + "end": 12628, + "name": "tag", + "source": 1, + "value": "169" + }, + { "begin": 12296, "end": 12628, "name": "JUMPDEST", "source": 1 }, + { + "begin": 12417, + "end": 12421, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 12455, + "end": 12457, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { "begin": 12444, "end": 12453, "name": "DUP3", "source": 1 }, + { "begin": 12440, "end": 12458, "name": "ADD", "source": 1 }, + { "begin": 12432, "end": 12458, "name": "SWAP1", "source": 1 }, + { "begin": 12432, "end": 12458, "name": "POP", "source": 1 }, + { + "begin": 12468, + "end": 12539, + "name": "PUSH [tag]", + "source": 1, + "value": "472" + }, + { + "begin": 12536, + "end": 12537, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 12525, "end": 12534, "name": "DUP4", "source": 1 }, + { "begin": 12521, "end": 12538, "name": "ADD", "source": 1 }, + { "begin": 12512, "end": 12518, "name": "DUP6", "source": 1 }, + { + "begin": 12468, + "end": 12539, + "name": "PUSH [tag]", + "source": 1, + "value": "281" + }, + { + "begin": 12468, + "end": 12539, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 12468, + "end": 12539, + "name": "tag", + "source": 1, + "value": "472" + }, + { "begin": 12468, "end": 12539, "name": "JUMPDEST", "source": 1 }, + { + "begin": 12549, + "end": 12621, + "name": "PUSH [tag]", + "source": 1, + "value": "473" + }, + { + "begin": 12617, + "end": 12619, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 12606, "end": 12615, "name": "DUP4", "source": 1 }, + { "begin": 12602, "end": 12620, "name": "ADD", "source": 1 }, + { "begin": 12593, "end": 12599, "name": "DUP5", "source": 1 }, + { + "begin": 12549, + "end": 12621, + "name": "PUSH [tag]", + "source": 1, + "value": "297" + }, + { + "begin": 12549, + "end": 12621, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 12549, + "end": 12621, + "name": "tag", + "source": 1, + "value": "473" + }, + { "begin": 12549, "end": 12621, "name": "JUMPDEST", "source": 1 }, + { "begin": 12296, "end": 12628, "name": "SWAP4", "source": 1 }, + { "begin": 12296, "end": 12628, "name": "SWAP3", "source": 1 }, + { "begin": 12296, "end": 12628, "name": "POP", "source": 1 }, + { "begin": 12296, "end": 12628, "name": "POP", "source": 1 }, + { "begin": 12296, "end": 12628, "name": "POP", "source": 1 }, + { + "begin": 12296, + "end": 12628, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 12634, + "end": 12750, + "name": "tag", + "source": 1, + "value": "318" + }, + { "begin": 12634, "end": 12750, "name": "JUMPDEST", "source": 1 }, + { + "begin": 12704, + "end": 12725, + "name": "PUSH [tag]", + "source": 1, + "value": "475" + }, + { "begin": 12719, "end": 12724, "name": "DUP2", "source": 1 }, + { + "begin": 12704, + "end": 12725, + "name": "PUSH [tag]", + "source": 1, + "value": "295" + }, + { + "begin": 12704, + "end": 12725, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 12704, + "end": 12725, + "name": "tag", + "source": 1, + "value": "475" + }, + { "begin": 12704, "end": 12725, "name": "JUMPDEST", "source": 1 }, + { "begin": 12697, "end": 12702, "name": "DUP2", "source": 1 }, + { "begin": 12694, "end": 12726, "name": "EQ", "source": 1 }, + { + "begin": 12684, + "end": 12744, + "name": "PUSH [tag]", + "source": 1, + "value": "476" + }, + { "begin": 12684, "end": 12744, "name": "JUMPI", "source": 1 }, + { + "begin": 12740, + "end": 12741, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 12737, "end": 12738, "name": "DUP1", "source": 1 }, + { "begin": 12730, "end": 12742, "name": "REVERT", "source": 1 }, + { + "begin": 12684, + "end": 12744, + "name": "tag", + "source": 1, + "value": "476" + }, + { "begin": 12684, "end": 12744, "name": "JUMPDEST", "source": 1 }, + { "begin": 12634, "end": 12750, "name": "POP", "source": 1 }, + { + "begin": 12634, + "end": 12750, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 12756, + "end": 12893, + "name": "tag", + "source": 1, + "value": "319" + }, + { "begin": 12756, "end": 12893, "name": "JUMPDEST", "source": 1 }, + { + "begin": 12810, + "end": 12815, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 12841, "end": 12847, "name": "DUP2", "source": 1 }, + { "begin": 12835, "end": 12848, "name": "MLOAD", "source": 1 }, + { "begin": 12826, "end": 12848, "name": "SWAP1", "source": 1 }, + { "begin": 12826, "end": 12848, "name": "POP", "source": 1 }, + { + "begin": 12857, + "end": 12887, + "name": "PUSH [tag]", + "source": 1, + "value": "478" + }, + { "begin": 12881, "end": 12886, "name": "DUP2", "source": 1 }, + { + "begin": 12857, + "end": 12887, + "name": "PUSH [tag]", + "source": 1, + "value": "318" + }, + { + "begin": 12857, + "end": 12887, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 12857, + "end": 12887, + "name": "tag", + "source": 1, + "value": "478" + }, + { "begin": 12857, "end": 12887, "name": "JUMPDEST", "source": 1 }, + { "begin": 12756, "end": 12893, "name": "SWAP3", "source": 1 }, + { "begin": 12756, "end": 12893, "name": "SWAP2", "source": 1 }, + { "begin": 12756, "end": 12893, "name": "POP", "source": 1 }, + { "begin": 12756, "end": 12893, "name": "POP", "source": 1 }, + { + "begin": 12756, + "end": 12893, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 12899, + "end": 13244, + "name": "tag", + "source": 1, + "value": "173" + }, + { "begin": 12899, "end": 13244, "name": "JUMPDEST", "source": 1 }, + { + "begin": 12966, + "end": 12972, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 13015, + "end": 13017, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 13003, "end": 13012, "name": "DUP3", "source": 1 }, + { "begin": 12994, "end": 13001, "name": "DUP5", "source": 1 }, + { "begin": 12990, "end": 13013, "name": "SUB", "source": 1 }, + { "begin": 12986, "end": 13018, "name": "SLT", "source": 1 }, + { "begin": 12983, "end": 13102, "name": "ISZERO", "source": 1 }, + { + "begin": 12983, + "end": 13102, + "name": "PUSH [tag]", + "source": 1, + "value": "480" + }, + { "begin": 12983, "end": 13102, "name": "JUMPI", "source": 1 }, + { + "begin": 13021, + "end": 13100, + "name": "PUSH [tag]", + "source": 1, + "value": "481" + }, + { + "begin": 13021, + "end": 13100, + "name": "PUSH [tag]", + "source": 1, + "value": "288" + }, + { + "begin": 13021, + "end": 13100, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 13021, + "end": 13100, + "name": "tag", + "source": 1, + "value": "481" + }, + { "begin": 13021, "end": 13100, "name": "JUMPDEST", "source": 1 }, + { + "begin": 12983, + "end": 13102, + "name": "tag", + "source": 1, + "value": "480" + }, + { "begin": 12983, "end": 13102, "name": "JUMPDEST", "source": 1 }, + { + "begin": 13141, + "end": 13142, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 13166, + "end": 13227, + "name": "PUSH [tag]", + "source": 1, + "value": "482" + }, + { "begin": 13219, "end": 13226, "name": "DUP5", "source": 1 }, + { "begin": 13210, "end": 13216, "name": "DUP3", "source": 1 }, + { "begin": 13199, "end": 13208, "name": "DUP6", "source": 1 }, + { "begin": 13195, "end": 13217, "name": "ADD", "source": 1 }, + { + "begin": 13166, + "end": 13227, + "name": "PUSH [tag]", + "source": 1, + "value": "319" + }, + { + "begin": 13166, + "end": 13227, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 13166, + "end": 13227, + "name": "tag", + "source": 1, + "value": "482" + }, + { "begin": 13166, "end": 13227, "name": "JUMPDEST", "source": 1 }, + { "begin": 13156, "end": 13227, "name": "SWAP2", "source": 1 }, + { "begin": 13156, "end": 13227, "name": "POP", "source": 1 }, + { "begin": 13112, "end": 13237, "name": "POP", "source": 1 }, + { "begin": 12899, "end": 13244, "name": "SWAP3", "source": 1 }, + { "begin": 12899, "end": 13244, "name": "SWAP2", "source": 1 }, + { "begin": 12899, "end": 13244, "name": "POP", "source": 1 }, + { "begin": 12899, "end": 13244, "name": "POP", "source": 1 }, + { + "begin": 12899, + "end": 13244, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 13250, + "end": 13393, + "name": "tag", + "source": 1, + "value": "320" + }, + { "begin": 13250, "end": 13393, "name": "JUMPDEST", "source": 1 }, + { + "begin": 13307, + "end": 13312, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 13338, "end": 13344, "name": "DUP2", "source": 1 }, + { "begin": 13332, "end": 13345, "name": "MLOAD", "source": 1 }, + { "begin": 13323, "end": 13345, "name": "SWAP1", "source": 1 }, + { "begin": 13323, "end": 13345, "name": "POP", "source": 1 }, + { + "begin": 13354, + "end": 13387, + "name": "PUSH [tag]", + "source": 1, + "value": "484" + }, + { "begin": 13381, "end": 13386, "name": "DUP2", "source": 1 }, + { + "begin": 13354, + "end": 13387, + "name": "PUSH [tag]", + "source": 1, + "value": "293" + }, + { + "begin": 13354, + "end": 13387, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 13354, + "end": 13387, + "name": "tag", + "source": 1, + "value": "484" + }, + { "begin": 13354, "end": 13387, "name": "JUMPDEST", "source": 1 }, + { "begin": 13250, "end": 13393, "name": "SWAP3", "source": 1 }, + { "begin": 13250, "end": 13393, "name": "SWAP2", "source": 1 }, + { "begin": 13250, "end": 13393, "name": "POP", "source": 1 }, + { "begin": 13250, "end": 13393, "name": "POP", "source": 1 }, + { + "begin": 13250, + "end": 13393, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 13399, + "end": 13750, + "name": "tag", + "source": 1, + "value": "178" + }, + { "begin": 13399, "end": 13750, "name": "JUMPDEST", "source": 1 }, + { + "begin": 13469, + "end": 13475, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 13518, + "end": 13520, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 13506, "end": 13515, "name": "DUP3", "source": 1 }, + { "begin": 13497, "end": 13504, "name": "DUP5", "source": 1 }, + { "begin": 13493, "end": 13516, "name": "SUB", "source": 1 }, + { "begin": 13489, "end": 13521, "name": "SLT", "source": 1 }, + { "begin": 13486, "end": 13605, "name": "ISZERO", "source": 1 }, + { + "begin": 13486, + "end": 13605, + "name": "PUSH [tag]", + "source": 1, + "value": "486" + }, + { "begin": 13486, "end": 13605, "name": "JUMPI", "source": 1 }, + { + "begin": 13524, + "end": 13603, + "name": "PUSH [tag]", + "source": 1, + "value": "487" + }, + { + "begin": 13524, + "end": 13603, + "name": "PUSH [tag]", + "source": 1, + "value": "288" + }, + { + "begin": 13524, + "end": 13603, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 13524, + "end": 13603, + "name": "tag", + "source": 1, + "value": "487" + }, + { "begin": 13524, "end": 13603, "name": "JUMPDEST", "source": 1 }, + { + "begin": 13486, + "end": 13605, + "name": "tag", + "source": 1, + "value": "486" + }, + { "begin": 13486, "end": 13605, "name": "JUMPDEST", "source": 1 }, + { + "begin": 13644, + "end": 13645, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 13669, + "end": 13733, + "name": "PUSH [tag]", + "source": 1, + "value": "488" + }, + { "begin": 13725, "end": 13732, "name": "DUP5", "source": 1 }, + { "begin": 13716, "end": 13722, "name": "DUP3", "source": 1 }, + { "begin": 13705, "end": 13714, "name": "DUP6", "source": 1 }, + { "begin": 13701, "end": 13723, "name": "ADD", "source": 1 }, + { + "begin": 13669, + "end": 13733, + "name": "PUSH [tag]", + "source": 1, + "value": "320" + }, + { + "begin": 13669, + "end": 13733, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 13669, + "end": 13733, + "name": "tag", + "source": 1, + "value": "488" + }, + { "begin": 13669, "end": 13733, "name": "JUMPDEST", "source": 1 }, + { "begin": 13659, "end": 13733, "name": "SWAP2", "source": 1 }, + { "begin": 13659, "end": 13733, "name": "POP", "source": 1 }, + { "begin": 13615, "end": 13743, "name": "POP", "source": 1 }, + { "begin": 13399, "end": 13750, "name": "SWAP3", "source": 1 }, + { "begin": 13399, "end": 13750, "name": "SWAP2", "source": 1 }, + { "begin": 13399, "end": 13750, "name": "POP", "source": 1 }, + { "begin": 13399, "end": 13750, "name": "POP", "source": 1 }, + { + "begin": 13399, + "end": 13750, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 13756, + "end": 14198, + "name": "tag", + "source": 1, + "value": "185" + }, + { "begin": 13756, "end": 14198, "name": "JUMPDEST", "source": 1 }, + { + "begin": 13905, + "end": 13909, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 13943, + "end": 13945, + "name": "PUSH", + "source": 1, + "value": "60" + }, + { "begin": 13932, "end": 13941, "name": "DUP3", "source": 1 }, + { "begin": 13928, "end": 13946, "name": "ADD", "source": 1 }, + { "begin": 13920, "end": 13946, "name": "SWAP1", "source": 1 }, + { "begin": 13920, "end": 13946, "name": "POP", "source": 1 }, + { + "begin": 13956, + "end": 14027, + "name": "PUSH [tag]", + "source": 1, + "value": "490" + }, + { + "begin": 14024, + "end": 14025, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 14013, "end": 14022, "name": "DUP4", "source": 1 }, + { "begin": 14009, "end": 14026, "name": "ADD", "source": 1 }, + { "begin": 14000, "end": 14006, "name": "DUP7", "source": 1 }, + { + "begin": 13956, + "end": 14027, + "name": "PUSH [tag]", + "source": 1, + "value": "281" + }, + { + "begin": 13956, + "end": 14027, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 13956, + "end": 14027, + "name": "tag", + "source": 1, + "value": "490" + }, + { "begin": 13956, "end": 14027, "name": "JUMPDEST", "source": 1 }, + { + "begin": 14037, + "end": 14109, + "name": "PUSH [tag]", + "source": 1, + "value": "491" + }, + { + "begin": 14105, + "end": 14107, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 14094, "end": 14103, "name": "DUP4", "source": 1 }, + { "begin": 14090, "end": 14108, "name": "ADD", "source": 1 }, + { "begin": 14081, "end": 14087, "name": "DUP6", "source": 1 }, + { + "begin": 14037, + "end": 14109, + "name": "PUSH [tag]", + "source": 1, + "value": "281" + }, + { + "begin": 14037, + "end": 14109, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 14037, + "end": 14109, + "name": "tag", + "source": 1, + "value": "491" + }, + { "begin": 14037, "end": 14109, "name": "JUMPDEST", "source": 1 }, + { + "begin": 14119, + "end": 14191, + "name": "PUSH [tag]", + "source": 1, + "value": "492" + }, + { + "begin": 14187, + "end": 14189, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { "begin": 14176, "end": 14185, "name": "DUP4", "source": 1 }, + { "begin": 14172, "end": 14190, "name": "ADD", "source": 1 }, + { "begin": 14163, "end": 14169, "name": "DUP5", "source": 1 }, + { + "begin": 14119, + "end": 14191, + "name": "PUSH [tag]", + "source": 1, + "value": "297" + }, + { + "begin": 14119, + "end": 14191, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 14119, + "end": 14191, + "name": "tag", + "source": 1, + "value": "492" + }, + { "begin": 14119, "end": 14191, "name": "JUMPDEST", "source": 1 }, + { "begin": 13756, "end": 14198, "name": "SWAP5", "source": 1 }, + { "begin": 13756, "end": 14198, "name": "SWAP4", "source": 1 }, + { "begin": 13756, "end": 14198, "name": "POP", "source": 1 }, + { "begin": 13756, "end": 14198, "name": "POP", "source": 1 }, + { "begin": 13756, "end": 14198, "name": "POP", "source": 1 }, + { "begin": 13756, "end": 14198, "name": "POP", "source": 1 }, + { + "begin": 13756, + "end": 14198, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 14204, + "end": 14343, + "name": "tag", + "source": 1, + "value": "321" + }, + { "begin": 14204, "end": 14343, "name": "JUMPDEST", "source": 1 }, + { + "begin": 14259, + "end": 14264, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 14290, "end": 14296, "name": "DUP2", "source": 1 }, + { "begin": 14284, "end": 14297, "name": "MLOAD", "source": 1 }, + { "begin": 14275, "end": 14297, "name": "SWAP1", "source": 1 }, + { "begin": 14275, "end": 14297, "name": "POP", "source": 1 }, + { + "begin": 14306, + "end": 14337, + "name": "PUSH [tag]", + "source": 1, + "value": "494" + }, + { "begin": 14331, "end": 14336, "name": "DUP2", "source": 1 }, + { + "begin": 14306, + "end": 14337, + "name": "PUSH [tag]", + "source": 1, + "value": "309" + }, + { + "begin": 14306, + "end": 14337, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 14306, + "end": 14337, + "name": "tag", + "source": 1, + "value": "494" + }, + { "begin": 14306, "end": 14337, "name": "JUMPDEST", "source": 1 }, + { "begin": 14204, "end": 14343, "name": "SWAP3", "source": 1 }, + { "begin": 14204, "end": 14343, "name": "SWAP2", "source": 1 }, + { "begin": 14204, "end": 14343, "name": "POP", "source": 1 }, + { "begin": 14204, "end": 14343, "name": "POP", "source": 1 }, + { + "begin": 14204, + "end": 14343, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 14349, + "end": 14696, + "name": "tag", + "source": 1, + "value": "193" + }, + { "begin": 14349, "end": 14696, "name": "JUMPDEST", "source": 1 }, + { + "begin": 14417, + "end": 14423, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 14466, + "end": 14468, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 14454, "end": 14463, "name": "DUP3", "source": 1 }, + { "begin": 14445, "end": 14452, "name": "DUP5", "source": 1 }, + { "begin": 14441, "end": 14464, "name": "SUB", "source": 1 }, + { "begin": 14437, "end": 14469, "name": "SLT", "source": 1 }, + { "begin": 14434, "end": 14553, "name": "ISZERO", "source": 1 }, + { + "begin": 14434, + "end": 14553, + "name": "PUSH [tag]", + "source": 1, + "value": "496" + }, + { "begin": 14434, "end": 14553, "name": "JUMPI", "source": 1 }, + { + "begin": 14472, + "end": 14551, + "name": "PUSH [tag]", + "source": 1, + "value": "497" + }, + { + "begin": 14472, + "end": 14551, + "name": "PUSH [tag]", + "source": 1, + "value": "288" + }, + { + "begin": 14472, + "end": 14551, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 14472, + "end": 14551, + "name": "tag", + "source": 1, + "value": "497" + }, + { "begin": 14472, "end": 14551, "name": "JUMPDEST", "source": 1 }, + { + "begin": 14434, + "end": 14553, + "name": "tag", + "source": 1, + "value": "496" + }, + { "begin": 14434, "end": 14553, "name": "JUMPDEST", "source": 1 }, + { + "begin": 14592, + "end": 14593, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 14617, + "end": 14679, + "name": "PUSH [tag]", + "source": 1, + "value": "498" + }, + { "begin": 14671, "end": 14678, "name": "DUP5", "source": 1 }, + { "begin": 14662, "end": 14668, "name": "DUP3", "source": 1 }, + { "begin": 14651, "end": 14660, "name": "DUP6", "source": 1 }, + { "begin": 14647, "end": 14669, "name": "ADD", "source": 1 }, + { + "begin": 14617, + "end": 14679, + "name": "PUSH [tag]", + "source": 1, + "value": "321" + }, + { + "begin": 14617, + "end": 14679, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 14617, + "end": 14679, + "name": "tag", + "source": 1, + "value": "498" + }, + { "begin": 14617, "end": 14679, "name": "JUMPDEST", "source": 1 }, + { "begin": 14607, "end": 14679, "name": "SWAP2", "source": 1 }, + { "begin": 14607, "end": 14679, "name": "POP", "source": 1 }, + { "begin": 14563, "end": 14689, "name": "POP", "source": 1 }, + { "begin": 14349, "end": 14696, "name": "SWAP3", "source": 1 }, + { "begin": 14349, "end": 14696, "name": "SWAP2", "source": 1 }, + { "begin": 14349, "end": 14696, "name": "POP", "source": 1 }, + { "begin": 14349, "end": 14696, "name": "POP", "source": 1 }, + { + "begin": 14349, + "end": 14696, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 14702, + "end": 14800, + "name": "tag", + "source": 1, + "value": "322" + }, + { "begin": 14702, "end": 14800, "name": "JUMPDEST", "source": 1 }, + { + "begin": 14753, + "end": 14759, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 14787, "end": 14792, "name": "DUP2", "source": 1 }, + { "begin": 14781, "end": 14793, "name": "MLOAD", "source": 1 }, + { "begin": 14771, "end": 14793, "name": "SWAP1", "source": 1 }, + { "begin": 14771, "end": 14793, "name": "POP", "source": 1 }, + { "begin": 14702, "end": 14800, "name": "SWAP2", "source": 1 }, + { "begin": 14702, "end": 14800, "name": "SWAP1", "source": 1 }, + { "begin": 14702, "end": 14800, "name": "POP", "source": 1 }, + { + "begin": 14702, + "end": 14800, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 14806, + "end": 14953, + "name": "tag", + "source": 1, + "value": "323" + }, + { "begin": 14806, "end": 14953, "name": "JUMPDEST", "source": 1 }, + { + "begin": 14907, + "end": 14918, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 14944, "end": 14947, "name": "DUP2", "source": 1 }, + { "begin": 14929, "end": 14947, "name": "SWAP1", "source": 1 }, + { "begin": 14929, "end": 14947, "name": "POP", "source": 1 }, + { "begin": 14806, "end": 14953, "name": "SWAP3", "source": 1 }, + { "begin": 14806, "end": 14953, "name": "SWAP2", "source": 1 }, + { "begin": 14806, "end": 14953, "name": "POP", "source": 1 }, + { "begin": 14806, "end": 14953, "name": "POP", "source": 1 }, + { + "begin": 14806, + "end": 14953, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 14959, + "end": 15332, + "name": "tag", + "source": 1, + "value": "324" + }, + { "begin": 14959, "end": 15332, "name": "JUMPDEST", "source": 1 }, + { + "begin": 15063, + "end": 15066, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 15091, + "end": 15129, + "name": "PUSH [tag]", + "source": 1, + "value": "502" + }, + { "begin": 15123, "end": 15128, "name": "DUP3", "source": 1 }, + { + "begin": 15091, + "end": 15129, + "name": "PUSH [tag]", + "source": 1, + "value": "322" + }, + { + "begin": 15091, + "end": 15129, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 15091, + "end": 15129, + "name": "tag", + "source": 1, + "value": "502" + }, + { "begin": 15091, "end": 15129, "name": "JUMPDEST", "source": 1 }, + { + "begin": 15145, + "end": 15233, + "name": "PUSH [tag]", + "source": 1, + "value": "503" + }, + { "begin": 15226, "end": 15232, "name": "DUP2", "source": 1 }, + { "begin": 15221, "end": 15224, "name": "DUP6", "source": 1 }, + { + "begin": 15145, + "end": 15233, + "name": "PUSH [tag]", + "source": 1, + "value": "323" + }, + { + "begin": 15145, + "end": 15233, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 15145, + "end": 15233, + "name": "tag", + "source": 1, + "value": "503" + }, + { "begin": 15145, "end": 15233, "name": "JUMPDEST", "source": 1 }, + { "begin": 15138, "end": 15233, "name": "SWAP4", "source": 1 }, + { "begin": 15138, "end": 15233, "name": "POP", "source": 1 }, + { + "begin": 15242, + "end": 15294, + "name": "PUSH [tag]", + "source": 1, + "value": "504" + }, + { "begin": 15287, "end": 15293, "name": "DUP2", "source": 1 }, + { "begin": 15282, "end": 15285, "name": "DUP6", "source": 1 }, + { + "begin": 15275, + "end": 15279, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 15268, "end": 15273, "name": "DUP7", "source": 1 }, + { "begin": 15264, "end": 15280, "name": "ADD", "source": 1 }, + { + "begin": 15242, + "end": 15294, + "name": "PUSH [tag]", + "source": 1, + "value": "284" + }, + { + "begin": 15242, + "end": 15294, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 15242, + "end": 15294, + "name": "tag", + "source": 1, + "value": "504" + }, + { "begin": 15242, "end": 15294, "name": "JUMPDEST", "source": 1 }, + { "begin": 15319, "end": 15325, "name": "DUP1", "source": 1 }, + { "begin": 15314, "end": 15317, "name": "DUP5", "source": 1 }, + { "begin": 15310, "end": 15326, "name": "ADD", "source": 1 }, + { "begin": 15303, "end": 15326, "name": "SWAP2", "source": 1 }, + { "begin": 15303, "end": 15326, "name": "POP", "source": 1 }, + { "begin": 15067, "end": 15332, "name": "POP", "source": 1 }, + { "begin": 14959, "end": 15332, "name": "SWAP3", "source": 1 }, + { "begin": 14959, "end": 15332, "name": "SWAP2", "source": 1 }, + { "begin": 14959, "end": 15332, "name": "POP", "source": 1 }, + { "begin": 14959, "end": 15332, "name": "POP", "source": 1 }, + { + "begin": 14959, + "end": 15332, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 15338, + "end": 15609, + "name": "tag", + "source": 1, + "value": "216" + }, + { "begin": 15338, "end": 15609, "name": "JUMPDEST", "source": 1 }, + { + "begin": 15468, + "end": 15471, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 15490, + "end": 15583, + "name": "PUSH [tag]", + "source": 1, + "value": "506" + }, + { "begin": 15579, "end": 15582, "name": "DUP3", "source": 1 }, + { "begin": 15570, "end": 15576, "name": "DUP5", "source": 1 }, + { + "begin": 15490, + "end": 15583, + "name": "PUSH [tag]", + "source": 1, + "value": "324" + }, + { + "begin": 15490, + "end": 15583, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 15490, + "end": 15583, + "name": "tag", + "source": 1, + "value": "506" + }, + { "begin": 15490, "end": 15583, "name": "JUMPDEST", "source": 1 }, + { "begin": 15483, "end": 15583, "name": "SWAP2", "source": 1 }, + { "begin": 15483, "end": 15583, "name": "POP", "source": 1 }, + { "begin": 15600, "end": 15603, "name": "DUP2", "source": 1 }, + { "begin": 15593, "end": 15603, "name": "SWAP1", "source": 1 }, + { "begin": 15593, "end": 15603, "name": "POP", "source": 1 }, + { "begin": 15338, "end": 15609, "name": "SWAP3", "source": 1 }, + { "begin": 15338, "end": 15609, "name": "SWAP2", "source": 1 }, + { "begin": 15338, "end": 15609, "name": "POP", "source": 1 }, + { "begin": 15338, "end": 15609, "name": "POP", "source": 1 }, + { + "begin": 15338, + "end": 15609, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 15615, + "end": 15947, + "name": "tag", + "source": 1, + "value": "252" + }, + { "begin": 15615, "end": 15947, "name": "JUMPDEST", "source": 1 }, + { + "begin": 15736, + "end": 15740, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 15774, + "end": 15776, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { "begin": 15763, "end": 15772, "name": "DUP3", "source": 1 }, + { "begin": 15759, "end": 15777, "name": "ADD", "source": 1 }, + { "begin": 15751, "end": 15777, "name": "SWAP1", "source": 1 }, + { "begin": 15751, "end": 15777, "name": "POP", "source": 1 }, + { + "begin": 15787, + "end": 15858, + "name": "PUSH [tag]", + "source": 1, + "value": "508" + }, + { + "begin": 15855, + "end": 15856, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 15844, "end": 15853, "name": "DUP4", "source": 1 }, + { "begin": 15840, "end": 15857, "name": "ADD", "source": 1 }, + { "begin": 15831, "end": 15837, "name": "DUP6", "source": 1 }, + { + "begin": 15787, + "end": 15858, + "name": "PUSH [tag]", + "source": 1, + "value": "281" + }, + { + "begin": 15787, + "end": 15858, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 15787, + "end": 15858, + "name": "tag", + "source": 1, + "value": "508" + }, + { "begin": 15787, "end": 15858, "name": "JUMPDEST", "source": 1 }, + { + "begin": 15868, + "end": 15940, + "name": "PUSH [tag]", + "source": 1, + "value": "509" + }, + { + "begin": 15936, + "end": 15938, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 15925, "end": 15934, "name": "DUP4", "source": 1 }, + { "begin": 15921, "end": 15939, "name": "ADD", "source": 1 }, + { "begin": 15912, "end": 15918, "name": "DUP5", "source": 1 }, + { + "begin": 15868, + "end": 15940, + "name": "PUSH [tag]", + "source": 1, + "value": "281" + }, + { + "begin": 15868, + "end": 15940, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 15868, + "end": 15940, + "name": "tag", + "source": 1, + "value": "509" + }, + { "begin": 15868, "end": 15940, "name": "JUMPDEST", "source": 1 }, + { "begin": 15615, "end": 15947, "name": "SWAP4", "source": 1 }, + { "begin": 15615, "end": 15947, "name": "SWAP3", "source": 1 }, + { "begin": 15615, "end": 15947, "name": "POP", "source": 1 }, + { "begin": 15615, "end": 15947, "name": "POP", "source": 1 }, + { "begin": 15615, "end": 15947, "name": "POP", "source": 1 }, + { + "begin": 15615, + "end": 15947, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 15953, + "end": 16107, + "name": "tag", + "source": 1, + "value": "325" + }, + { "begin": 15953, "end": 16107, "name": "JUMPDEST", "source": 1 }, + { "begin": 16037, "end": 16043, "name": "DUP3", "source": 1 }, + { "begin": 16032, "end": 16035, "name": "DUP2", "source": 1 }, + { "begin": 16027, "end": 16030, "name": "DUP4", "source": 1 }, + { + "begin": 16014, + "end": 16044, + "name": "CALLDATACOPY", + "source": 1 + }, + { + "begin": 16099, + "end": 16100, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 16090, "end": 16096, "name": "DUP4", "source": 1 }, + { "begin": 16085, "end": 16088, "name": "DUP4", "source": 1 }, + { "begin": 16081, "end": 16097, "name": "ADD", "source": 1 }, + { "begin": 16074, "end": 16101, "name": "MSTORE", "source": 1 }, + { "begin": 15953, "end": 16107, "name": "POP", "source": 1 }, + { "begin": 15953, "end": 16107, "name": "POP", "source": 1 }, + { "begin": 15953, "end": 16107, "name": "POP", "source": 1 }, + { + "begin": 15953, + "end": 16107, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 16137, + "end": 16441, + "name": "tag", + "source": 1, + "value": "326" + }, + { "begin": 16137, "end": 16441, "name": "JUMPDEST", "source": 1 }, + { + "begin": 16235, + "end": 16238, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 16256, + "end": 16327, + "name": "PUSH [tag]", + "source": 1, + "value": "512" + }, + { "begin": 16320, "end": 16326, "name": "DUP4", "source": 1 }, + { "begin": 16315, "end": 16318, "name": "DUP6", "source": 1 }, + { + "begin": 16256, + "end": 16327, + "name": "PUSH [tag]", + "source": 1, + "value": "283" + }, + { + "begin": 16256, + "end": 16327, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 16256, + "end": 16327, + "name": "tag", + "source": 1, + "value": "512" + }, + { "begin": 16256, "end": 16327, "name": "JUMPDEST", "source": 1 }, + { "begin": 16249, "end": 16327, "name": "SWAP4", "source": 1 }, + { "begin": 16249, "end": 16327, "name": "POP", "source": 1 }, + { + "begin": 16337, + "end": 16380, + "name": "PUSH [tag]", + "source": 1, + "value": "513" + }, + { "begin": 16373, "end": 16379, "name": "DUP4", "source": 1 }, + { "begin": 16368, "end": 16371, "name": "DUP6", "source": 1 }, + { "begin": 16361, "end": 16366, "name": "DUP5", "source": 1 }, + { + "begin": 16337, + "end": 16380, + "name": "PUSH [tag]", + "source": 1, + "value": "325" + }, + { + "begin": 16337, + "end": 16380, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 16337, + "end": 16380, + "name": "tag", + "source": 1, + "value": "513" + }, + { "begin": 16337, "end": 16380, "name": "JUMPDEST", "source": 1 }, + { + "begin": 16405, + "end": 16434, + "name": "PUSH [tag]", + "source": 1, + "value": "514" + }, + { "begin": 16427, "end": 16433, "name": "DUP4", "source": 1 }, + { + "begin": 16405, + "end": 16434, + "name": "PUSH [tag]", + "source": 1, + "value": "285" + }, + { + "begin": 16405, + "end": 16434, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 16405, + "end": 16434, + "name": "tag", + "source": 1, + "value": "514" + }, + { "begin": 16405, "end": 16434, "name": "JUMPDEST", "source": 1 }, + { "begin": 16400, "end": 16403, "name": "DUP5", "source": 1 }, + { "begin": 16396, "end": 16435, "name": "ADD", "source": 1 }, + { "begin": 16389, "end": 16435, "name": "SWAP1", "source": 1 }, + { "begin": 16389, "end": 16435, "name": "POP", "source": 1 }, + { "begin": 16137, "end": 16441, "name": "SWAP4", "source": 1 }, + { "begin": 16137, "end": 16441, "name": "SWAP3", "source": 1 }, + { "begin": 16137, "end": 16441, "name": "POP", "source": 1 }, + { "begin": 16137, "end": 16441, "name": "POP", "source": 1 }, + { "begin": 16137, "end": 16441, "name": "POP", "source": 1 }, + { + "begin": 16137, + "end": 16441, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 16447, + "end": 17103, + "name": "tag", + "source": 1, + "value": "258" + }, + { "begin": 16447, "end": 17103, "name": "JUMPDEST", "source": 1 }, + { + "begin": 16652, + "end": 16656, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 16690, + "end": 16692, + "name": "PUSH", + "source": 1, + "value": "60" + }, + { "begin": 16679, "end": 16688, "name": "DUP3", "source": 1 }, + { "begin": 16675, "end": 16693, "name": "ADD", "source": 1 }, + { "begin": 16667, "end": 16693, "name": "SWAP1", "source": 1 }, + { "begin": 16667, "end": 16693, "name": "POP", "source": 1 }, + { "begin": 16739, "end": 16748, "name": "DUP2", "source": 1 }, + { "begin": 16733, "end": 16737, "name": "DUP2", "source": 1 }, + { "begin": 16729, "end": 16749, "name": "SUB", "source": 1 }, + { + "begin": 16725, + "end": 16726, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 16714, "end": 16723, "name": "DUP4", "source": 1 }, + { "begin": 16710, "end": 16727, "name": "ADD", "source": 1 }, + { "begin": 16703, "end": 16750, "name": "MSTORE", "source": 1 }, + { + "begin": 16767, + "end": 16855, + "name": "PUSH [tag]", + "source": 1, + "value": "516" + }, + { "begin": 16850, "end": 16854, "name": "DUP2", "source": 1 }, + { "begin": 16841, "end": 16847, "name": "DUP8", "source": 1 }, + { "begin": 16833, "end": 16839, "name": "DUP10", "source": 1 }, + { + "begin": 16767, + "end": 16855, + "name": "PUSH [tag]", + "source": 1, + "value": "326" + }, + { + "begin": 16767, + "end": 16855, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 16767, + "end": 16855, + "name": "tag", + "source": 1, + "value": "516" + }, + { "begin": 16767, "end": 16855, "name": "JUMPDEST", "source": 1 }, + { "begin": 16759, "end": 16855, "name": "SWAP1", "source": 1 }, + { "begin": 16759, "end": 16855, "name": "POP", "source": 1 }, + { "begin": 16902, "end": 16911, "name": "DUP2", "source": 1 }, + { "begin": 16896, "end": 16900, "name": "DUP2", "source": 1 }, + { "begin": 16892, "end": 16912, "name": "SUB", "source": 1 }, + { + "begin": 16887, + "end": 16889, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 16876, "end": 16885, "name": "DUP4", "source": 1 }, + { "begin": 16872, "end": 16890, "name": "ADD", "source": 1 }, + { "begin": 16865, "end": 16913, "name": "MSTORE", "source": 1 }, + { + "begin": 16930, + "end": 17018, + "name": "PUSH [tag]", + "source": 1, + "value": "517" + }, + { "begin": 17013, "end": 17017, "name": "DUP2", "source": 1 }, + { "begin": 17004, "end": 17010, "name": "DUP6", "source": 1 }, + { "begin": 16996, "end": 17002, "name": "DUP8", "source": 1 }, + { + "begin": 16930, + "end": 17018, + "name": "PUSH [tag]", + "source": 1, + "value": "326" + }, + { + "begin": 16930, + "end": 17018, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 16930, + "end": 17018, + "name": "tag", + "source": 1, + "value": "517" + }, + { "begin": 16930, "end": 17018, "name": "JUMPDEST", "source": 1 }, + { "begin": 16922, "end": 17018, "name": "SWAP1", "source": 1 }, + { "begin": 16922, "end": 17018, "name": "POP", "source": 1 }, + { + "begin": 17028, + "end": 17096, + "name": "PUSH [tag]", + "source": 1, + "value": "518" + }, + { + "begin": 17092, + "end": 17094, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { "begin": 17081, "end": 17090, "name": "DUP4", "source": 1 }, + { "begin": 17077, "end": 17095, "name": "ADD", "source": 1 }, + { "begin": 17068, "end": 17074, "name": "DUP5", "source": 1 }, + { + "begin": 17028, + "end": 17096, + "name": "PUSH [tag]", + "source": 1, + "value": "299" + }, + { + "begin": 17028, + "end": 17096, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 17028, + "end": 17096, + "name": "tag", + "source": 1, + "value": "518" + }, + { "begin": 17028, "end": 17096, "name": "JUMPDEST", "source": 1 }, + { "begin": 16447, "end": 17103, "name": "SWAP7", "source": 1 }, + { "begin": 16447, "end": 17103, "name": "SWAP6", "source": 1 }, + { "begin": 16447, "end": 17103, "name": "POP", "source": 1 }, + { "begin": 16447, "end": 17103, "name": "POP", "source": 1 }, + { "begin": 16447, "end": 17103, "name": "POP", "source": 1 }, + { "begin": 16447, "end": 17103, "name": "POP", "source": 1 }, + { "begin": 16447, "end": 17103, "name": "POP", "source": 1 }, + { "begin": 16447, "end": 17103, "name": "POP", "source": 1 }, + { + "begin": 16447, + "end": 17103, + "name": "JUMP", + "source": 1, + "value": "[out]" + }, + { + "begin": 17109, + "end": 17551, + "name": "tag", + "source": 1, + "value": "275" + }, + { "begin": 17109, "end": 17551, "name": "JUMPDEST", "source": 1 }, + { + "begin": 17258, + "end": 17262, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 17296, + "end": 17298, + "name": "PUSH", + "source": 1, + "value": "60" + }, + { "begin": 17285, "end": 17294, "name": "DUP3", "source": 1 }, + { "begin": 17281, "end": 17299, "name": "ADD", "source": 1 }, + { "begin": 17273, "end": 17299, "name": "SWAP1", "source": 1 }, + { "begin": 17273, "end": 17299, "name": "POP", "source": 1 }, + { + "begin": 17309, + "end": 17380, + "name": "PUSH [tag]", + "source": 1, + "value": "520" + }, + { + "begin": 17377, + "end": 17378, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { "begin": 17366, "end": 17375, "name": "DUP4", "source": 1 }, + { "begin": 17362, "end": 17379, "name": "ADD", "source": 1 }, + { "begin": 17353, "end": 17359, "name": "DUP7", "source": 1 }, + { + "begin": 17309, + "end": 17380, + "name": "PUSH [tag]", + "source": 1, + "value": "281" + }, + { + "begin": 17309, + "end": 17380, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 17309, + "end": 17380, + "name": "tag", + "source": 1, + "value": "520" + }, + { "begin": 17309, "end": 17380, "name": "JUMPDEST", "source": 1 }, + { + "begin": 17390, + "end": 17462, + "name": "PUSH [tag]", + "source": 1, + "value": "521" + }, + { + "begin": 17458, + "end": 17460, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { "begin": 17447, "end": 17456, "name": "DUP4", "source": 1 }, + { "begin": 17443, "end": 17461, "name": "ADD", "source": 1 }, + { "begin": 17434, "end": 17440, "name": "DUP6", "source": 1 }, + { + "begin": 17390, + "end": 17462, + "name": "PUSH [tag]", + "source": 1, + "value": "281" + }, + { + "begin": 17390, + "end": 17462, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 17390, + "end": 17462, + "name": "tag", + "source": 1, + "value": "521" + }, + { "begin": 17390, "end": 17462, "name": "JUMPDEST", "source": 1 }, + { + "begin": 17472, + "end": 17544, + "name": "PUSH [tag]", + "source": 1, + "value": "522" + }, + { + "begin": 17540, + "end": 17542, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { "begin": 17529, "end": 17538, "name": "DUP4", "source": 1 }, + { "begin": 17525, "end": 17543, "name": "ADD", "source": 1 }, + { "begin": 17516, "end": 17522, "name": "DUP5", "source": 1 }, + { + "begin": 17472, + "end": 17544, + "name": "PUSH [tag]", + "source": 1, + "value": "281" + }, + { + "begin": 17472, + "end": 17544, + "name": "JUMP", + "source": 1, + "value": "[in]" + }, + { + "begin": 17472, + "end": 17544, + "name": "tag", + "source": 1, + "value": "522" + }, + { "begin": 17472, "end": 17544, "name": "JUMPDEST", "source": 1 }, + { "begin": 17109, "end": 17551, "name": "SWAP5", "source": 1 }, + { "begin": 17109, "end": 17551, "name": "SWAP4", "source": 1 }, + { "begin": 17109, "end": 17551, "name": "POP", "source": 1 }, + { "begin": 17109, "end": 17551, "name": "POP", "source": 1 }, + { "begin": 17109, "end": 17551, "name": "POP", "source": 1 }, + { "begin": 17109, "end": 17551, "name": "POP", "source": 1 }, + { + "begin": 17109, + "end": 17551, + "name": "JUMP", + "source": 1, + "value": "[out]" + } + ] + } + } + }, + "methodIdentifiers": { + "allowance(address,address)": "dd62ed3e", + "approve(address,uint256)": "095ea7b3", + "approve_delegate(address,uint256)": "f5bfbd8a", + "balanceOf(address)": "70a08231", + "burn(address,uint256)": "9dc29fac", + "clear_metadata()": "d3ba4b9e", + "decimals()": "313ce567", + "freeze(address)": "8d1fdf2f", + "freeze_asset()": "6b8751c1", + "get_address()": "0131222f", + "localasseterc20()": "9b5067e7", + "mint(address,uint256)": "40c10f19", + "name()": "06fdde03", + "set_address_interface(address)": "84810219", + "set_metadata(string,string,uint8)": "ee5dc1e4", + "set_team(address,address,address)": "f8bf8e95", + "symbol()": "95d89b41", + "thaw(address)": "5ea20216", + "thaw_asset()": "1cddec19", + "totalSupply()": "18160ddd", + "transfer(address,uint256)": "a9059cbb", + "transferFrom(address,address,uint256)": "23b872dd", + "transferFrom_delegate(address,address,uint256)": "7eea1205", + "transfer_delegate(address,uint256)": "a887c981", + "transfer_ownership(address)": "f0350c04" + } + }, + "ewasm": { "wasm": "" }, + "metadata": "{\"compiler\":{\"version\":\"0.8.11+commit.d7f03943\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve_delegate\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"who\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"clear_metadata\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"freeze\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"freeze_asset\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"get_address\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localasseterc20\",\"outputs\":[{\"internalType\":\"contract LocalAssetExtendedErc20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"instance_address\",\"type\":\"address\"}],\"name\":\"set_address_interface\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"name\":\"set_metadata\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"issuer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"freezer\",\"type\":\"address\"}],\"name\":\"set_team\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"thaw\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"thaw_asset\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom_delegate\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer_delegate\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"transfer_ownership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"Function to check the amount of tokens that an owner allowed to a spender. Selector: dd62ed3e\",\"params\":{\"owner\":\"address The address which owns the funds.\",\"spender\":\"address The address which will spend the funds.\"},\"returns\":{\"_0\":\"A uint256 specifying the amount of tokens still available for the spender.\"}},\"approve(address,uint256)\":{\"details\":\"Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 Selector: 095ea7b3\",\"params\":{\"spender\":\"The address which will spend the funds.\",\"value\":\"The amount of tokens to be spent.\"}},\"balanceOf(address)\":{\"details\":\"Gets the balance of the specified address. Selector: 70a08231\",\"params\":{\"who\":\"The address to query the balance of.\"},\"returns\":{\"_0\":\"An uint256 representing the amount owned by the passed address.\"}},\"burn(address,uint256)\":{\"details\":\"Burn tokens from an address Selector: 23b872dd\",\"params\":{\"from\":\"address The address from which you want to burn tokens\",\"value\":\"uint256 the amount of tokens to be burnt\"}},\"clear_metadata()\":{\"details\":\"Clear the name, symbol and decimals of your asset Selector: 23b872dd\"},\"decimals()\":{\"details\":\"Returns the decimals places of the token. Selector: 313ce567\"},\"freeze(address)\":{\"details\":\"Freeze an account, preventing it from operating with the asset Selector: 23b872dd\",\"params\":{\"account\":\"address The address that you want to freeze\"}},\"freeze_asset()\":{\"details\":\"Freeze the entire asset operations Selector: 23b872dd\"},\"mint(address,uint256)\":{\"details\":\"Mint tokens to an address Selector: 23b872dd\",\"params\":{\"to\":\"address The address to which you want to mint tokens\",\"value\":\"uint256 the amount of tokens to be minted\"}},\"name()\":{\"details\":\"Returns the name of the token. Selector: 06fdde03\"},\"set_metadata(string,string,uint8)\":{\"details\":\"Specify the name, symbol and decimals of your asset Selector: 23b872dd\",\"params\":{\"decimals\":\"uint8 The number of decimals of your asset\",\"name\":\"string The name of the asset\",\"symbol\":\"string The symbol of the asset\"}},\"set_team(address,address,address)\":{\"details\":\"Specify the issuer, admin and freezer of an asset Selector: 23b872dd\",\"params\":{\"admin\":\"address The address capable of burning tokens and unfreezing accounts/assets\",\"freezer\":\"address The address capable of freezing accounts/asset\",\"issuer\":\"address The address capable of issuing tokens\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token. Selector: 95d89b41\"},\"thaw(address)\":{\"details\":\"Unfreeze an account, letting it from operating againt with the asset Selector: 23b872dd\",\"params\":{\"account\":\"address The address that you want to unfreeze\"}},\"thaw_asset()\":{\"details\":\"Unfreeze the entire asset operations Selector: 23b872dd\"},\"totalSupply()\":{\"details\":\"Total number of tokens in existence Selector: 18160ddd\"},\"transfer(address,uint256)\":{\"details\":\"Transfer token for a specified address Selector: a9059cbb\",\"params\":{\"to\":\"The address to transfer to.\",\"value\":\"The amount to be transferred.\"}},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfer tokens from one address to another Selector: 23b872dd\",\"params\":{\"from\":\"address The address which you want to send tokens from\",\"to\":\"address The address which you want to transfer to\",\"value\":\"uint256 the amount of tokens to be transferred\"}},\"transfer_ownership(address)\":{\"details\":\"Transfer the ownership of an asset to a new account Selector: 23b872dd\",\"params\":{\"owner\":\"address The address of the new owner\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"localasseterc20()\":{\"notice\":\"The ierc20 at the known pre-compile address.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"main.sol\":\"LocalAssetExtendedErc20Instance\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"main.sol\":{\"keccak256\":\"0x5a3d183a3c7c37f3b13c339567c1f801439d7dcb24e86b42a7c0b7a04d07ffe4\",\"urls\":[\"bzz-raw://91e48fc055f1421fe4a69674c7c21789f7670e77f8079dae0ceebb53ade3bac8\",\"dweb:/ipfs/QmQ3g41AZRKVThWeF2VQ4bXVEb7tkoBLqo494kyAe3RLtt\"]}},\"version\":1}", + "storageLayout": { + "storage": [ + { + "astId": 190, + "contract": "main.sol:LocalAssetExtendedErc20Instance", + "label": "localasseterc20", + "offset": 0, + "slot": "0", + "type": "t_contract(LocalAssetExtendedErc20)181" + }, + { + "astId": 193, + "contract": "main.sol:LocalAssetExtendedErc20Instance", + "label": "localasseterc20address", + "offset": 0, + "slot": "1", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_contract(LocalAssetExtendedErc20)181": { + "encoding": "inplace", + "label": "contract LocalAssetExtendedErc20", + "numberOfBytes": "20" + } + } + }, + "userdoc": { + "kind": "user", + "methods": { + "localasseterc20()": { + "notice": "The ierc20 at the known pre-compile address." + } + }, + "version": 1 + } + }, + "sourceCode": "\n pragma solidity ^0.8.0;\n\n /**\n * @title ERC20 interface\n * @dev see https://github.com/ethereum/EIPs/issues/20\n * @dev copied from https://github.com/OpenZeppelin/openzeppelin-contracts\n */\n interface LocalAssetExtendedErc20 {\n \n /**\n * @dev Returns the name of the token.\n * Selector: 06fdde03\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n * Selector: 95d89b41\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n * Selector: 313ce567\n */\n function decimals() external view returns (uint8);\n \n /**\n * @dev Total number of tokens in existence\n * Selector: 18160ddd\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Gets the balance of the specified address.\n * Selector: 70a08231\n * @param who The address to query the balance of.\n * @return An uint256 representing the amount owned by the passed address.\n */\n function balanceOf(address who) external view returns (uint256);\n\n /**\n * @dev Function to check the amount of tokens that an owner allowed to a spender.\n * Selector: dd62ed3e\n * @param owner address The address which owns the funds.\n * @param spender address The address which will spend the funds.\n * @return A uint256 specifying the amount of tokens still available for the spender.\n */\n function allowance(address owner, address spender)\n external view returns (uint256);\n\n /**\n * @dev Transfer token for a specified address\n * Selector: a9059cbb\n * @param to The address to transfer to.\n * @param value The amount to be transferred.\n */\n function transfer(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Approve the passed address to spend the specified amount of tokens on behalf\n * of msg.sender.\n * Beware that changing an allowance with this method brings the risk that someone may\n * use both the old\n * and the new allowance by unfortunate transaction ordering. One possible solution to\n * mitigate this race condition is to first reduce the spender's allowance to 0 and set\n * the desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n * Selector: 095ea7b3\n * @param spender The address which will spend the funds.\n * @param value The amount of tokens to be spent.\n */\n function approve(address spender, uint256 value)\n external returns (bool);\n\n /**\n * @dev Transfer tokens from one address to another\n * Selector: 23b872dd\n * @param from address The address which you want to send tokens from\n * @param to address The address which you want to transfer to\n * @param value uint256 the amount of tokens to be transferred\n */\n function transferFrom(address from, address to, uint256 value)\n external returns (bool);\n\n /**\n * @dev Mint tokens to an address\n * Selector: 23b872dd\n * @param to address The address to which you want to mint tokens\n * @param value uint256 the amount of tokens to be minted\n */\n function mint(address to, uint256 value)\n external returns (bool);\n\n /**\n * @dev Burn tokens from an address\n * Selector: 23b872dd\n * @param from address The address from which you want to burn tokens\n * @param value uint256 the amount of tokens to be burnt\n */\n function burn(address from, uint256 value)\n external returns (bool);\n\n /**\n * @dev Freeze an account, preventing it from operating with the asset\n * Selector: 23b872dd\n * @param account address The address that you want to freeze\n */\n function freeze(address account)\n external returns (bool);\n\n /**\n * @dev Unfreeze an account, letting it from operating againt with the asset\n * Selector: 23b872dd\n * @param account address The address that you want to unfreeze\n */\n function thaw(address account)\n external returns (bool);\n\n /**\n * @dev Freeze the entire asset operations\n * Selector: 23b872dd\n */\n function freeze_asset()\n external returns (bool);\n\n /**\n * @dev Unfreeze the entire asset operations\n * Selector: 23b872dd\n */\n function thaw_asset()\n external returns (bool);\n\n /**\n * @dev Transfer the ownership of an asset to a new account\n * Selector: 23b872dd\n * @param owner address The address of the new owner\n */\n function transfer_ownership(address owner)\n external returns (bool);\n \n /**\n * @dev Specify the issuer, admin and freezer of an asset\n * Selector: 23b872dd\n * @param issuer address The address capable of issuing tokens\n * @param admin address The address capable of burning tokens and unfreezing accounts/assets\n * @param freezer address The address capable of freezing accounts/asset\n */\n function set_team(address issuer, address admin, address freezer)\n external returns (bool);\n\n /**\n * @dev Specify the name, symbol and decimals of your asset\n * Selector: 23b872dd\n * @param name string The name of the asset\n * @param symbol string The symbol of the asset\n * @param decimals uint8 The number of decimals of your asset\n */\n function set_metadata(string calldata name, string calldata symbol, uint8 decimals)\n external returns (bool);\n\n /**\n * @dev Clear the name, symbol and decimals of your asset\n * Selector: 23b872dd\n */\n function clear_metadata()\n external returns (bool);\n /**\n * @dev Event emited when a transfer has been performed.\n * Selector: ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\n * @param from address The address sending the tokens\n * @param to address The address receiving the tokens.\n * @param value uint256 The amount of tokens transfered.\n */\n event Transfer(\n address indexed from,\n address indexed to,\n uint256 value\n );\n\n /**\n * @dev Event emited when an approval has been registered.\n * Selector: 8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925\n * @param owner address Owner of the tokens.\n * @param spender address Allowed spender.\n * @param value uint256 Amount of tokens approved.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n }\n\n contract LocalAssetExtendedErc20Instance is LocalAssetExtendedErc20 {\n\n /// The ierc20 at the known pre-compile address.\n LocalAssetExtendedErc20 public localasseterc20 = LocalAssetExtendedErc20(0xffFfFffEDe9001a6f7F4798cCb76ef1E7f664701);\n address localasseterc20address = 0xffFfFffEDe9001a6f7F4798cCb76ef1E7f664701;\n\n receive() external payable {\n // React to receiving ether\n }\n\n function set_address_interface(address instance_address) public {\n localasseterc20 = LocalAssetExtendedErc20(instance_address);\n localasseterc20address = instance_address;\n }\n\n function get_address() public view returns(address) {\n return localasseterc20address;\n }\n\n function name() override external view returns (string memory) {\n // We nominate our target collator with all the tokens provided\n return localasseterc20.name();\n }\n \n function symbol() override external view returns (string memory) {\n // We nominate our target collator with all the tokens provided\n return localasseterc20.symbol();\n }\n \n function decimals() override external view returns (uint8) {\n // We nominate our target collator with all the tokens provided\n return localasseterc20.decimals();\n }\n\n function totalSupply() override external view returns (uint256){\n // We nominate our target collator with all the tokens provided\n return localasseterc20.totalSupply();\n }\n \n function balanceOf(address who) override external view returns (uint256){\n // We nominate our target collator with all the tokens provided\n return localasseterc20.balanceOf(who);\n }\n \n function allowance(\n address owner,\n address spender\n ) override external view returns (uint256){\n return localasseterc20.allowance(owner, spender);\n }\n\n function transfer(address to, uint256 value) override external returns (bool) {\n return localasseterc20.transfer(to, value);\n }\n\n function mint(address to, uint256 value) override external returns (bool) {\n return localasseterc20.mint(to, value);\n }\n\n function burn(address from, uint256 value) override external returns (bool) {\n return localasseterc20.burn(from, value);\n }\n\n function freeze(address account) override external returns (bool) {\n return localasseterc20.freeze(account);\n }\n\n function thaw(address account) override external returns (bool) {\n return localasseterc20.thaw(account);\n }\n\n function freeze_asset() override external returns (bool) {\n return localasseterc20.freeze_asset();\n }\n\n function thaw_asset() override external returns (bool) {\n return localasseterc20.thaw_asset();\n }\n\n function transfer_ownership(address owner) override external returns (bool) {\n return localasseterc20.transfer_ownership(owner);\n }\n\n function set_team(address issuer, address admin, address freezer) override external returns (bool) {\n return localasseterc20.set_team(issuer, admin, freezer);\n }\n\n function set_metadata(string calldata name, string calldata symbol, uint8 decimals) override external returns (bool) {\n return localasseterc20.set_metadata(name, symbol, decimals);\n }\n\n function clear_metadata() override external returns (bool) {\n return localasseterc20.clear_metadata();\n }\n \n function transfer_delegate(address to, uint256 value) external returns (bool) {\n (bool result, bytes memory data) = localasseterc20address.delegatecall(\n abi.encodeWithSignature(\"transfer(address,uint256)\", to, value));\n return result;\n }\n \n function approve(address spender, uint256 value) override external returns (bool) {\n return localasseterc20.approve(spender, value);\n }\n\n function approve_delegate(address spender, uint256 value) external returns (bool) {\n (bool result, bytes memory data) = localasseterc20address.delegatecall(\n abi.encodeWithSignature(\"approve(address,uint256)\", spender, value));\n return result;\n }\n \n function transferFrom(\n address from,\n address to,\n uint256 value)\n override external returns (bool) {\n return localasseterc20.transferFrom(from, to, value);\n }\n \n function transferFrom_delegate(\n address from,\n address to,\n uint256 value) external returns (bool) {\n (bool result, bytes memory data) = localasseterc20address.delegatecall(\n abi.encodeWithSignature(\"transferFrom(address,address,uint256)\", from, to, value));\n return result;\n }\n }" +} diff --git a/tests/contracts/sources.ts b/tests/contracts/sources.ts index 9778061ac6..b416bb35c0 100644 --- a/tests/contracts/sources.ts +++ b/tests/contracts/sources.ts @@ -1447,6 +1447,338 @@ export const contractSources: { [key: string]: string } = { author_mapping.clear_association(nimbus_id); } }`, + LocalAssetExtendedErc20Instance: ` + pragma solidity ^0.8.0; + + /** + * @title ERC20 interface + * @dev see https://github.com/ethereum/EIPs/issues/20 + * @dev copied from https://github.com/OpenZeppelin/openzeppelin-contracts + */ + interface LocalAssetExtendedErc20 { + + /** + * @dev Returns the name of the token. + * Selector: 06fdde03 + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token. + * Selector: 95d89b41 + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the decimals places of the token. + * Selector: 313ce567 + */ + function decimals() external view returns (uint8); + + /** + * @dev Total number of tokens in existence + * Selector: 18160ddd + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Gets the balance of the specified address. + * Selector: 70a08231 + * @param who The address to query the balance of. + * @return An uint256 representing the amount owned by the passed address. + */ + function balanceOf(address who) external view returns (uint256); + + /** + * @dev Function to check the amount of tokens that an owner allowed to a spender. + * Selector: dd62ed3e + * @param owner address The address which owns the funds. + * @param spender address The address which will spend the funds. + * @return A uint256 specifying the amount of tokens still available for the spender. + */ + function allowance(address owner, address spender) + external view returns (uint256); + + /** + * @dev Transfer token for a specified address + * Selector: a9059cbb + * @param to The address to transfer to. + * @param value The amount to be transferred. + */ + function transfer(address to, uint256 value) external returns (bool); + + /** + * @dev Approve the passed address to spend the specified amount of tokens on behalf + * of msg.sender. + * Beware that changing an allowance with this method brings the risk that someone may + * use both the old + * and the new allowance by unfortunate transaction ordering. One possible solution to + * mitigate this race condition is to first reduce the spender's allowance to 0 and set + * the desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * Selector: 095ea7b3 + * @param spender The address which will spend the funds. + * @param value The amount of tokens to be spent. + */ + function approve(address spender, uint256 value) + external returns (bool); + + /** + * @dev Transfer tokens from one address to another + * Selector: 23b872dd + * @param from address The address which you want to send tokens from + * @param to address The address which you want to transfer to + * @param value uint256 the amount of tokens to be transferred + */ + function transferFrom(address from, address to, uint256 value) + external returns (bool); + + /** + * @dev Mint tokens to an address + * Selector: 23b872dd + * @param to address The address to which you want to mint tokens + * @param value uint256 the amount of tokens to be minted + */ + function mint(address to, uint256 value) + external returns (bool); + + /** + * @dev Burn tokens from an address + * Selector: 23b872dd + * @param from address The address from which you want to burn tokens + * @param value uint256 the amount of tokens to be burnt + */ + function burn(address from, uint256 value) + external returns (bool); + + /** + * @dev Freeze an account, preventing it from operating with the asset + * Selector: 23b872dd + * @param account address The address that you want to freeze + */ + function freeze(address account) + external returns (bool); + + /** + * @dev Unfreeze an account, letting it from operating againt with the asset + * Selector: 23b872dd + * @param account address The address that you want to unfreeze + */ + function thaw(address account) + external returns (bool); + + /** + * @dev Freeze the entire asset operations + * Selector: 23b872dd + */ + function freeze_asset() + external returns (bool); + + /** + * @dev Unfreeze the entire asset operations + * Selector: 23b872dd + */ + function thaw_asset() + external returns (bool); + + /** + * @dev Transfer the ownership of an asset to a new account + * Selector: 23b872dd + * @param owner address The address of the new owner + */ + function transfer_ownership(address owner) + external returns (bool); + + /** + * @dev Specify the issuer, admin and freezer of an asset + * Selector: 23b872dd + * @param issuer address The address capable of issuing tokens + * @param admin address The address capable of burning tokens and unfreezing accounts/assets + * @param freezer address The address capable of freezing accounts/asset + */ + function set_team(address issuer, address admin, address freezer) + external returns (bool); + + /** + * @dev Specify the name, symbol and decimals of your asset + * Selector: 23b872dd + * @param name string The name of the asset + * @param symbol string The symbol of the asset + * @param decimals uint8 The number of decimals of your asset + */ + function set_metadata(string calldata name, string calldata symbol, uint8 decimals) + external returns (bool); + + /** + * @dev Clear the name, symbol and decimals of your asset + * Selector: 23b872dd + */ + function clear_metadata() + external returns (bool); + /** + * @dev Event emited when a transfer has been performed. + * Selector: ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef + * @param from address The address sending the tokens + * @param to address The address receiving the tokens. + * @param value uint256 The amount of tokens transfered. + */ + event Transfer( + address indexed from, + address indexed to, + uint256 value + ); + + /** + * @dev Event emited when an approval has been registered. + * Selector: 8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925 + * @param owner address Owner of the tokens. + * @param spender address Allowed spender. + * @param value uint256 Amount of tokens approved. + */ + event Approval( + address indexed owner, + address indexed spender, + uint256 value + ); + } + + contract LocalAssetExtendedErc20Instance is LocalAssetExtendedErc20 { + + /// The ierc20 at the known pre-compile address. + LocalAssetExtendedErc20 public localasseterc20 = + LocalAssetExtendedErc20(0xffFfFffEDe9001a6f7F4798cCb76ef1E7f664701); + address localasseterc20address = 0xffFfFffEDe9001a6f7F4798cCb76ef1E7f664701; + + receive() external payable { + // React to receiving ether + } + + function set_address_interface(address instance_address) public { + localasseterc20 = LocalAssetExtendedErc20(instance_address); + localasseterc20address = instance_address; + } + + function get_address() public view returns(address) { + return localasseterc20address; + } + + function name() override external view returns (string memory) { + // We nominate our target collator with all the tokens provided + return localasseterc20.name(); + } + + function symbol() override external view returns (string memory) { + // We nominate our target collator with all the tokens provided + return localasseterc20.symbol(); + } + + function decimals() override external view returns (uint8) { + // We nominate our target collator with all the tokens provided + return localasseterc20.decimals(); + } + + function totalSupply() override external view returns (uint256){ + // We nominate our target collator with all the tokens provided + return localasseterc20.totalSupply(); + } + + function balanceOf(address who) override external view returns (uint256){ + // We nominate our target collator with all the tokens provided + return localasseterc20.balanceOf(who); + } + + function allowance( + address owner, + address spender + ) override external view returns (uint256){ + return localasseterc20.allowance(owner, spender); + } + + function transfer(address to, uint256 value) override external returns (bool) { + return localasseterc20.transfer(to, value); + } + + function mint(address to, uint256 value) override external returns (bool) { + return localasseterc20.mint(to, value); + } + + function burn(address from, uint256 value) override external returns (bool) { + return localasseterc20.burn(from, value); + } + + function freeze(address account) override external returns (bool) { + return localasseterc20.freeze(account); + } + + function thaw(address account) override external returns (bool) { + return localasseterc20.thaw(account); + } + + function freeze_asset() override external returns (bool) { + return localasseterc20.freeze_asset(); + } + + function thaw_asset() override external returns (bool) { + return localasseterc20.thaw_asset(); + } + + function transfer_ownership(address owner) override external returns (bool) { + return localasseterc20.transfer_ownership(owner); + } + + function set_team( + address issuer, + address admin, + address freezer + ) override external returns (bool) { + return localasseterc20.set_team(issuer, admin, freezer); + } + + function set_metadata( + string calldata name, + string calldata symbol, + uint8 decimals + ) override external returns (bool) { + return localasseterc20.set_metadata(name, symbol, decimals); + } + + function clear_metadata() override external returns (bool) { + return localasseterc20.clear_metadata(); + } + + function transfer_delegate(address to, uint256 value) external returns (bool) { + (bool result, bytes memory data) = localasseterc20address.delegatecall( + abi.encodeWithSignature("transfer(address,uint256)", to, value)); + return result; + } + + function approve(address spender, uint256 value) override external returns (bool) { + return localasseterc20.approve(spender, value); + } + + function approve_delegate(address spender, uint256 value) external returns (bool) { + (bool result, bytes memory data) = localasseterc20address.delegatecall( + abi.encodeWithSignature("approve(address,uint256)", spender, value)); + return result; + } + + function transferFrom( + address from, + address to, + uint256 value) + override external returns (bool) { + return localasseterc20.transferFrom(from, to, value); + } + + function transferFrom_delegate( + address from, + address to, + uint256 value) external returns (bool) { + (bool result, bytes memory data) = localasseterc20address.delegatecall( + abi.encodeWithSignature("transferFrom(address,address,uint256)", from, to, value)); + return result; + } + }`, TestCallList: ` pragma solidity >=0.8.0; diff --git a/tests/tests/test-asset-manager.ts b/tests/tests/test-asset-manager.ts index 527bbe9a8e..9a4025bff6 100644 --- a/tests/tests/test-asset-manager.ts +++ b/tests/tests/test-asset-manager.ts @@ -3,7 +3,7 @@ import { expect } from "chai"; import { BN, bnToHex } from "@polkadot/util"; import { KeyringPair } from "@polkadot/keyring/types"; -import { ALITH_PRIV_KEY } from "../util/constants"; +import { ALITH, ALITH_PRIV_KEY, GLMR } from "../util/constants"; import { describeDevMoonbeam } from "../util/setup-dev-tests"; import { createBlockWithExtrinsic } from "../util/substrate-rpc"; import { verifyLatestBlockFees } from "../util/block"; @@ -19,18 +19,23 @@ const assetMetadata = { const sourceLocation = { XCM: { parents: 1, interior: "Here" } }; const newSourceLocation = { XCM: { parents: 1, interior: { X1: { Parachain: 1000 } } } }; -describeDevMoonbeam("XCM - asset manager - register asset", (context) => { - it("should be able to register an asset and set unit per sec", async function () { +describeDevMoonbeam("XCM - asset manager - register foreign asset", (context) => { + it("should be able to register a foreign asset and set unit per sec", async function () { const keyringEth = new Keyring({ type: "ethereum" }); const alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); const parachainOne = context.polkadotApi; - // registerAsset + // registerForeignAsset const { events: eventsRegister } = await createBlockWithExtrinsic( context, alith, parachainOne.tx.sudo.sudo( - parachainOne.tx.assetManager.registerAsset(sourceLocation, assetMetadata, new BN(1), true) + parachainOne.tx.assetManager.registerForeignAsset( + sourceLocation, + assetMetadata, + new BN(1), + true + ) ) ); // Look for assetId in events @@ -61,7 +66,44 @@ describeDevMoonbeam("XCM - asset manager - register asset", (context) => { }); }); -describeDevMoonbeam("XCM - asset manager - register asset", (context) => { +describeDevMoonbeam("XCM - asset manager - register local asset", (context) => { + it("should be able to register a local asset", async function () { + const keyringEth = new Keyring({ type: "ethereum" }); + const alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + + const parachainOne = context.polkadotApi; + // registerForeignAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + alith, + parachainOne.tx.sudo.sudo( + parachainOne.tx.assetManager.registerLocalAsset(ALITH, ALITH, true, new BN(1)) + ) + ); + // Look for assetId in events + let assetId: string; + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + // check asset in storage + const registeredAsset = ((await parachainOne.query.localAssets.asset(assetId)) as any).unwrap(); + expect(registeredAsset.owner.toString()).to.eq(ALITH); + + // check deposit in storage + const deposit = ( + (await parachainOne.query.assetManager.localAssetDeposit(assetId)) as any + ).unwrap(); + expect(deposit.creator.toString()).to.eq(ALITH); + + await verifyLatestBlockFees(context, expect); + }); +}); + +describeDevMoonbeam("XCM - asset manager - Change existing asset", (context) => { let assetId: string; let alith: KeyringPair; before("should be able to change existing asset type", async function () { @@ -69,12 +111,17 @@ describeDevMoonbeam("XCM - asset manager - register asset", (context) => { alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); const parachainOne = context.polkadotApi; - // registerAsset + // registerForeignAsset const { events: eventsRegister } = await createBlockWithExtrinsic( context, alith, parachainOne.tx.sudo.sudo( - parachainOne.tx.assetManager.registerAsset(sourceLocation, assetMetadata, new BN(1), true) + parachainOne.tx.assetManager.registerForeignAsset( + sourceLocation, + assetMetadata, + new BN(1), + true + ) ) ); @@ -139,7 +186,7 @@ describeDevMoonbeam("XCM - asset manager - register asset", (context) => { }); }); -describeDevMoonbeam("XCM - asset manager - register asset", (context) => { +describeDevMoonbeam("XCM - asset manager - Remove asset from supported", (context) => { let assetId: string; let alith: KeyringPair; before("should be able to change existing asset type", async function () { @@ -147,12 +194,17 @@ describeDevMoonbeam("XCM - asset manager - register asset", (context) => { alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); const parachainOne = context.polkadotApi; - // registerAsset + // registerForeignAsset const { events: eventsRegister } = await createBlockWithExtrinsic( context, alith, parachainOne.tx.sudo.sudo( - parachainOne.tx.assetManager.registerAsset(sourceLocation, assetMetadata, new BN(1), true) + parachainOne.tx.assetManager.registerForeignAsset( + sourceLocation, + assetMetadata, + new BN(1), + true + ) ) ); @@ -211,3 +263,167 @@ describeDevMoonbeam("XCM - asset manager - register asset", (context) => { expect(supportedAssets.length).to.eq(0); }); }); + +describeDevMoonbeam("XCM - asset manager - destroy foreign asset", (context) => { + let assetId: string; + let alith: KeyringPair; + before("should be able to change existing asset type", async function () { + const keyringEth = new Keyring({ type: "ethereum" }); + alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + + const parachainOne = context.polkadotApi; + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + alith, + parachainOne.tx.sudo.sudo( + parachainOne.tx.assetManager.registerForeignAsset( + sourceLocation, + assetMetadata, + new BN(1), + true + ) + ) + ); + + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + // setAssetUnitsPerSecond + const { events } = await createBlockWithExtrinsic( + context, + alith, + parachainOne.tx.sudo.sudo( + parachainOne.tx.assetManager.setAssetUnitsPerSecond(sourceLocation, 1, 0) + ) + ); + expect(events[1].method.toString()).to.eq("UnitsPerSecondChanged"); + expect(events[4].method.toString()).to.eq("ExtrinsicSuccess"); + + // check asset in storage + const registeredAsset = ((await parachainOne.query.assets.asset(assetId)) as any).unwrap(); + expect(registeredAsset.owner.toString()).to.eq(palletId); + + await verifyLatestBlockFees(context, expect); + }); + + it("should be able to destroy a foreign asset through pallet-asset-manager", async function () { + const assetDestroyWitness = context.polkadotApi.createType("PalletAssetsDestroyWitness", { + accounts: 0, + sufficients: 0, + approvals: 0, + }); + + // Destroy foreign asset + await createBlockWithExtrinsic( + context, + alith, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.destroyForeignAsset(assetId, assetDestroyWitness, 1) + ) + ); + + // assetId + let id = (await context.polkadotApi.query.assetManager.assetTypeId(sourceLocation)) as any; + + // asset units per second removed + let assetUnitsPerSecond = (await context.polkadotApi.query.assetManager.assetTypeUnitsPerSecond( + sourceLocation + )) as any; + + // Supported assets should be 0 + let supportedAssets = + (await context.polkadotApi.query.assetManager.supportedFeePaymentAssets()) as any; + + // assetDetails should have dissapeared + let assetDetails = (await context.polkadotApi.query.assets.asset(assetId)) as any; + + expect(assetUnitsPerSecond.isNone).to.eq(true); + expect(id.isNone).to.eq(true); + expect(assetDetails.isNone).to.eq(true); + // the asset should not be supported + expect(supportedAssets.length).to.eq(0); + }); +}); + +describeDevMoonbeam("XCM - asset manager - destroy local asset", (context) => { + let assetId: string; + let alith: KeyringPair; + before("should be able to change existing asset type", async function () { + const keyringEth = new Keyring({ type: "ethereum" }); + alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + + const parachainOne = context.polkadotApi; + + // Check ALITH has amount reserved + const accountDetailsBefore = (await parachainOne.query.system.account(ALITH)) as any; + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + alith, + parachainOne.tx.sudo.sudo( + parachainOne.tx.assetManager.registerLocalAsset(ALITH, ALITH, true, new BN(1)) + ) + ); + + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + // check asset in storage + const registeredAsset = ((await parachainOne.query.localAssets.asset(assetId)) as any).unwrap(); + expect(registeredAsset.owner.toString()).to.eq(ALITH); + + // Check ALITH has amount reserved + const accountDetails = (await parachainOne.query.system.account(ALITH)) as any; + expect(accountDetails.data.reserved.toString()).to.eq( + (accountDetailsBefore.data.reserved.toBigInt() + 100n * GLMR).toString() + ); + await verifyLatestBlockFees(context, expect); + }); + + it("should be able to destroy a local asset through pallet-asset-manager", async function () { + const assetDestroyWitness = context.polkadotApi.createType("PalletAssetsDestroyWitness", { + accounts: 0, + sufficients: 0, + approvals: 0, + }); + + // Reserved amount back to creator + const accountDetailsBefore = (await context.polkadotApi.query.system.account(ALITH)) as any; + + await createBlockWithExtrinsic( + context, + alith, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.destroyLocalAsset(assetId, assetDestroyWitness) + ) + ); + + // assetDetails should have dissapeared + let assetDetails = (await context.polkadotApi.query.localAssets.asset(assetId)) as any; + expect(assetDetails.isNone).to.eq(true); + + // Reserved amount back to creator + const accountDetailsAfter = (await context.polkadotApi.query.system.account(ALITH)) as any; + + // Amount should have decreased in one GLMR + expect(accountDetailsAfter.data.reserved.toString()).to.eq( + (accountDetailsBefore.data.reserved.toBigInt() - 100n * GLMR).toString() + ); + + // check deposit not in storage + const deposit = (await context.polkadotApi.query.assetManager.localAssetDeposit( + assetId + )) as any; + expect(deposit.isNone).to.eq(true); + }); +}); diff --git a/tests/tests/test-assets-sufficients.ts b/tests/tests/test-assets-sufficients.ts index 26d7bf427b..be872776f2 100644 --- a/tests/tests/test-assets-sufficients.ts +++ b/tests/tests/test-assets-sufficients.ts @@ -35,7 +35,7 @@ async function mockAssetBalance( // Register the asset await context.polkadotApi.tx.sudo .sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( sourceLocationRelayAssetType, relayAssetMetadata, new BN(1), diff --git a/tests/tests/test-mock-dmp.ts b/tests/tests/test-mock-dmp.ts index 3bcb8abcd5..08ffcd5a5b 100644 --- a/tests/tests/test-mock-dmp.ts +++ b/tests/tests/test-mock-dmp.ts @@ -30,12 +30,12 @@ describeDevMoonbeam("Mock XCM - receive downward transfer", (context) => { const keyringEth = new Keyring({ type: "ethereum" }); alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); - // registerAsset + // registerForeignAsset const { events: eventsRegister } = await createBlockWithExtrinsic( context, alith, context.polkadotApi.tx.sudo.sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( sourceLocation, assetMetadata, new BN(1), diff --git a/tests/tests/test-mock-hrmp.ts b/tests/tests/test-mock-hrmp.ts index 99bbdd0bdf..29a8c1d50e 100644 --- a/tests/tests/test-mock-hrmp.ts +++ b/tests/tests/test-mock-hrmp.ts @@ -3,7 +3,7 @@ import { KeyringPair } from "@polkadot/keyring/types"; import { expect } from "chai"; import { BN, u8aToHex } from "@polkadot/util"; -import { ALITH_PRIV_KEY, RANDOM_PRIV_KEY } from "../util/constants"; +import { ALITH_PRIV_KEY, BALTATHAR_PRIVATE_KEY, RANDOM_PRIV_KEY } from "../util/constants"; import { describeDevMoonbeam } from "../util/setup-dev-tests"; import { createBlockWithExtrinsic } from "../util/substrate-rpc"; import { customWeb3Request } from "../util/providers"; @@ -60,12 +60,12 @@ describeDevMoonbeam("Mock XCM - receive horizontal transfer", (context) => { const keyringEth = new Keyring({ type: "ethereum" }); alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); - // registerAsset + // registerForeignAsset const { events: eventsRegister } = await createBlockWithExtrinsic( context, alith, context.polkadotApi.tx.sudo.sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( sourceLocation, assetMetadata, new BN(1), @@ -126,13 +126,13 @@ describeDevMoonbeam("Mock XCM - receive horizontal transfer", (context) => { const keyringEth = new Keyring({ type: "ethereum" }); alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); - // registerAsset + // registerForeignAsset // We register statemine with the new prefix const { events: eventsRegister } = await createBlockWithExtrinsic( context, alith, context.polkadotApi.tx.sudo.sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( statemintLocation, assetMetadata, new BN(1), @@ -255,12 +255,12 @@ describeDevMoonbeam("Mock XCM - receive horizontal transfer", (context) => { const keyringEth = new Keyring({ type: "ethereum" }); alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); - // registerAsset + // registerForeignAsset const { events: eventsRegister } = await createBlockWithExtrinsic( context, alith, context.polkadotApi.tx.sudo.sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( statemintLocation, assetMetadata, new BN(1), @@ -645,6 +645,179 @@ describeDevMoonbeam( } ); +describeDevMoonbeam("Mock XCM - receive horizontal transfer", (context) => { + let assetId: string; + let alith: KeyringPair; + let baltathar: KeyringPair; + let paraId: ParaId; + let transferredBalance; + let sovereignAddress; + + before("Should Register an asset and set unit per sec", async function () { + const keyringEth = new Keyring({ type: "ethereum" }); + alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltathar = await keyringEth.addFromUri(BALTATHAR_PRIVATE_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + alith, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltathar.address, + baltathar.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + transferredBalance = new BN(100000000000000); + + // mint asset + await createBlockWithExtrinsic( + context, + baltathar, + context.polkadotApi.tx.localAssets.mint(assetId, alith.address, transferredBalance) + ); + + paraId = context.polkadotApi.createType("ParaId", 2000) as any; + sovereignAddress = u8aToHex( + new Uint8Array([...new TextEncoder().encode("sibl"), ...paraId.toU8a()]) + ).padEnd(42, "0"); + + // We first fund parachain 2000 sovreign account + await createBlockWithExtrinsic( + context, + alith, + context.polkadotApi.tx.balances.transfer(sovereignAddress, transferredBalance) + ); + + // transfer to para Id sovereign to emulate having sent the tokens + await createBlockWithExtrinsic( + context, + alith, + context.polkadotApi.tx.localAssets.transfer(assetId, alith.address, transferredBalance) + ); + }); + + it("Should receive 10 Local Asset tokens and sufficent DEV to pay for fee", async function () { + const metadata = await context.polkadotApi.rpc.state.getMetadata(); + const balancesPalletIndex = (metadata.asLatest.toHuman().pallets as Array).find( + (pallet) => { + return pallet.name === "Balances"; + } + ).index; + + const localAssetsPalletIndex = (metadata.asLatest.toHuman().pallets as Array).find( + (pallet) => { + return pallet.name === "LocalAssets"; + } + ).index; + + // We are charging 100_000_000 weight for every XCM instruction + // We are executing 4 instructions + // 100_000_000 * 4 * 50000 = 20000000000000 + // We are charging 20 micro DEV for this operation + // The rest should be going to the deposit account + let xcmMessage = { + V2: [ + { + WithdrawAsset: [ + { + // This is the new reanchored logic + id: { + Concrete: { + parents: 0, + interior: { + X1: { PalletInstance: balancesPalletIndex }, + }, + }, + }, + fun: { Fungible: transferredBalance }, + }, + { + // This is the new reanchored logic + id: { + Concrete: { + parents: 0, + interior: { + X2: [{ PalletInstance: localAssetsPalletIndex }, { GeneralIndex: assetId }], + }, + }, + }, + fun: { Fungible: transferredBalance }, + }, + ], + }, + { ClearOrigin: null }, + { + BuyExecution: { + fees: { + id: { + // This is the new reanchored logic + Concrete: { + parents: 0, + interior: { + X1: { PalletInstance: balancesPalletIndex }, + }, + }, + }, + fun: { Fungible: transferredBalance }, + }, + weightLimit: { Limited: new BN(4000000000) }, + }, + }, + { + DepositAsset: { + assets: { Wild: "All" }, + maxAssets: new BN(2), + beneficiary: { + parents: 0, + interior: { X1: { AccountKey20: { network: "Any", key: alith.address } } }, + }, + }, + }, + ], + }; + + const xcmpFormat: XcmpMessageFormat = context.polkadotApi.createType( + "XcmpMessageFormat", + "ConcatenatedVersionedXcm" + ) as any; + const receivedMessage: XcmVersionedXcm = context.polkadotApi.createType( + "XcmVersionedXcm", + xcmMessage + ) as any; + + const totalMessage = [...xcmpFormat.toU8a(), ...receivedMessage.toU8a()]; + + // Send RPC call to inject XCM message + // We will set a specific message knowing that it should mint the statemint asset + await customWeb3Request(context.web3, "xcm_injectHrmpMessage", [foreign_para_id, totalMessage]); + + // Create a block in which the XCM will be executed + await context.createBlock(); + + // Make sure the state has ALITH's LOCAL parachain tokens + let alithLocalTokBalance = ( + (await context.polkadotApi.query.localAssets.account(assetId, alith.address)) as any + ) + .unwrap() + ["balance"].toBigInt(); + + expect(alithLocalTokBalance.toString()).to.eq(transferredBalance.toString()); + }); +}); + describeDevMoonbeam("Mock XCM - receive horizontal transfer", (context) => { let assetIdZero: string; let assetIdOne: string; @@ -662,7 +835,7 @@ describeDevMoonbeam("Mock XCM - receive horizontal transfer", (context) => { context, alith, context.polkadotApi.tx.sudo.sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( statemintLocation, assetMetadata, new BN(1), @@ -684,7 +857,7 @@ describeDevMoonbeam("Mock XCM - receive horizontal transfer", (context) => { context, alith, context.polkadotApi.tx.sudo.sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( statemintLocationAssetOne, assetMetadata, new BN(1), @@ -813,6 +986,182 @@ describeDevMoonbeam("Mock XCM - receive horizontal transfer", (context) => { }); }); +describeDevMoonbeam("Mock XCM - receive horizontal transfer", (context) => { + let assetId: string; + let alith: KeyringPair; + let baltathar: KeyringPair; + let paraId: ParaId; + let transferredBalance; + let sovereignAddress; + + before("Should Register an asset and set unit per sec", async function () { + const keyringEth = new Keyring({ type: "ethereum" }); + alith = keyringEth.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltathar = await keyringEth.addFromUri(BALTATHAR_PRIVATE_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + alith, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltathar.address, + baltathar.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + transferredBalance = new BN(100000000000000); + + // mint asset + await createBlockWithExtrinsic( + context, + baltathar, + context.polkadotApi.tx.localAssets.mint(assetId, alith.address, transferredBalance) + ); + + paraId = context.polkadotApi.createType("ParaId", 2000) as any; + sovereignAddress = u8aToHex( + new Uint8Array([...new TextEncoder().encode("sibl"), ...paraId.toU8a()]) + ).padEnd(42, "0"); + + // We first fund parachain 2000 sovreign account + await createBlockWithExtrinsic( + context, + alith, + context.polkadotApi.tx.balances.transfer(sovereignAddress, transferredBalance) + ); + + // transfer to para Id sovereign to emulate having sent the tokens + await createBlockWithExtrinsic( + context, + alith, + context.polkadotApi.tx.localAssets.transfer(assetId, alith.address, transferredBalance) + ); + }); + + it("Should receive 10 Local Assets and DEV to pay for fee with old reanchor", async function () { + let ownParaId = (await context.polkadotApi.query.parachainInfo.parachainId()) as any; + const metadata = await context.polkadotApi.rpc.state.getMetadata(); + const balancesPalletIndex = (metadata.asLatest.toHuman().pallets as Array).find( + (pallet) => { + return pallet.name === "Balances"; + } + ).index; + + const localAssetsPalletIndex = (metadata.asLatest.toHuman().pallets as Array).find( + (pallet) => { + return pallet.name === "LocalAssets"; + } + ).index; + + // We are charging 100_000_000 weight for every XCM instruction + // We are executing 4 instructions + // 100_000_000 * 4 * 50000 = 20000000000000 + // We are charging 20 micro DEV for this operation + // The rest should be going to the deposit account + let xcmMessage = { + V2: [ + { + WithdrawAsset: [ + { + // This is the new reanchored logic + id: { + Concrete: { + parents: 1, + interior: { + X2: [{ Parachain: ownParaId }, { PalletInstance: balancesPalletIndex }], + }, + }, + }, + fun: { Fungible: transferredBalance }, + }, + { + // This is the new reanchored logic + id: { + Concrete: { + parents: 1, + interior: { + X3: [ + { Parachain: ownParaId }, + { PalletInstance: localAssetsPalletIndex }, + { GeneralIndex: assetId }, + ], + }, + }, + }, + fun: { Fungible: transferredBalance }, + }, + ], + }, + { ClearOrigin: null }, + { + BuyExecution: { + fees: { + id: { + // This is the new reanchored logic + Concrete: { + parents: 1, + interior: { + X2: [{ Parachain: ownParaId }, { PalletInstance: balancesPalletIndex }], + }, + }, + }, + fun: { Fungible: transferredBalance }, + }, + weightLimit: { Limited: new BN(4000000000) }, + }, + }, + { + DepositAsset: { + assets: { Wild: "All" }, + maxAssets: new BN(2), + beneficiary: { + parents: 0, + interior: { X1: { AccountKey20: { network: "Any", key: alith.address } } }, + }, + }, + }, + ], + }; + + const xcmpFormat: XcmpMessageFormat = context.polkadotApi.createType( + "XcmpMessageFormat", + "ConcatenatedVersionedXcm" + ) as any; + const receivedMessage: XcmVersionedXcm = context.polkadotApi.createType( + "XcmVersionedXcm", + xcmMessage + ) as any; + + const totalMessage = [...xcmpFormat.toU8a(), ...receivedMessage.toU8a()]; + // Send RPC call to inject XCM message + // We will set a specific message knowing that it should mint the statemint asset + await customWeb3Request(context.web3, "xcm_injectHrmpMessage", [foreign_para_id, totalMessage]); + + // Create a block in which the XCM will be executed + await context.createBlock(); + + // Make sure the state has ALITH's LOCAL parachain tokens + let alithLocalTokBalance = ( + (await context.polkadotApi.query.localAssets.account(assetId, alith.address)) as any + ) + .unwrap() + ["balance"].toBigInt(); + + expect(alithLocalTokBalance.toString()).to.eq(transferredBalance.toString()); + }); +}); describeDevMoonbeam("Mock XCM - receive horizontal transfer", (context) => { let assetIdZero: string; let alith: KeyringPair; @@ -827,7 +1176,7 @@ describeDevMoonbeam("Mock XCM - receive horizontal transfer", (context) => { context, alith, context.polkadotApi.tx.sudo.sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( statemintLocation, assetMetadata, new BN(1), diff --git a/tests/tests/test-pallet-maintenance-mode.ts b/tests/tests/test-pallet-maintenance-mode.ts index 9f8b76ee56..6e935131bc 100644 --- a/tests/tests/test-pallet-maintenance-mode.ts +++ b/tests/tests/test-pallet-maintenance-mode.ts @@ -455,12 +455,12 @@ describeDevMoonbeam( const keyring = new Keyring({ type: "ethereum" }); sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); - // registerAsset + // registerForeignAsset const { events: eventsRegister } = await createBlockWithExtrinsic( context, sudoAccount, context.polkadotApi.tx.sudo.sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( sourceLocation, assetMetadata, new BN(1), @@ -549,12 +549,12 @@ describeDevMoonbeam( const keyring = new Keyring({ type: "ethereum" }); sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); - // registerAsset + // registerForeignAsset const { events: eventsRegister } = await createBlockWithExtrinsic( context, sudoAccount, context.polkadotApi.tx.sudo.sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( sourceLocation, assetMetadata, new BN(1), diff --git a/tests/tests/test-precompile/test-precompile-assets-erc20.ts b/tests/tests/test-precompile/test-precompile-assets-erc20.ts index c44d0a0957..049fc5eeed 100644 --- a/tests/tests/test-precompile/test-precompile-assets-erc20.ts +++ b/tests/tests/test-precompile/test-precompile-assets-erc20.ts @@ -43,7 +43,7 @@ export async function mockAssetBalance( // Register the asset await context.polkadotApi.tx.sudo .sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( sourceLocationRelayAssetType, relayAssetMetadata, new BN(1), diff --git a/tests/tests/test-precompile/test-precompile-local-assets-erc20.ts b/tests/tests/test-precompile/test-precompile-local-assets-erc20.ts new file mode 100644 index 0000000000..ebb43ed445 --- /dev/null +++ b/tests/tests/test-precompile/test-precompile-local-assets-erc20.ts @@ -0,0 +1,2102 @@ +import { expect } from "chai"; +import { describeDevMoonbeamAllEthTxTypes } from "../../util/setup-dev-tests"; +import { customWeb3Request } from "../../util/providers"; +import { createBlockWithExtrinsic } from "../../util/substrate-rpc"; + +import { + GENESIS_ACCOUNT, + ALITH, + BALTATHAR, + ALITH_PRIV_KEY, + CHARLETH, + BALTATHAR_PRIV_KEY, +} from "../../util/constants"; +import { blake2AsU8a, xxhashAsU8a } from "@polkadot/util-crypto"; +import { + BN, + hexToU8a, + bnToHex, + u8aToHex, + stringToHex, + numberToHex, + u8aToString, +} from "@polkadot/util"; +import Keyring from "@polkadot/keyring"; +import { getCompiled } from "../../util/contracts"; +import { ethers } from "ethers"; +import { createContract, createTransaction } from "../../util/transactions"; + +const ADDRESS_ERC20 = "0xFfFFfFff1FcaCBd218EDc0EbA20Fc2308C778080"; +const SELECTORS = { + balanceOf: "70a08231", + totalSupply: "18160ddd", + approve: "095ea7b3", + allowance: "dd62ed3e", + transfer: "a9059cbb", + transferFrom: "23b872dd", + logApprove: "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + logTransfer: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", +}; +const GAS_PRICE = "0x" + (1_000_000_000).toString(16); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress, contractInstanceAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, baltatharAccount.address, 100000000000000) + ); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + contractInstanceAddress = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + + it("allows to call name", async function () { + let data = iFace.encodeFunctionData( + // action + "name", + [] + ); + + const tx_call = await customWeb3Request(context.web3, "eth_call", [ + { + from: ALITH, + value: "0x0", + gas: "0x10000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }, + ]); + + let expected = stringToHex("Local"); + let offset = numberToHex(32).slice(2).padStart(64, "0"); + let length = numberToHex(5).slice(2).padStart(64, "0"); + // Bytes are padded at the end + let expected_hex = expected.slice(2).padEnd(64, "0"); + expect(tx_call.result).equals("0x" + offset + length + expected_hex); + }); + + it("allows to call symbol", async function () { + let data = iFace.encodeFunctionData( + // action + "symbol", + [] + ); + + const tx_call = await customWeb3Request(context.web3, "eth_call", [ + { + from: GENESIS_ACCOUNT, + value: "0x0", + gas: "0x10000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }, + ]); + + let expected = stringToHex("Local"); + let offset = numberToHex(32).slice(2).padStart(64, "0"); + let length = numberToHex(5).slice(2).padStart(64, "0"); + // Bytes are padded at the end + let expected_hex = expected.slice(2).padEnd(64, "0"); + expect(tx_call.result).equals("0x" + offset + length + expected_hex); + }); + + it("allows to call decimals", async function () { + let data = iFace.encodeFunctionData( + // action + "decimals", + [] + ); + + const tx_call = await customWeb3Request(context.web3, "eth_call", [ + { + from: GENESIS_ACCOUNT, + value: "0x0", + gas: "0x10000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }, + ]); + + let expected = "0x" + numberToHex(12).slice(2).padStart(64, "0"); + expect(tx_call.result).equals(expected); + }); + + it("allows to call getBalance", async function () { + let data = iFace.encodeFunctionData( + // action + "balanceOf", + [BALTATHAR] + ); + + const tx_call = await customWeb3Request(context.web3, "eth_call", [ + { + from: GENESIS_ACCOUNT, + value: "0x0", + gas: "0x10000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }, + ]); + let amount = new BN(100000000000000); + + let amount_hex = "0x" + bnToHex(amount).slice(2).padStart(64, "0"); + expect(tx_call.result).equals(amount_hex); + }); + + it("allows to call totalSupply", async function () { + let data = iFace.encodeFunctionData( + // action + "totalSupply", + [] + ); + const tx_call = await customWeb3Request(context.web3, "eth_call", [ + { + from: GENESIS_ACCOUNT, + value: "0x0", + gas: "0x10000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }, + ]); + + let amount = new BN(100000000000000); + + let amount_hex = "0x" + bnToHex(amount).slice(2).padStart(64, "0"); + expect(tx_call.result).equals(amount_hex); + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, sudoAccount.address, 100000000000000) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to approve transfers, and allowance matches", async function () { + let data = iFace.encodeFunctionData( + // action + "approve", + [BALTATHAR, 1000] + ); + + const tx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + const block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + expect(receipt.logs.length).to.eq(1); + expect(receipt.logs[0].address.toLowerCase()).to.eq(assetAddress); + expect(receipt.logs[0].topics.length).to.eq(3); + expect(receipt.logs[0].topics[0]).to.eq(SELECTORS.logApprove); + let approvals = (await context.polkadotApi.query.localAssets.approvals( + assetId, + ALITH, + BALTATHAR + )) as any; + + expect(approvals.unwrap().amount.eq(new BN(1000))).to.equal(true); + }); + it("should gather the allowance", async function () { + let data = iFace.encodeFunctionData( + // action + "allowance", + [ALITH, BALTATHAR] + ); + + const tx_call = await customWeb3Request(context.web3, "eth_call", [ + { + from: GENESIS_ACCOUNT, + value: "0x0", + gas: "0x10000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }, + ]); + let amount = new BN(1000); + + let amount_hex = "0x" + bnToHex(amount).slice(2).padStart(64, "0"); + expect(tx_call.result).equals(amount_hex); + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, sudoAccount.address, 100000000000000) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to approve transfer and use transferFrom", async function () { + // Create approval + let data = iFace.encodeFunctionData( + // action + "approve", + [BALTATHAR, 1000] + ); + + let tx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + let block = await context.createBlock({ + transactions: [tx], + }); + + let approvals = (await context.polkadotApi.query.localAssets.approvals( + assetId, + ALITH, + BALTATHAR + )) as any; + + expect(approvals.unwrap().amount.eq(new BN(1000))).to.equal(true); + // We are gonna spend 1000 from alith to send it to charleth + data = iFace.encodeFunctionData( + // action + "transferFrom", + [ALITH, CHARLETH, 1000] + ); + + tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + block = await context.createBlock({ + transactions: [tx], + }); + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.logs.length).to.eq(1); + expect(receipt.logs[0].address.toLocaleLowerCase()).to.eq(assetAddress); + expect(receipt.logs[0].topics.length).to.eq(3); + expect(receipt.logs[0].topics[0]).to.eq(SELECTORS.logTransfer); + expect(receipt.status).to.equal(true); + + // Approve amount is null now + approvals = (await context.polkadotApi.query.localAssets.approvals( + assetId, + ALITH, + BALTATHAR + )) as any; + expect(approvals.isNone).to.eq(true); + + // Charleth balance is 1000 + let charletBalance = (await context.polkadotApi.query.localAssets.account( + assetId, + CHARLETH + )) as any; + expect(charletBalance.unwrap()["balance"].eq(new BN(1000))).to.equal(true); + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, sudoAccount.address, 100000000000000) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to transfer", async function () { + // Create approval + let data = iFace.encodeFunctionData( + // action + "transfer", + [BALTATHAR, 1000] + ); + + let tx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + let block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + expect(receipt.status).to.equal(true); + + // Baltathar balance is 1000 + let baltatharBalance = (await context.polkadotApi.query.localAssets.account( + assetId, + BALTATHAR + )) as any; + expect(baltatharBalance.unwrap()["balance"].eq(new BN(1000))).to.equal(true); + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes("Precompiles - Assets-ERC20 Wasm", (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress, contractInstanceAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, sudoAccount.address, 100000000000000) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + contractInstanceAddress = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + + // set asset address + let setAddressData = iFace.encodeFunctionData( + // action + "set_address_interface", + [context.web3.utils.toChecksumAddress(assetAddress)] + ); + + // We need this because the asset addres is random + // so we need a way to correctly reference it in the contract + let setDataTx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: setAddressData, + }); + + await context.createBlock({ + transactions: [setDataTx], + }); + }); + it("allows to approve transfer and use transferFrom through delegateCalls", async function () { + // Create approval + let data = iFace.encodeFunctionData( + // action + "approve_delegate", + [BALTATHAR, 1000] + ); + + let tx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: data, + }); + + let block = await context.createBlock({ + transactions: [tx], + }); + + let receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + expect(receipt.logs.length).to.eq(1); + expect(receipt.logs[0].address).to.eq(contractInstanceAddress); + expect(receipt.logs[0].topics.length).to.eq(3); + expect(receipt.logs[0].topics[0]).to.eq(SELECTORS.logApprove); + + let approvals = (await context.polkadotApi.query.localAssets.approvals( + assetId, + ALITH, + BALTATHAR + )) as any; + + expect(approvals.unwrap().amount.eq(new BN(1000))).to.equal(true); + // We are gonna spend 1000 from alith to send it to charleth + data = iFace.encodeFunctionData( + // action + "transferFrom_delegate", + [ALITH, CHARLETH, 1000] + ); + + tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: data, + }); + + block = await context.createBlock({ + transactions: [tx], + }); + receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.logs.length).to.eq(1); + expect(receipt.logs[0].address).to.eq(contractInstanceAddress); + expect(receipt.logs[0].topics.length).to.eq(3); + expect(receipt.logs[0].topics[0]).to.eq(SELECTORS.logTransfer); + expect(receipt.status).to.equal(true); + + // Approve amount is null now + approvals = (await context.polkadotApi.query.localAssets.approvals( + assetId, + ALITH, + BALTATHAR + )) as any; + expect(approvals.isNone).to.eq(true); + + // Charleth balance is 1000 + let charletBalance = (await context.polkadotApi.query.localAssets.account( + assetId, + CHARLETH + )) as any; + expect(charletBalance.unwrap()["balance"].eq(new BN(1000))).to.equal(true); + }); +}); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress, contractInstanceAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, sudoAccount.address, 100000000000000) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + contractInstanceAddress = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + // set asset address + let setAddressData = iFace.encodeFunctionData( + // action + "set_address_interface", + [context.web3.utils.toChecksumAddress(assetAddress)] + ); + + // We need this because the asset addres is random, + // so we need a way to correctly reference it in the contract + let setDataTx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: setAddressData, + }); + + await context.createBlock({ + transactions: [setDataTx], + }); + }); + it("allows to transfer through delegateCall", async function () { + // Create approval + let data = iFace.encodeFunctionData( + // action + "transfer_delegate", + [BALTATHAR, 1000] + ); + + let tx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: data, + }); + + let block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + expect(receipt.status).to.equal(true); + + // Baltathar balance is 1000 + let baltatharBalance = (await context.polkadotApi.query.localAssets.account( + assetId, + BALTATHAR + )) as any; + expect(baltatharBalance.unwrap()["balance"].eq(new BN(1000))).to.equal(true); + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes("Precompiles - Assets-ERC20 Wasm", (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress, contractInstanceAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + contractInstanceAddress = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + + // before we mint asset, since these are non-sufficient, we need to transfer native balance + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.balances.transfer(contractInstanceAddress, 1000) + ); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, contractInstanceAddress, 100000000000000) + ); + // set asset address + let setAddressData = iFace.encodeFunctionData( + // action + "set_address_interface", + [context.web3.utils.toChecksumAddress(assetAddress)] + ); + + // We need this because the asset addres is random, + // so we need a way to correctly reference it in the contract + let setDataTx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: setAddressData, + }); + + await context.createBlock({ + transactions: [setDataTx], + }); + }); + it("allows to approve transfer and use transferFrom from contract calls", async function () { + // Create approval + let data = iFace.encodeFunctionData( + // action + "approve", + [BALTATHAR, 1000] + ); + + const tx_call = await customWeb3Request(context.web3, "eth_call", [ + { + from: ALITH, + value: "0x0", + gas: "0x10000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: data, + }, + ]); + + let tx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: data, + }); + + let block = await context.createBlock({ + transactions: [tx], + }); + + let receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + expect(receipt.logs.length).to.eq(1); + expect(receipt.logs[0].address.toLowerCase()).to.eq(assetAddress); + expect(receipt.logs[0].topics.length).to.eq(3); + expect(receipt.logs[0].topics[0]).to.eq(SELECTORS.logApprove); + + let approvals = (await context.polkadotApi.query.localAssets.approvals( + assetId, + contractInstanceAddress, + BALTATHAR + )) as any; + + expect(approvals.unwrap().amount.eq(new BN(1000))).to.equal(true); + // We are gonna spend 1000 from contractInstanceAddress to send it to charleth + // Since this is a regular call, it will take contractInstanceAddress as msg.sender + // thus from & to will be the same, and approval wont be touched + data = iFace.encodeFunctionData( + // action + "transferFrom", + [contractInstanceAddress, CHARLETH, 1000] + ); + + tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: data, + }); + block = await context.createBlock({ + transactions: [tx], + }); + receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + expect(receipt.logs.length).to.eq(1); + expect(receipt.logs[0].address.toLowerCase()).to.eq(assetAddress); + expect(receipt.logs[0].topics.length).to.eq(3); + expect(receipt.logs[0].topics[0]).to.eq(SELECTORS.logTransfer); + expect(receipt.status).to.equal(true); + + // approvals are untouched + approvals = (await context.polkadotApi.query.localAssets.approvals( + assetId, + contractInstanceAddress, + BALTATHAR + )) as any; + expect(approvals.unwrap().amount.eq(new BN(1000))).to.equal(true); + + // this time we call directly from Baltathar the ERC20 contract + tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + block = await context.createBlock({ + transactions: [tx], + }); + receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + expect(receipt.logs.length).to.eq(1); + expect(receipt.logs[0].address.toLowerCase()).to.eq(assetAddress); + expect(receipt.logs[0].topics.length).to.eq(3); + expect(receipt.logs[0].topics[0]).to.eq(SELECTORS.logTransfer); + expect(receipt.status).to.equal(true); + + // Approve amount is null now + approvals = (await context.polkadotApi.query.localAssets.approvals( + assetId, + contractInstanceAddress, + BALTATHAR + )) as any; + expect(approvals.isNone).to.eq(true); + + // Charleth balance is 2000 + let charletBalance = (await context.polkadotApi.query.localAssets.account( + assetId, + CHARLETH + )) as any; + expect(charletBalance.unwrap()["balance"].eq(new BN(2000))).to.equal(true); + }); +}); + +describeDevMoonbeamAllEthTxTypes("Precompiles - Assets-ERC20 Wasm", (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress, contractInstanceAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, sudoAccount.address, 100000000000000) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + contractInstanceAddress = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + // set asset address + let setAddressData = iFace.encodeFunctionData( + // action + "set_address_interface", + [context.web3.utils.toChecksumAddress(assetAddress)] + ); + + // We need this because the asset addres is random, + // so we need a way to correctly reference it in the contract + let setDataTx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: setAddressData, + }); + + await context.createBlock({ + transactions: [setDataTx], + }); + }); + it("Bob approves contract and use transferFrom from contract calls", async function () { + // Create approval + let data = iFace.encodeFunctionData( + // action + "approve", + [contractInstanceAddress, 1000] + ); + + let tx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + let block = await context.createBlock({ + transactions: [tx], + }); + + let receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + expect(receipt.logs.length).to.eq(1); + expect(receipt.logs[0].address.toLowerCase()).to.eq(assetAddress); + expect(receipt.logs[0].topics.length).to.eq(3); + expect(receipt.logs[0].topics[0]).to.eq(SELECTORS.logApprove); + + let approvals = (await context.polkadotApi.query.localAssets.approvals( + assetId, + ALITH, + contractInstanceAddress + )) as any; + + expect(approvals.unwrap().amount.eq(new BN(1000))).to.equal(true); + // We are gonna spend 1000 from ALITH to send it to charleth from contract address + // even if Bob calls, msg.sender will become the contract with regular calls + data = iFace.encodeFunctionData( + // action + "transferFrom", + [ALITH, CHARLETH, 1000] + ); + + tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: data, + }); + block = await context.createBlock({ + transactions: [tx], + }); + receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + expect(receipt.logs.length).to.eq(1); + expect(receipt.logs[0].address.toLowerCase()).to.eq(assetAddress); + expect(receipt.logs[0].topics.length).to.eq(3); + expect(receipt.logs[0].topics[0]).to.eq(SELECTORS.logTransfer); + expect(receipt.status).to.equal(true); + + // Approve amount is null now + approvals = (await context.polkadotApi.query.localAssets.approvals( + assetId, + ALITH, + contractInstanceAddress + )) as any; + expect(approvals.isNone).to.eq(true); + + // Charleth balance is 1000 + let charletBalance = (await context.polkadotApi.query.localAssets.account( + assetId, + CHARLETH + )) as any; + expect(charletBalance.unwrap()["balance"].eq(new BN(1000))).to.equal(true); + }); +}); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress, contractInstanceAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + contractInstanceAddress = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + + // before we mint asset, since these are non-sufficient, we need to transfer native balance + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.balances.transfer(contractInstanceAddress, 1000) + ); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, contractInstanceAddress, 100000000000000) + ); + // set asset address + let setAddressData = iFace.encodeFunctionData( + // action + "set_address_interface", + [context.web3.utils.toChecksumAddress(assetAddress)] + ); + + // We need this because the asset addres is random, + // so we need a way to correctly reference it in the contract + let setDataTx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: setAddressData, + }); + + await context.createBlock({ + transactions: [setDataTx], + }); + }); + it("allows to transfer through call from SC ", async function () { + // Create approval + let data = iFace.encodeFunctionData( + // action + "transfer", + [BALTATHAR, 1000] + ); + + let tx = await createTransaction(context, { + from: ALITH, + privateKey: ALITH_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: contractInstanceAddress, + data: data, + }); + + let block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + expect(receipt.status).to.equal(true); + + // Baltathar balance is 1000 + let baltatharBalance = (await context.polkadotApi.query.localAssets.account( + assetId, + BALTATHAR + )) as any; + expect(baltatharBalance.unwrap()["balance"].eq(new BN(1000))).to.equal(true); + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to mint", async function () { + let data = iFace.encodeFunctionData( + // action + "mint", + [BALTATHAR, 1000] + ); + + const tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + const block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + expect(receipt.logs.length).to.eq(1); + expect(receipt.logs[0].address.toLowerCase()).to.eq(assetAddress); + expect(receipt.logs[0].topics.length).to.eq(3); + expect(receipt.logs[0].topics[0]).to.eq(SELECTORS.logTransfer); + + let baltatharBalance = (await context.polkadotApi.query.localAssets.account( + assetId, + BALTATHAR + )) as any; + + expect(baltatharBalance.unwrap()["balance"].eq(new BN(1000))).to.equal(true); + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, sudoAccount.address, 100000000000000) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to burn", async function () { + let data = iFace.encodeFunctionData( + // action + "burn", + [ALITH, 1000000000000] + ); + + const tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + const block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + expect(receipt.logs.length).to.eq(1); + expect(receipt.logs[0].address.toLowerCase()).to.eq(assetAddress); + expect(receipt.logs[0].topics.length).to.eq(3); + expect(receipt.logs[0].topics[0]).to.eq(SELECTORS.logTransfer); + + let alithBalance = (await context.polkadotApi.query.localAssets.account( + assetId, + ALITH + )) as any; + + expect(alithBalance.unwrap()["balance"].eq(new BN(99000000000000))).to.equal(true); + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, sudoAccount.address, 100000000000000) + ); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to freeze account", async function () { + let data = iFace.encodeFunctionData( + // action + "freeze", + [ALITH] + ); + + const tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + const block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + + let alithFrozen = (await context.polkadotApi.query.localAssets.account( + assetId, + ALITH + )) as any; + + expect(alithFrozen.unwrap()["isFrozen"].toHuman()).to.be.true; + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + // mint asset + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.mint(assetId, sudoAccount.address, 100000000000000) + ); + + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.freeze(assetId, sudoAccount.address) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to thaw account", async function () { + let data = iFace.encodeFunctionData( + // action + "thaw", + [ALITH] + ); + + const tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + const block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + + let baltatharFrozen = (await context.polkadotApi.query.localAssets.account( + assetId, + ALITH + )) as any; + + expect(baltatharFrozen.unwrap()["isFrozen"].toHuman()).to.be.false; + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.freeze(assetId, sudoAccount.address) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to freeze an asset", async function () { + let data = iFace.encodeFunctionData( + // action + "freeze_asset" + ); + + const tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + const block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + + const registeredAsset = ( + (await context.polkadotApi.query.localAssets.asset(assetId)) as any + ).unwrap(); + + expect(registeredAsset.isFrozen.toHuman()).to.be.true; + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.freezeAsset(assetId) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to thaw an asset", async function () { + let data = iFace.encodeFunctionData( + // action + "thaw_asset" + ); + + const tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + const block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + + const registeredAsset = ( + (await context.polkadotApi.query.localAssets.asset(assetId)) as any + ).unwrap(); + + expect(registeredAsset.isFrozen.toHuman()).to.be.false; + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to transfer ownership", async function () { + let data = iFace.encodeFunctionData( + // action + "transfer_ownership", + [ALITH] + ); + + const tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + const block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + + const registeredAsset = ( + (await context.polkadotApi.query.localAssets.asset(assetId)) as any + ).unwrap(); + + expect(registeredAsset.owner.toHex()).to.eq(ALITH.toLowerCase()); + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to set team", async function () { + let data = iFace.encodeFunctionData( + // action + "set_team", + [ALITH, ALITH, ALITH] + ); + + const tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + const block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + + const registeredAsset = ( + (await context.polkadotApi.query.localAssets.asset(assetId)) as any + ).unwrap(); + + expect(registeredAsset.admin.toHex()).to.eq(ALITH.toLowerCase()); + expect(registeredAsset.freezer.toHex()).to.eq(ALITH.toLowerCase()); + expect(registeredAsset.issuer.toHex()).to.eq(ALITH.toLowerCase()); + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to set metadata", async function () { + let data = iFace.encodeFunctionData( + // action + "set_metadata", + ["Local", "LOC", 12] + ); + + const tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + const block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + + const metadata = (await context.polkadotApi.query.localAssets.metadata(assetId)) as any; + + expect(u8aToString(metadata.name)).to.eq("Local"); + expect(u8aToString(metadata.symbol)).to.eq("LOC"); + expect(metadata.decimals.toString()).to.eq("12"); + }); + }, + true +); + +describeDevMoonbeamAllEthTxTypes( + "Precompiles - Assets-ERC20 Wasm", + (context) => { + let sudoAccount, baltatharAccount, assetId, iFace, assetAddress; + before("Setup contract and mock balance", async () => { + const keyring = new Keyring({ type: "ethereum" }); + sudoAccount = await keyring.addFromUri(ALITH_PRIV_KEY, null, "ethereum"); + baltatharAccount = await keyring.addFromUri(BALTATHAR_PRIV_KEY, null, "ethereum"); + + // registerAsset + const { events: eventsRegister } = await createBlockWithExtrinsic( + context, + sudoAccount, + context.polkadotApi.tx.sudo.sudo( + context.polkadotApi.tx.assetManager.registerLocalAsset( + baltatharAccount.address, + baltatharAccount.address, + true, + new BN(1) + ) + ) + ); + + // Look for assetId in events + eventsRegister.forEach((e) => { + if (e.section.toString() === "assetManager") { + assetId = e.data[0].toHex(); + } + }); + assetId = assetId.replace(/,/g, ""); + + assetAddress = u8aToHex(new Uint8Array([...hexToU8a("0xFFFFFFFE"), ...hexToU8a(assetId)])); + + // Set metadata + await createBlockWithExtrinsic( + context, + baltatharAccount, + context.polkadotApi.tx.localAssets.setMetadata(assetId, "Local", "Local", new BN(12)) + ); + + const contractData = await getCompiled("LocalAssetExtendedErc20Instance"); + iFace = new ethers.utils.Interface(contractData.contract.abi); + const { contract, rawTx } = await createContract(context, "LocalAssetExtendedErc20Instance"); + const address = contract.options.address; + await context.createBlock({ transactions: [rawTx] }); + }); + it("allows to clear metadata", async function () { + let data = iFace.encodeFunctionData( + // action + "clear_metadata", + [] + ); + + const tx = await createTransaction(context, { + from: BALTATHAR, + privateKey: BALTATHAR_PRIV_KEY, + value: "0x0", + gas: "0x200000", + gasPrice: GAS_PRICE, + to: assetAddress, + data: data, + }); + + const block = await context.createBlock({ + transactions: [tx], + }); + + const receipt = await context.web3.eth.getTransactionReceipt(block.txResults[0].result); + + expect(receipt.status).to.equal(true); + + const metadata = (await context.polkadotApi.query.localAssets.metadata(assetId)) as any; + + expect(u8aToString(metadata.name)).to.eq(""); + expect(u8aToString(metadata.symbol)).to.eq(""); + expect(metadata.decimals.toString()).to.eq("0"); + }); + }, + true +); diff --git a/tests/tests/test-precompile/test-precompile-xcm-transactor.ts b/tests/tests/test-precompile/test-precompile-xcm-transactor.ts index 6acb799cea..11ac3e63c1 100644 --- a/tests/tests/test-precompile/test-precompile-xcm-transactor.ts +++ b/tests/tests/test-precompile/test-precompile-xcm-transactor.ts @@ -19,7 +19,7 @@ async function mockAssetBalance(context, assetBalance, assetDetails, sudoAccount // Register the asset await context.polkadotApi.tx.sudo .sudo( - context.polkadotApi.tx.assetManager.registerAsset( + context.polkadotApi.tx.assetManager.registerForeignAsset( sourceLocationRelayAssetType, relayAssetMetadata, new BN(1),