From 0b9b3e14b1f5814ec552042cec14eabaa2e1cd87 Mon Sep 17 00:00:00 2001 From: Andrei Vlad Birgaoanu <99738872+andreivladbrg@users.noreply.github.com> Date: Wed, 18 Oct 2023 15:46:46 +0300 Subject: [PATCH] Remove the ability to cancel for recipients (#710) * feat: remove ability to cancel for recipient feat: remove sender's hook test: update tests accordingly * feat: emit asset in cancel and withdraw events refactor: remove recipient from cancel event test: update tests accordingly test: update precompiles bytecode * chore: update gas snapshot * test: update Precompiles bytecode * docs: include recipient disable to cancel in changelog * refactor: add "recipient" in cancel event docs: refine explanatory comments refactor: reorder parameters in events * test: update Precompiles bytecode * chore: add explantory comment --------- Co-authored-by: Paul Razvan Berg --- .gas-snapshot | 648 +++++++++--------- CHANGELOG.md | 1 + shell/prepare-artifacts.sh | 1 - src/SablierV2LockupDynamic.sol | 52 +- src/SablierV2LockupLinear.sol | 52 +- src/abstracts/SablierV2Lockup.sol | 7 +- src/interfaces/ISablierV2Lockup.sol | 9 +- .../hooks/ISablierV2LockupSender.sol | 27 - test/Base.t.sol | 4 - test/fork/LockupDynamic.t.sol | 3 +- test/fork/LockupLinear.t.sol | 3 +- test/integration/Integration.t.sol | 6 - .../concrete/lockup/burn/burn.t.sol | 2 + .../cancel-multiple/cancelMultiple.t.sol | 57 +- .../cancel-multiple/cancelMultiple.tree | 22 +- .../concrete/lockup/cancel/cancel.t.sol | 221 +----- .../concrete/lockup/cancel/cancel.tree | 89 +-- .../withdrawMaxAndTransfer.t.sol | 7 +- .../lockup/withdraw-max/withdrawMax.t.sol | 10 +- .../withdraw-multiple/withdrawMultiple.t.sol | 23 +- .../concrete/lockup/withdraw/withdraw.t.sol | 14 +- .../nft-descriptor/generateAccentColor.t.sol | 2 +- .../fuzz/lockup-dynamic/withdraw.t.sol | 2 +- test/integration/fuzz/lockup/cancel.t.sol | 70 +- .../fuzz/lockup/cancelMultiple.t.sol | 2 + test/integration/fuzz/lockup/withdraw.t.sol | 6 +- .../integration/fuzz/lockup/withdrawMax.t.sol | 8 +- .../fuzz/lockup/withdrawMaxAndTransfer.t.sol | 7 +- .../fuzz/lockup/withdrawMultiple.t.sol | 4 +- test/integration/shared/lockup/cancel.t.sol | 28 +- .../shared/lockup/cancelMultiple.t.sol | 2 +- test/mocks/hooks/GoodSender.sol | 21 - test/mocks/hooks/ReentrantSender.sol | 22 - test/mocks/hooks/RevertingSender.sol | 22 - test/utils/Events.sol | 5 +- test/utils/Precompiles.sol | 4 +- 36 files changed, 502 insertions(+), 961 deletions(-) delete mode 100644 src/interfaces/hooks/ISablierV2LockupSender.sol delete mode 100644 test/mocks/hooks/GoodSender.sol delete mode 100644 test/mocks/hooks/ReentrantSender.sol delete mode 100644 test/mocks/hooks/RevertingSender.sol diff --git a/.gas-snapshot b/.gas-snapshot index 31ba7f609..4bf009e11 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,425 +1,413 @@ -Burn_LockupDynamic_Integration_Concrete_Test:test_Burn_CallerApprovedOperator() (gas: 87474) -Burn_LockupDynamic_Integration_Concrete_Test:test_Burn_CallerNFTOwner() (gas: 78058) -Burn_LockupDynamic_Integration_Concrete_Test:test_Burn_NonTransferableNFT() (gas: 78067) -Burn_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_NFTDoesNotExist() (gas: 79272) +Burn_LockupDynamic_Integration_Concrete_Test:test_Burn_CallerApprovedOperator() (gas: 87800) +Burn_LockupDynamic_Integration_Concrete_Test:test_Burn_CallerNFTOwner() (gas: 78384) +Burn_LockupDynamic_Integration_Concrete_Test:test_Burn_NonTransferableNFT() (gas: 78393) +Burn_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_NFTDoesNotExist() (gas: 79598) Burn_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11325) -Burn_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 86942) -Burn_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusPending() (gas: 14284) -Burn_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusSettled() (gas: 19520) -Burn_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusStreaming() (gas: 19556) -Burn_LockupLinear_Integration_Concrete_Test:test_Burn_CallerApprovedOperator() (gas: 87711) -Burn_LockupLinear_Integration_Concrete_Test:test_Burn_CallerNFTOwner() (gas: 78284) -Burn_LockupLinear_Integration_Concrete_Test:test_Burn_NonTransferableNFT() (gas: 78293) -Burn_LockupLinear_Integration_Concrete_Test:test_RevertGiven_NFTDoesNotExist() (gas: 79480) +Burn_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 90036) +Burn_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusPending() (gas: 14289) +Burn_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusSettled() (gas: 19525) +Burn_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusStreaming() (gas: 19561) +Burn_LockupLinear_Integration_Concrete_Test:test_Burn_CallerApprovedOperator() (gas: 88034) +Burn_LockupLinear_Integration_Concrete_Test:test_Burn_CallerNFTOwner() (gas: 78607) +Burn_LockupLinear_Integration_Concrete_Test:test_Burn_NonTransferableNFT() (gas: 78616) +Burn_LockupLinear_Integration_Concrete_Test:test_RevertGiven_NFTDoesNotExist() (gas: 79803) Burn_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11311) -Burn_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 77650) -Burn_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusPending() (gas: 14270) -Burn_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusSettled() (gas: 19506) -Burn_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusStreaming() (gas: 19542) -CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_CancelMultiple() (gas: 831368) -CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_CancelMultiple_ArrayCountZero() (gas: 6293) -CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_AllStreamsCold() (gas: 32410) -CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_AllStreamsNotCancelable() (gas: 866449) -CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_OnlyNull() (gas: 12340) -CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_SomeNull() (gas: 78328) -CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_SomeStreamsCold() (gas: 340997) -CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_SomeStreamsNotCancelable() (gas: 950201) -CancelMultiple_LockupDynamic_Integration_Fuzz_Test:testFuzz_CancelMultiple(uint256,uint40) (runs: 50, μ: 1201756, ~: 1206371) -CancelMultiple_LockupLinear_Integration_Concrete_Test:test_CancelMultiple() (gas: 563445) -CancelMultiple_LockupLinear_Integration_Concrete_Test:test_CancelMultiple_ArrayCountZero() (gas: 6313) -CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_AllStreamsCold() (gas: 32558) -CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_AllStreamsNotCancelable() (gas: 579829) -CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_OnlyNull() (gas: 12366) -CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_SomeNull() (gas: 78359) -CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_SomeStreamsCold() (gas: 245143) -CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_SomeStreamsNotCancelable() (gas: 661591) -CancelMultiple_LockupLinear_Integration_Fuzz_Test:testFuzz_CancelMultiple(uint256,uint40) (runs: 50, μ: 801956, ~: 802941) -Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_CallerRecipient() (gas: 391618) -Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_CallerRecipient_SenderDoesNotImplementHook() (gas: 377197) -Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_CallerRecipient_SenderNotContract() (gas: 100017) -Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_CallerRecipient_SenderReentrancy() (gas: 379308) -Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_CallerRecipient_SenderReverts() (gas: 377695) -Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_CallerSender() (gas: 386708) -Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_CallerSender_RecipientDoesNotImplementHook() (gas: 372228) -Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_CallerSender_RecipientNotContract() (gas: 97299) -Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_CallerSender_RecipientReentrancy() (gas: 374398) -Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_CallerSender_RecipientReverts() (gas: 372763) -Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_StatusPending() (gas: 76399) -Cancel_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11299) -Cancel_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 87330) -Cancel_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusDepleted() (gas: 65550) -Cancel_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusSettled() (gas: 29268) -Cancel_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamNotCancelable() (gas: 261722) -Cancel_LockupDynamic_Integration_Fuzz_Test:testFuzz_Cancel_CallerRecipient(uint256,uint128) (runs: 50, μ: 434849, ~: 435842) -Cancel_LockupDynamic_Integration_Fuzz_Test:testFuzz_Cancel_CallerSender(uint256,uint128) (runs: 50, μ: 453227, ~: 455450) -Cancel_LockupDynamic_Integration_Fuzz_Test:testFuzz_Cancel_StatusPending(uint256) (runs: 50, μ: 76963, ~: 77115) -Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_CallerRecipient() (gas: 274846) -Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_CallerRecipient_SenderDoesNotImplementHook() (gas: 260354) -Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_CallerRecipient_SenderNotContract() (gas: 80371) -Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_CallerRecipient_SenderReentrancy() (gas: 262451) -Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_CallerRecipient_SenderReverts() (gas: 260852) -Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_CallerSender() (gas: 269878) -Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_CallerSender_RecipientDoesNotImplementHook() (gas: 255372) -Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_CallerSender_RecipientNotContract() (gas: 77649) -Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_CallerSender_RecipientReentrancy() (gas: 257528) -Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_CallerSender_RecipientReverts() (gas: 255907) -Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_StatusPending() (gas: 76446) -Cancel_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11285) -Cancel_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 78038) -Cancel_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusDepleted() (gas: 65769) -Cancel_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusSettled() (gas: 29373) -Cancel_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamNotCancelable() (gas: 185888) -Cancel_LockupLinear_Integration_Fuzz_Test:testFuzz_Cancel_CallerRecipient(uint256,uint128) (runs: 50, μ: 291315, ~: 291257) -Cancel_LockupLinear_Integration_Fuzz_Test:testFuzz_Cancel_CallerSender(uint256,uint128) (runs: 50, μ: 310015, ~: 310670) -Cancel_LockupLinear_Integration_Fuzz_Test:testFuzz_Cancel_StatusPending(uint256) (runs: 50, μ: 76941, ~: 77016) -ClaimProtocolRevenues_LockupDynamic_Integration_Concrete_Test:test_ClaimProtocolRevenues() (gas: 319860) -ClaimProtocolRevenues_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_ProtocolRevenuesZero() (gas: 18973) -ClaimProtocolRevenues_LockupLinear_Integration_Concrete_Test:test_ClaimProtocolRevenues() (gas: 246630) -ClaimProtocolRevenues_LockupLinear_Integration_Concrete_Test:test_RevertGiven_ProtocolRevenuesZero() (gas: 18981) -Constructor_LockupDynamic_Integration_Concrete_Test:test_Constructor() (gas: 5410963) -Constructor_LockupLinear_Integration_Concrete_Test:test_Constructor() (gas: 4216694) -CreateWithDeltas_LockupDynamic_Integration_Concrete_Test:test_CreateWithDeltas() (gas: 380732) -CreateWithDeltas_LockupDynamic_Integration_Fuzz_Test:testFuzz_CreateWithDeltas((uint128,uint64,uint40)[]) (runs: 50, μ: 4100052, ~: 3555804) -CreateWithDurations_LockupLinear_Integration_Concrete_Test:test_CreateWithDurations() (gas: 287745) -CreateWithDurations_LockupLinear_Integration_Fuzz_Test:testFuzz_CreateWithDurations((uint40,uint40)) (runs: 50, μ: 286647, ~: 286702) -CreateWithMilestones_LockupDynamic_Integration_Concrete_Test:test_CreateWithMilestones() (gas: 370947) -CreateWithMilestones_LockupDynamic_Integration_Concrete_Test:test_CreateWithMilestones_AssetMissingReturnValue() (gas: 377735) +Burn_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 80712) +Burn_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusPending() (gas: 14275) +Burn_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusSettled() (gas: 19511) +Burn_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusStreaming() (gas: 19547) +CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_CancelMultiple() (gas: 831114) +CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_CancelMultiple_ArrayCountZero() (gas: 6265) +CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_AllStreamsCold() (gas: 32340) +CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_AllStreamsNotCancelable() (gas: 859532) +CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_OnlyNull() (gas: 12356) +CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_SomeNull() (gas: 78320) +CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_SomeStreamsCold() (gas: 341059) +CancelMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_SomeStreamsNotCancelable() (gas: 945583) +CancelMultiple_LockupDynamic_Integration_Fuzz_Test:testFuzz_CancelMultiple(uint256,uint40) (runs: 50, μ: 1194589, ~: 1198935) +CancelMultiple_LockupLinear_Integration_Concrete_Test:test_CancelMultiple() (gas: 562805) +CancelMultiple_LockupLinear_Integration_Concrete_Test:test_CancelMultiple_ArrayCountZero() (gas: 6288) +CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_AllStreamsCold() (gas: 32482) +CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_AllStreamsNotCancelable() (gas: 572852) +CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_OnlyNull() (gas: 12373) +CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_SomeNull() (gas: 78250) +CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_SomeStreamsCold() (gas: 245095) +CancelMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_SomeStreamsNotCancelable() (gas: 656729) +CancelMultiple_LockupLinear_Integration_Fuzz_Test:testFuzz_CancelMultiple(uint256,uint40) (runs: 50, μ: 794341, ~: 795547) +Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel() (gas: 385726) +Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_RecipientDoesNotImplementHook() (gas: 371244) +Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_RecipientNotContract() (gas: 96900) +Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_RecipientReentrancy() (gas: 373435) +Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_RecipientReverts() (gas: 371811) +Cancel_LockupDynamic_Integration_Concrete_Test:test_Cancel_StatusPending() (gas: 76125) +Cancel_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11321) +Cancel_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 87122) +Cancel_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusDepleted() (gas: 68253) +Cancel_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusSettled() (gas: 27019) +Cancel_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamNotCancelable() (gas: 261520) +Cancel_LockupDynamic_Integration_Fuzz_Test:testFuzz_Cancel(uint256,uint128) (runs: 50, μ: 453354, ~: 454739) +Cancel_LockupDynamic_Integration_Fuzz_Test:testFuzz_Cancel_StatusPending(uint256) (runs: 50, μ: 76673, ~: 76852) +Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel() (gas: 268892) +Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_RecipientDoesNotImplementHook() (gas: 254340) +Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_RecipientNotContract() (gas: 77222) +Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_RecipientReentrancy() (gas: 256520) +Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_RecipientReverts() (gas: 254907) +Cancel_LockupLinear_Integration_Concrete_Test:test_Cancel_StatusPending() (gas: 76140) +Cancel_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11310) +Cancel_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 77801) +Cancel_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusDepleted() (gas: 68472) +Cancel_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusSettled() (gas: 27130) +Cancel_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamNotCancelable() (gas: 185680) +Cancel_LockupLinear_Integration_Fuzz_Test:testFuzz_Cancel(uint256,uint128) (runs: 50, μ: 309781, ~: 309696) +Cancel_LockupLinear_Integration_Fuzz_Test:testFuzz_Cancel_StatusPending(uint256) (runs: 50, μ: 76674, ~: 76867) +ClaimProtocolRevenues_LockupDynamic_Integration_Concrete_Test:test_ClaimProtocolRevenues() (gas: 319731) +ClaimProtocolRevenues_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_ProtocolRevenuesZero() (gas: 18907) +ClaimProtocolRevenues_LockupLinear_Integration_Concrete_Test:test_ClaimProtocolRevenues() (gas: 246489) +ClaimProtocolRevenues_LockupLinear_Integration_Concrete_Test:test_RevertGiven_ProtocolRevenuesZero() (gas: 18915) +Constructor_LockupDynamic_Integration_Concrete_Test:test_Constructor() (gas: 5383879) +Constructor_LockupLinear_Integration_Concrete_Test:test_Constructor() (gas: 4189626) +CreateWithDeltas_LockupDynamic_Integration_Concrete_Test:test_CreateWithDeltas() (gas: 380624) +CreateWithDeltas_LockupDynamic_Integration_Fuzz_Test:testFuzz_CreateWithDeltas((uint128,uint64,uint40)[]) (runs: 50, μ: 4099444, ~: 3556313) +CreateWithDurations_LockupLinear_Integration_Concrete_Test:test_CreateWithDurations() (gas: 287625) +CreateWithDurations_LockupLinear_Integration_Fuzz_Test:testFuzz_CreateWithDurations((uint40,uint40)) (runs: 50, μ: 286496, ~: 286576) +CreateWithMilestones_LockupDynamic_Integration_Concrete_Test:test_CreateWithMilestones() (gas: 370971) +CreateWithMilestones_LockupDynamic_Integration_Concrete_Test:test_CreateWithMilestones_AssetMissingReturnValue() (gas: 377759) CreateWithMilestones_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_EndTimeNotInTheFuture() (gas: 47540) CreateWithMilestones_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_ProtocolFeeTooHigh() (gas: 58079) -CreateWithMilestones_LockupDynamic_Integration_Fuzz_Test:testFuzz_CreateWithMilestones(address,(address,uint40,bool,bool,address,uint128,address,(address,uint256),(uint128,uint64,uint40)[]),uint256) (runs: 50, μ: 4646762, ~: 4503477) -CreateWithRange_LockupLinear_Integration_Concrete_Test:test_CreateWithRange() (gas: 283011) -CreateWithRange_LockupLinear_Integration_Concrete_Test:test_CreateWithRange_AssetMissingReturnValue() (gas: 289778) +CreateWithMilestones_LockupDynamic_Integration_Fuzz_Test:testFuzz_CreateWithMilestones(address,(address,uint40,bool,bool,address,uint128,address,(address,uint256),(uint128,uint64,uint40)[]),uint256) (runs: 50, μ: 4697705, ~: 4643584) +CreateWithRange_LockupLinear_Integration_Concrete_Test:test_CreateWithRange() (gas: 283023) +CreateWithRange_LockupLinear_Integration_Concrete_Test:test_CreateWithRange_AssetMissingReturnValue() (gas: 289790) CreateWithRange_LockupLinear_Integration_Concrete_Test:test_RevertGiven_EndTimeNotInTheFuture() (gas: 41154) CreateWithRange_LockupLinear_Integration_Concrete_Test:test_RevertGiven_ProtocolFeeTooHigh() (gas: 51749) -CreateWithRange_LockupLinear_Integration_Fuzz_Test:testFuzz_CreateWithRange(address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)),uint256) (runs: 50, μ: 370169, ~: 370511) +CreateWithRange_LockupLinear_Integration_Fuzz_Test:testFuzz_CreateWithRange(address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)),uint256) (runs: 50, μ: 370443, ~: 370634) FlashFee_Integration_Concrete_Test:test_FlashFee() (gas: 50968) FlashFee_Integration_Concrete_Test:test_RevertGiven_AssetNotFlashLoanable() (gas: 18626) -FlashFee_Integration_Fuzz_Test:testFuzz_FlashFee(uint256,uint256) (runs: 50, μ: 51839, ~: 52081) +FlashFee_Integration_Fuzz_Test:testFuzz_FlashFee(uint256,uint256) (runs: 50, μ: 51814, ~: 52081) FlashLoanFunction_Integration_Concrete_Test:test_FlashLoan() (gas: 402140) FlashLoanFunction_Integration_Concrete_Test:test_RevertGiven_AssetNotFlashLoanable() (gas: 21603) -FlashLoanFunction_Integration_Fuzz_Test:testFuzz_FlashLoanFunction(uint256,uint128,bytes) (runs: 50, μ: 403410, ~: 407188) -GenerateAccentColor_Integration_Concrete_Test:test_GenerateAccentColor() (gas: 12968) -GetAsset_LockupDynamic_Integration_Concrete_Test:test_GetAsset() (gas: 307738) +FlashLoanFunction_Integration_Fuzz_Test:testFuzz_FlashLoanFunction(uint256,uint128,bytes) (runs: 50, μ: 403132, ~: 406851) +GenerateAccentColor_Integration_Concrete_Test:test_GenerateAccentColor() (gas: 13215) +GetAsset_LockupDynamic_Integration_Concrete_Test:test_GetAsset() (gas: 307762) GetAsset_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 12049) -GetAsset_LockupLinear_Integration_Concrete_Test:test_GetAsset() (gas: 234488) +GetAsset_LockupLinear_Integration_Concrete_Test:test_GetAsset() (gas: 234500) GetAsset_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 12035) -GetCliffTime_LockupLinear_Integration_Concrete_Test:test_GetCliffTime() (gas: 234972) +GetCliffTime_LockupLinear_Integration_Concrete_Test:test_GetCliffTime() (gas: 234984) GetCliffTime_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11392) -GetDepositedAmount_LockupDynamic_Integration_Concrete_Test:test_GetDepositedAmount() (gas: 310535) +GetDepositedAmount_LockupDynamic_Integration_Concrete_Test:test_GetDepositedAmount() (gas: 310559) GetDepositedAmount_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11682) -GetDepositedAmount_LockupLinear_Integration_Concrete_Test:test_GetDepositedAmount() (gas: 237259) +GetDepositedAmount_LockupLinear_Integration_Concrete_Test:test_GetDepositedAmount() (gas: 237271) GetDepositedAmount_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11678) -GetEndTime_LockupDynamic_Integration_Concrete_Test:test_GetEndTime() (gas: 310333) +GetEndTime_LockupDynamic_Integration_Concrete_Test:test_GetEndTime() (gas: 310357) GetEndTime_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11538) -GetEndTime_LockupLinear_Integration_Concrete_Test:test_GetEndTime() (gas: 237111) +GetEndTime_LockupLinear_Integration_Concrete_Test:test_GetEndTime() (gas: 237123) GetEndTime_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11546) -GetRange_LockupDynamic_Integration_Concrete_Test:test_GetRange() (gas: 309759) +GetRange_LockupDynamic_Integration_Concrete_Test:test_GetRange() (gas: 309783) GetRange_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 13125) -GetRange_LockupLinear_Integration_Concrete_Test:test_GetRange() (gas: 237329) +GetRange_LockupLinear_Integration_Concrete_Test:test_GetRange() (gas: 237341) GetRange_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 13308) GetRecipient_LockupDynamic_Integration_Concrete_Test:test_GetRecipient() (gas: 12585) -GetRecipient_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_NFTBurned() (gas: 72366) +GetRecipient_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_NFTBurned() (gas: 72692) GetRecipient_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 10989) GetRecipient_LockupLinear_Integration_Concrete_Test:test_GetRecipient() (gas: 12565) -GetRecipient_LockupLinear_Integration_Concrete_Test:test_RevertGiven_NFTBurned() (gas: 72592) +GetRecipient_LockupLinear_Integration_Concrete_Test:test_RevertGiven_NFTBurned() (gas: 72915) GetRecipient_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 10993) -GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StatusDepleted() (gas: 362872) -GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StatusPending() (gas: 332677) -GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StatusSettled() (gas: 337885) -GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StatusStreaming() (gas: 337899) -GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StreamHasBeenCanceled_StatusCanceled() (gas: 377267) -GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StreamHasBeenCanceled_StatusDepleted() (gas: 399131) +GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StatusDepleted() (gas: 363038) +GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StatusPending() (gas: 332701) +GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StatusSettled() (gas: 337909) +GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StatusStreaming() (gas: 337923) +GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StreamHasBeenCanceled_StatusCanceled() (gas: 377279) +GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_GetRefundedAmount_StreamHasBeenCanceled_StatusDepleted() (gas: 399285) GetRefundedAmount_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 12045) -GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StatusDepleted() (gas: 287867) -GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StatusPending() (gas: 257439) -GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StatusSettled() (gas: 262647) -GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StatusStreaming() (gas: 262661) -GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StreamHasBeenCanceled_StatusCanceled() (gas: 298747) -GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StreamHasBeenCanceled_StatusDepleted() (gas: 320600) +GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StatusDepleted() (gas: 288018) +GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StatusPending() (gas: 257451) +GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StatusSettled() (gas: 262659) +GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StatusStreaming() (gas: 262673) +GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StreamHasBeenCanceled_StatusCanceled() (gas: 298719) +GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_GetRefundedAmount_StreamHasBeenCanceled_StatusDepleted() (gas: 320711) GetRefundedAmount_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 12031) -GetSegments_LockupDynamic_Integration_Concrete_Test:test_GetSegments() (gas: 315237) +GetSegments_LockupDynamic_Integration_Concrete_Test:test_GetSegments() (gas: 315261) GetSegments_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 13758) -GetSender_LockupDynamic_Integration_Concrete_Test:test_GetSender() (gas: 307456) +GetSender_LockupDynamic_Integration_Concrete_Test:test_GetSender() (gas: 307480) GetSender_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11814) -GetSender_LockupLinear_Integration_Concrete_Test:test_GetSender() (gas: 234222) +GetSender_LockupLinear_Integration_Concrete_Test:test_GetSender() (gas: 234234) GetSender_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11816) -GetStartTime_LockupDynamic_Integration_Concrete_Test:test_GetStartTime() (gas: 310662) +GetStartTime_LockupDynamic_Integration_Concrete_Test:test_GetStartTime() (gas: 310686) GetStartTime_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11823) -GetStartTime_LockupLinear_Integration_Concrete_Test:test_GetStartTime() (gas: 237434) +GetStartTime_LockupLinear_Integration_Concrete_Test:test_GetStartTime() (gas: 237446) GetStartTime_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11831) -GetStream_LockupDynamic_Integration_Concrete_Test:test_GetStream() (gas: 278699) +GetStream_LockupDynamic_Integration_Concrete_Test:test_GetStream() (gas: 278723) GetStream_LockupDynamic_Integration_Concrete_Test:test_GetStream_StatusSettled() (gas: 52024) GetStream_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 15544) GetStream_LockupLinear_Integration_Concrete_Test:test_GetStream() (gas: 34920) GetStream_LockupLinear_Integration_Concrete_Test:test_GetStream_StatusSettled() (gas: 39431) GetStream_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 14299) -GetWithdrawnAmount_LockupDynamic_Integration_Concrete_Test:test_GetWithdrawnAmount() (gas: 384565) -GetWithdrawnAmount_LockupDynamic_Integration_Concrete_Test:test_GetWithdrawnAmount_NoPreviousWithdrawals() (gas: 335859) +GetWithdrawnAmount_LockupDynamic_Integration_Concrete_Test:test_GetWithdrawnAmount() (gas: 384891) +GetWithdrawnAmount_LockupDynamic_Integration_Concrete_Test:test_GetWithdrawnAmount_NoPreviousWithdrawals() (gas: 335883) GetWithdrawnAmount_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 12012) -GetWithdrawnAmount_LockupDynamic_Integration_Fuzz_Test:testFuzz_GetWithdrawnAmount(uint256,uint128) (runs: 50, μ: 387601, ~: 388165) -GetWithdrawnAmount_LockupDynamic_Integration_Fuzz_Test:testFuzz_GetWithdrawnAmount_NoPreviousWithdrawals(uint256) (runs: 50, μ: 337603, ~: 337783) -GetWithdrawnAmount_LockupLinear_Integration_Concrete_Test:test_GetWithdrawnAmount() (gas: 282047) -GetWithdrawnAmount_LockupLinear_Integration_Concrete_Test:test_GetWithdrawnAmount_NoPreviousWithdrawals() (gas: 262621) +GetWithdrawnAmount_LockupDynamic_Integration_Fuzz_Test:testFuzz_GetWithdrawnAmount(uint256,uint128) (runs: 50, μ: 388029, ~: 388565) +GetWithdrawnAmount_LockupDynamic_Integration_Fuzz_Test:testFuzz_GetWithdrawnAmount_NoPreviousWithdrawals(uint256) (runs: 50, μ: 337600, ~: 337807) +GetWithdrawnAmount_LockupLinear_Integration_Concrete_Test:test_GetWithdrawnAmount() (gas: 282382) +GetWithdrawnAmount_LockupLinear_Integration_Concrete_Test:test_GetWithdrawnAmount_NoPreviousWithdrawals() (gas: 262633) GetWithdrawnAmount_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11998) -GetWithdrawnAmount_LockupLinear_Integration_Fuzz_Test:testFuzz_GetWithdrawnAmount(uint256,uint128) (runs: 50, μ: 285233, ~: 285189) -GetWithdrawnAmount_LockupLinear_Integration_Fuzz_Test:testFuzz_GetWithdrawnAmount_NoPreviousWithdrawals(uint256) (runs: 50, μ: 264296, ~: 264259) -IsCancelable_LockupDynamic_Integration_Concrete_Test:test_IsCancelable() (gas: 515823) -IsCancelable_LockupDynamic_Integration_Concrete_Test:test_IsCancelable_Cold() (gas: 336082) -IsCancelable_LockupDynamic_Integration_Concrete_Test:test_IsCancelable_StreamCancelable() (gas: 327326) +GetWithdrawnAmount_LockupLinear_Integration_Fuzz_Test:testFuzz_GetWithdrawnAmount(uint256,uint128) (runs: 50, μ: 285546, ~: 285524) +GetWithdrawnAmount_LockupLinear_Integration_Fuzz_Test:testFuzz_GetWithdrawnAmount_NoPreviousWithdrawals(uint256) (runs: 50, μ: 264363, ~: 264557) +IsCancelable_LockupDynamic_Integration_Concrete_Test:test_IsCancelable() (gas: 515871) +IsCancelable_LockupDynamic_Integration_Concrete_Test:test_IsCancelable_Cold() (gas: 336106) +IsCancelable_LockupDynamic_Integration_Concrete_Test:test_IsCancelable_StreamCancelable() (gas: 327350) IsCancelable_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11239) -IsCancelable_LockupLinear_Integration_Concrete_Test:test_IsCancelable() (gas: 372821) -IsCancelable_LockupLinear_Integration_Concrete_Test:test_IsCancelable_Cold() (gas: 262996) -IsCancelable_LockupLinear_Integration_Concrete_Test:test_IsCancelable_StreamCancelable() (gas: 254123) +IsCancelable_LockupLinear_Integration_Concrete_Test:test_IsCancelable() (gas: 372845) +IsCancelable_LockupLinear_Integration_Concrete_Test:test_IsCancelable_Cold() (gas: 263008) +IsCancelable_LockupLinear_Integration_Concrete_Test:test_IsCancelable_StreamCancelable() (gas: 254135) IsCancelable_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11263) -IsCold_LockupDynamic_Integration_Concrete_Test:test_IsCold_StatusCanceled() (gas: 375998) -IsCold_LockupDynamic_Integration_Concrete_Test:test_IsCold_StatusDepleted() (gas: 362551) -IsCold_LockupDynamic_Integration_Concrete_Test:test_IsCold_StatusPending() (gas: 330616) -IsCold_LockupDynamic_Integration_Concrete_Test:test_IsCold_StatusSettled() (gas: 336386) -IsCold_LockupDynamic_Integration_Concrete_Test:test_IsCold_StatusStreaming() (gas: 352696) -IsCold_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11558) -IsCold_LockupLinear_Integration_Concrete_Test:test_IsCold_StatusCanceled() (gas: 297529) -IsCold_LockupLinear_Integration_Concrete_Test:test_IsCold_StatusDepleted() (gas: 287604) -IsCold_LockupLinear_Integration_Concrete_Test:test_IsCold_StatusPending() (gas: 257436) -IsCold_LockupLinear_Integration_Concrete_Test:test_IsCold_StatusSettled() (gas: 263318) -IsCold_LockupLinear_Integration_Concrete_Test:test_IsCold_StatusStreaming() (gas: 263853) -IsCold_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11601) -IsDepleted_LockupDynamic_Integration_Concrete_Test:test_IsDepleted() (gas: 361956) -IsDepleted_LockupDynamic_Integration_Concrete_Test:test_IsDepleted_StreamNotDepleted() (gas: 326750) +IsCold_LockupDynamic_Integration_Concrete_Test:test_IsCold_StatusCanceled() (gas: 375977) +IsCold_LockupDynamic_Integration_Concrete_Test:test_IsCold_StatusDepleted() (gas: 362684) +IsCold_LockupDynamic_Integration_Concrete_Test:test_IsCold_StatusPending() (gas: 330607) +IsCold_LockupDynamic_Integration_Concrete_Test:test_IsCold_StatusSettled() (gas: 336377) +IsCold_LockupDynamic_Integration_Concrete_Test:test_IsCold_StatusStreaming() (gas: 352687) +IsCold_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11525) +IsCold_LockupLinear_Integration_Concrete_Test:test_IsCold_StatusCanceled() (gas: 297468) +IsCold_LockupLinear_Integration_Concrete_Test:test_IsCold_StatusDepleted() (gas: 287722) +IsCold_LockupLinear_Integration_Concrete_Test:test_IsCold_StatusPending() (gas: 257415) +IsCold_LockupLinear_Integration_Concrete_Test:test_IsCold_StatusSettled() (gas: 263297) +IsCold_LockupLinear_Integration_Concrete_Test:test_IsCold_StatusStreaming() (gas: 263832) +IsCold_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11568) +IsDepleted_LockupDynamic_Integration_Concrete_Test:test_IsDepleted() (gas: 362122) +IsDepleted_LockupDynamic_Integration_Concrete_Test:test_IsDepleted_StreamNotDepleted() (gas: 326774) IsDepleted_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11191) -IsDepleted_LockupLinear_Integration_Concrete_Test:test_IsDepleted() (gas: 286971) -IsDepleted_LockupLinear_Integration_Concrete_Test:test_IsDepleted_StreamNotDepleted() (gas: 253532) +IsDepleted_LockupLinear_Integration_Concrete_Test:test_IsDepleted() (gas: 287122) +IsDepleted_LockupLinear_Integration_Concrete_Test:test_IsDepleted_StreamNotDepleted() (gas: 253544) IsDepleted_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11212) -IsStream_LockupDynamic_Integration_Concrete_Test:test_IsStream() (gas: 327090) +IsStream_LockupDynamic_Integration_Concrete_Test:test_IsStream() (gas: 327114) IsStream_LockupDynamic_Integration_Concrete_Test:test_IsStream_Null() (gas: 8527) -IsStream_LockupLinear_Integration_Concrete_Test:test_IsStream() (gas: 253894) +IsStream_LockupLinear_Integration_Concrete_Test:test_IsStream() (gas: 253906) IsStream_LockupLinear_Integration_Concrete_Test:test_IsStream_Null() (gas: 8570) -IsTransferable_LockupDynamic_Integration_Concrete_Test:test_IsTransferrable_Stream() (gas: 327274) +IsTransferable_LockupDynamic_Integration_Concrete_Test:test_IsTransferrable_Stream() (gas: 327298) IsTransferable_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11674) -IsTransferable_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamTransferNotEnabled() (gas: 515789) -IsTransferable_LockupLinear_Integration_Concrete_Test:test_IsTransferrable_Stream() (gas: 254100) +IsTransferable_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamTransferNotEnabled() (gas: 515837) +IsTransferable_LockupLinear_Integration_Concrete_Test:test_IsTransferrable_Stream() (gas: 254112) IsTransferable_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11739) -IsTransferable_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamTransferNotEnabled() (gas: 372843) -IsWarm_LockupDynamic_Integration_Concrete_Test:test_IsWarm_StatusCanceled() (gas: 375536) -IsWarm_LockupDynamic_Integration_Concrete_Test:test_IsWarm_StatusDepleted() (gas: 362065) -IsWarm_LockupDynamic_Integration_Concrete_Test:test_IsWarm_StatusPending() (gas: 330053) -IsWarm_LockupDynamic_Integration_Concrete_Test:test_IsWarm_StatusSettled() (gas: 335997) -IsWarm_LockupDynamic_Integration_Concrete_Test:test_IsWarm_StatusStreaming() (gas: 352181) -IsWarm_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11118) -IsWarm_LockupLinear_Integration_Concrete_Test:test_IsWarm_StatusCanceled() (gas: 297036) -IsWarm_LockupLinear_Integration_Concrete_Test:test_IsWarm_StatusDepleted() (gas: 287080) -IsWarm_LockupLinear_Integration_Concrete_Test:test_IsWarm_StatusPending() (gas: 256835) -IsWarm_LockupLinear_Integration_Concrete_Test:test_IsWarm_StatusSettled() (gas: 262901) -IsWarm_LockupLinear_Integration_Concrete_Test:test_IsWarm_StatusStreaming() (gas: 263300) -IsWarm_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11139) +IsTransferable_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamTransferNotEnabled() (gas: 372867) +IsWarm_LockupDynamic_Integration_Concrete_Test:test_IsWarm_StatusCanceled() (gas: 375515) +IsWarm_LockupDynamic_Integration_Concrete_Test:test_IsWarm_StatusDepleted() (gas: 362198) +IsWarm_LockupDynamic_Integration_Concrete_Test:test_IsWarm_StatusPending() (gas: 330044) +IsWarm_LockupDynamic_Integration_Concrete_Test:test_IsWarm_StatusSettled() (gas: 335988) +IsWarm_LockupDynamic_Integration_Concrete_Test:test_IsWarm_StatusStreaming() (gas: 352172) +IsWarm_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11085) +IsWarm_LockupLinear_Integration_Concrete_Test:test_IsWarm_StatusCanceled() (gas: 296975) +IsWarm_LockupLinear_Integration_Concrete_Test:test_IsWarm_StatusDepleted() (gas: 287198) +IsWarm_LockupLinear_Integration_Concrete_Test:test_IsWarm_StatusPending() (gas: 256814) +IsWarm_LockupLinear_Integration_Concrete_Test:test_IsWarm_StatusSettled() (gas: 262880) +IsWarm_LockupLinear_Integration_Concrete_Test:test_IsWarm_StatusStreaming() (gas: 263279) +IsWarm_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11106) MapSymbol_Integration_Concrete_Test:test_MapSymbol_LockupDynamic() (gas: 16959) MapSymbol_Integration_Concrete_Test:test_MapSymbol_LockupLinear() (gas: 16733) -MapSymbol_Integration_Concrete_Test:test_RevertGiven_UnknownNFT() (gas: 1037150) +MapSymbol_Integration_Concrete_Test:test_RevertGiven_UnknownNFT() (gas: 1039753) MaxFlashLoan_Integration_Concrete_Test:test_MaxFlashLoan() (gas: 178987) MaxFlashLoan_Integration_Concrete_Test:test_MaxFlashLoan_AssetNotFlashLoanable() (gas: 15248) -MaxFlashLoan_Integration_Fuzz_Test:testFuzz_MaxFlashLoan(uint256) (runs: 50, μ: 178984, ~: 179004) +MaxFlashLoan_Integration_Fuzz_Test:testFuzz_MaxFlashLoan(uint256) (runs: 50, μ: 178982, ~: 179000) ProtocolFees_Integration_Concrete_Test:test_ProtocolFees() (gas: 41254) ProtocolFees_Integration_Concrete_Test:test_ProtocolFees_ProtocolFeeNotSet() (gas: 9943) -ProtocolRevenues_LockupDynamic_Integration_Concrete_Test:test_ProtocolRevenues() (gas: 320207) +ProtocolRevenues_LockupDynamic_Integration_Concrete_Test:test_ProtocolRevenues() (gas: 320231) ProtocolRevenues_LockupDynamic_Integration_Concrete_Test:test_ProtocolRevenues_ProtocolRevenuesZero() (gas: 10125) -ProtocolRevenues_LockupLinear_Integration_Concrete_Test:test_ProtocolRevenues() (gas: 246966) +ProtocolRevenues_LockupLinear_Integration_Concrete_Test:test_ProtocolRevenues() (gas: 246978) ProtocolRevenues_LockupLinear_Integration_Concrete_Test:test_ProtocolRevenues_ProtocolRevenuesZero() (gas: 10111) -RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StatusDepleted() (gas: 361993) -RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StatusPending() (gas: 335820) -RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StatusSettled() (gas: 335813) -RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StatusStreaming() (gas: 342682) -RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 375412) -RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 398639) -RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StreamNotCancelable() (gas: 523449) +RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StatusDepleted() (gas: 362159) +RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StatusPending() (gas: 335844) +RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StatusSettled() (gas: 335837) +RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StatusStreaming() (gas: 342706) +RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 375424) +RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 398793) +RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RefundableAmountOf_StreamNotCancelable() (gas: 523497) RefundableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11099) -RefundableAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_RefundableAmountOf(uint256) (runs: 50, μ: 48250, ~: 63808) -RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StatusDepleted() (gas: 287004) -RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StatusPending() (gas: 262589) -RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StatusSettled() (gas: 262712) -RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StatusStreaming() (gas: 264199) -RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 296908) -RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 320124) -RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StreamNotCancelable() (gas: 380452) +RefundableAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_RefundableAmountOf(uint256) (runs: 50, μ: 44758, ~: 30742) +RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StatusDepleted() (gas: 287155) +RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StatusPending() (gas: 262601) +RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StatusSettled() (gas: 262724) +RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StatusStreaming() (gas: 264211) +RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 296880) +RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 320235) +RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RefundableAmountOf_StreamNotCancelable() (gas: 380476) RefundableAmountOf_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11110) -RefundableAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_RefundableAmountOf(uint256) (runs: 50, μ: 30700, ~: 30858) -Renounce_LockupDynamic_Integration_Concrete_Test:test_Renounce() (gas: 694529) -Renounce_LockupDynamic_Integration_Concrete_Test:test_Renounce_RecipientDoesNotImplementHook() (gas: 687576) -Renounce_LockupDynamic_Integration_Concrete_Test:test_Renounce_RecipientNotContract() (gas: 292583) -Renounce_LockupDynamic_Integration_Concrete_Test:test_Renounce_RecipientReentrancy() (gas: 692741) -Renounce_LockupDynamic_Integration_Concrete_Test:test_Renounce_RecipientReverts() (gas: 688183) +RefundableAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_RefundableAmountOf(uint256) (runs: 50, μ: 30789, ~: 30858) +Renounce_LockupDynamic_Integration_Concrete_Test:test_Renounce() (gas: 694601) +Renounce_LockupDynamic_Integration_Concrete_Test:test_Renounce_RecipientDoesNotImplementHook() (gas: 687648) +Renounce_LockupDynamic_Integration_Concrete_Test:test_Renounce_RecipientNotContract() (gas: 292607) +Renounce_LockupDynamic_Integration_Concrete_Test:test_Renounce_RecipientReentrancy() (gas: 692813) +Renounce_LockupDynamic_Integration_Concrete_Test:test_Renounce_RecipientReverts() (gas: 688255) Renounce_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11564) -Renounce_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 87127) -Renounce_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusDepleted() (gas: 68421) +Renounce_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 87115) +Renounce_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusDepleted() (gas: 68563) Renounce_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StatusSettled() (gas: 24707) -Renounce_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamNotCancelable() (gas: 649813) -Renounce_LockupLinear_Integration_Concrete_Test:test_Renounce() (gas: 481658) -Renounce_LockupLinear_Integration_Concrete_Test:test_Renounce_RecipientDoesNotImplementHook() (gas: 474703) -Renounce_LockupLinear_Integration_Concrete_Test:test_Renounce_RecipientNotContract() (gas: 219414) -Renounce_LockupLinear_Integration_Concrete_Test:test_Renounce_RecipientReentrancy() (gas: 479840) -Renounce_LockupLinear_Integration_Concrete_Test:test_Renounce_RecipientReverts() (gas: 475310) +Renounce_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamNotCancelable() (gas: 649885) +Renounce_LockupLinear_Integration_Concrete_Test:test_Renounce() (gas: 481694) +Renounce_LockupLinear_Integration_Concrete_Test:test_Renounce_RecipientDoesNotImplementHook() (gas: 474739) +Renounce_LockupLinear_Integration_Concrete_Test:test_Renounce_RecipientNotContract() (gas: 219426) +Renounce_LockupLinear_Integration_Concrete_Test:test_Renounce_RecipientReentrancy() (gas: 479876) +Renounce_LockupLinear_Integration_Concrete_Test:test_Renounce_RecipientReverts() (gas: 475346) Renounce_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11575) -Renounce_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 77847) -Renounce_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusDepleted() (gas: 68656) +Renounce_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusCanceled() (gas: 77807) +Renounce_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusDepleted() (gas: 68795) Renounce_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StatusSettled() (gas: 24822) -Renounce_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamNotCancelable() (gas: 436988) +Renounce_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamNotCancelable() (gas: 437024) SafeAssetDecimals_Integration_Concrete_Test:test_SafeAssetDecimals() (gas: 12117) SafeAssetDecimals_Integration_Concrete_Test:test_SafeAssetDecimals_DecimalsNotImplemented() (gas: 10852) SafeAssetDecimals_Integration_Concrete_Test:test_SafeAssetDecimals_EOA() (gas: 11625) SafeAssetSymbol_Integration_Concrete_Test:test_SafeAssetSymbol() (gas: 18550) -SafeAssetSymbol_Integration_Concrete_Test:test_SafeAssetSymbol_Bytes32() (gas: 59605) +SafeAssetSymbol_Integration_Concrete_Test:test_SafeAssetSymbol_Bytes32() (gas: 62214) SafeAssetSymbol_Integration_Concrete_Test:test_SafeAssetSymbol_EOA() (gas: 13222) -SafeAssetSymbol_Integration_Concrete_Test:test_SafeAssetSymbol_LongSymbol() (gas: 622290) +SafeAssetSymbol_Integration_Concrete_Test:test_SafeAssetSymbol_LongSymbol() (gas: 624896) SafeAssetSymbol_Integration_Concrete_Test:test_SafeAssetSymbol_SymbolNotImplemented() (gas: 12399) -SetComptroller_LockupDynamic_Integration_Concrete_Test:test_SetComptroller_NewComptroller() (gas: 309153) +SetComptroller_LockupDynamic_Integration_Concrete_Test:test_SetComptroller_NewComptroller() (gas: 311753) SetComptroller_LockupDynamic_Integration_Concrete_Test:test_SetComptroller_SameComptroller() (gas: 23283) -SetComptroller_LockupLinear_Integration_Concrete_Test:test_SetComptroller_NewComptroller() (gas: 309150) +SetComptroller_LockupLinear_Integration_Concrete_Test:test_SetComptroller_NewComptroller() (gas: 311750) SetComptroller_LockupLinear_Integration_Concrete_Test:test_SetComptroller_SameComptroller() (gas: 23280) -SetFlashFee_Integration_Fuzz_Test:testFuzz_SetFlashFee(uint256) (runs: 50, μ: 37809, ~: 40020) -SetNFTDescriptor_LockupDynamic_Integration_Concrete_Test:test_SetNFTDescriptor_NewNFTDescriptor() (gas: 6542473) -SetNFTDescriptor_LockupDynamic_Integration_Concrete_Test:test_SetNFTDescriptor_SameNFTDescriptor() (gas: 2251619) -SetNFTDescriptor_LockupLinear_Integration_Concrete_Test:test_SetNFTDescriptor_NewNFTDescriptor() (gas: 6541265) -SetNFTDescriptor_LockupLinear_Integration_Concrete_Test:test_SetNFTDescriptor_SameNFTDescriptor() (gas: 2250276) +SetFlashFee_Integration_Fuzz_Test:testFuzz_SetFlashFee(uint256) (runs: 50, μ: 37767, ~: 39448) +SetNFTDescriptor_LockupDynamic_Integration_Concrete_Test:test_SetNFTDescriptor_NewNFTDescriptor() (gas: 6551561) +SetNFTDescriptor_LockupDynamic_Integration_Concrete_Test:test_SetNFTDescriptor_SameNFTDescriptor() (gas: 2258131) +SetNFTDescriptor_LockupLinear_Integration_Concrete_Test:test_SetNFTDescriptor_NewNFTDescriptor() (gas: 6550197) +SetNFTDescriptor_LockupLinear_Integration_Concrete_Test:test_SetNFTDescriptor_SameNFTDescriptor() (gas: 2256602) SetProtocolFee_Integration_Concrete_Test:test_SetProtocolFee() (gas: 47804) SetProtocolFee_Integration_Concrete_Test:test_SetProtocolFee_SameFee() (gas: 22636) -SetProtocolFee_Integration_Fuzz_Test:testFuzz_SetProtocolFee(uint256) (runs: 50, μ: 43089, ~: 43074) -StatusOf_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11684) -StatusOf_LockupDynamic_Integration_Concrete_Test:test_StatusOf() (gas: 352818) -StatusOf_LockupDynamic_Integration_Concrete_Test:test_StatusOf_AssetsFullyWithdrawn() (gas: 362690) -StatusOf_LockupDynamic_Integration_Concrete_Test:test_StatusOf_RefundableAmountNotZero() (gas: 336598) -StatusOf_LockupDynamic_Integration_Concrete_Test:test_StatusOf_StartTimeInTheFuture() (gas: 330697) -StatusOf_LockupDynamic_Integration_Concrete_Test:test_StatusOf_StreamCanceled() (gas: 376172) -StatusOf_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11714) -StatusOf_LockupLinear_Integration_Concrete_Test:test_StatusOf() (gas: 263351) -StatusOf_LockupLinear_Integration_Concrete_Test:test_StatusOf_AssetsFullyWithdrawn() (gas: 287719) -StatusOf_LockupLinear_Integration_Concrete_Test:test_StatusOf_RefundableAmountNotZero() (gas: 263516) -StatusOf_LockupLinear_Integration_Concrete_Test:test_StatusOf_StartTimeInTheFuture() (gas: 257493) -StatusOf_LockupLinear_Integration_Concrete_Test:test_StatusOf_StreamCanceled() (gas: 297686) +SetProtocolFee_Integration_Fuzz_Test:testFuzz_SetProtocolFee(uint256) (runs: 50, μ: 43128, ~: 43074) +StatusOf_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11651) +StatusOf_LockupDynamic_Integration_Concrete_Test:test_StatusOf() (gas: 352809) +StatusOf_LockupDynamic_Integration_Concrete_Test:test_StatusOf_AssetsFullyWithdrawn() (gas: 362823) +StatusOf_LockupDynamic_Integration_Concrete_Test:test_StatusOf_RefundableAmountNotZero() (gas: 336589) +StatusOf_LockupDynamic_Integration_Concrete_Test:test_StatusOf_StartTimeInTheFuture() (gas: 330688) +StatusOf_LockupDynamic_Integration_Concrete_Test:test_StatusOf_StreamCanceled() (gas: 376151) +StatusOf_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11681) +StatusOf_LockupLinear_Integration_Concrete_Test:test_StatusOf() (gas: 263330) +StatusOf_LockupLinear_Integration_Concrete_Test:test_StatusOf_AssetsFullyWithdrawn() (gas: 287837) +StatusOf_LockupLinear_Integration_Concrete_Test:test_StatusOf_RefundableAmountNotZero() (gas: 263495) +StatusOf_LockupLinear_Integration_Concrete_Test:test_StatusOf_StartTimeInTheFuture() (gas: 257472) +StatusOf_LockupLinear_Integration_Concrete_Test:test_StatusOf_StreamCanceled() (gas: 297625) StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11319) StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_CurrentMilestone1st() (gas: 45931) StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_CurrentMilestoneNot1st() (gas: 50774) -StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_OneSegment() (gas: 257003) +StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_OneSegment() (gas: 257027) StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_StartTimeInTheFuture() (gas: 20230) StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_StartTimeInThePresent() (gas: 25593) -StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_StatusDepleted() (gas: 68749) +StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_StatusDepleted() (gas: 68891) StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_StatusPending() (gas: 20360) StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_StatusSettled() (gas: 26624) -StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 87534) -StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 116207) -StreamedAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_StreamedAmountOf_Calculation((uint128,uint64,uint40)[],uint40) (runs: 50, μ: 3520440, ~: 3134690) -StreamedAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_StreamedAmountOf_Monotonicity((uint128,uint64,uint40)[],uint40,uint40) (runs: 50, μ: 3969098, ~: 4086928) -StreamedAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_StreamedAmountOf_OneSegment((uint128,uint64,uint40),uint40) (runs: 50, μ: 276308, ~: 270719) +StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 87522) +StreamedAmountOf_LockupDynamic_Integration_Concrete_Test:test_StreamedAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 116337) +StreamedAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_StreamedAmountOf_Calculation((uint128,uint64,uint40)[],uint40) (runs: 50, μ: 3523474, ~: 3133486) +StreamedAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_StreamedAmountOf_Monotonicity((uint128,uint64,uint40)[],uint40,uint40) (runs: 50, μ: 3972237, ~: 4084392) +StreamedAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_StreamedAmountOf_OneSegment((uint128,uint64,uint40),uint40) (runs: 50, μ: 276656, ~: 270632) StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 11349) StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_StreamedAmountOf_CliffTimeInTheFuture() (gas: 26236) StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_StreamedAmountOf_CliffTimeInThePast() (gas: 17291) StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_StreamedAmountOf_CliffTimeInThePresent() (gas: 27121) -StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_StreamedAmountOf_StatusDepleted() (gas: 68969) +StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_StreamedAmountOf_StatusDepleted() (gas: 69108) StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_StreamedAmountOf_StatusPending() (gas: 20305) StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_StreamedAmountOf_StatusSettled() (gas: 26688) -StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_StreamedAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 78261) -StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_StreamedAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 106890) -StreamedAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_StreamedAmountOf_Calculation(uint40,uint128) (runs: 50, μ: 234531, ~: 235187) +StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_StreamedAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 78221) +StreamedAmountOf_LockupLinear_Integration_Concrete_Test:test_StreamedAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 106989) +StreamedAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_StreamedAmountOf_Calculation(uint40,uint128) (runs: 50, μ: 234406, ~: 234313) StreamedAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_StreamedAmountOf_CliffTimeInTheFuture(uint40) (runs: 50, μ: 27397, ~: 27604) -StreamedAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_StreamedAmountOf_Monotonicity(uint40,uint40,uint128) (runs: 50, μ: 239328, ~: 241463) +StreamedAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_StreamedAmountOf_Monotonicity(uint40,uint40,uint128) (runs: 50, μ: 239510, ~: 241475) ToggleFlashAsset_Integration_Concrete_Test:test_ToggleFlashAsset() (gas: 31848) ToggleFlashAsset_Integration_Concrete_Test:test_ToggleFlashAsset_FlagNotEnabled() (gas: 41868) TokenURI_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_NFTDoesNotExist() (gas: 13542) -TokenURI_LockupDynamic_Integration_Concrete_Test:test_TokenURI_Decoded() (gas: 5031712) -TokenURI_LockupDynamic_Integration_Concrete_Test:test_TokenURI_Full() (gas: 2738320) +TokenURI_LockupDynamic_Integration_Concrete_Test:test_TokenURI_Decoded() (gas: 6624) +TokenURI_LockupDynamic_Integration_Concrete_Test:test_TokenURI_Full() (gas: 6601) TokenURI_LockupLinear_Integration_Concrete_Test:test_RevertGiven_NFTDoesNotExist() (gas: 13525) -TokenURI_LockupLinear_Integration_Concrete_Test:test_TokenURI_Decoded() (gas: 4949035) -TokenURI_LockupLinear_Integration_Concrete_Test:test_TokenURI_Full() (gas: 2656181) -TransferFrom_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamNotTransferable() (gas: 314189) -TransferFrom_LockupDynamic_Integration_Concrete_Test:test_TransferFrom() (gas: 326528) -TransferFrom_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamNotTransferable() (gas: 240381) -TransferFrom_LockupLinear_Integration_Concrete_Test:test_TransferFrom() (gas: 253258) +TokenURI_LockupLinear_Integration_Concrete_Test:test_TokenURI_Decoded() (gas: 6624) +TokenURI_LockupLinear_Integration_Concrete_Test:test_TokenURI_Full() (gas: 6601) +TransferFrom_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamNotTransferable() (gas: 314213) +TransferFrom_LockupDynamic_Integration_Concrete_Test:test_TransferFrom() (gas: 326552) +TransferFrom_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamNotTransferable() (gas: 240393) +TransferFrom_LockupLinear_Integration_Concrete_Test:test_TransferFrom() (gas: 253270) WasCanceled_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 12048) -WasCanceled_LockupDynamic_Integration_Concrete_Test:test_WasCanceled() (gas: 364234) -WasCanceled_LockupDynamic_Integration_Concrete_Test:test_WasCanceled_StreamNotCanceled() (gas: 327640) +WasCanceled_LockupDynamic_Integration_Concrete_Test:test_WasCanceled() (gas: 364246) +WasCanceled_LockupDynamic_Integration_Concrete_Test:test_WasCanceled_StreamNotCanceled() (gas: 327664) WasCanceled_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 12069) -WasCanceled_LockupLinear_Integration_Concrete_Test:test_WasCanceled() (gas: 288988) -WasCanceled_LockupLinear_Integration_Concrete_Test:test_WasCanceled_StreamNotCanceled() (gas: 254422) -WithdrawMaxAndTransfer_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_NFTBurned() (gas: 75279) +WasCanceled_LockupLinear_Integration_Concrete_Test:test_WasCanceled() (gas: 288960) +WasCanceled_LockupLinear_Integration_Concrete_Test:test_WasCanceled_StreamNotCanceled() (gas: 254434) +WithdrawMaxAndTransfer_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_NFTBurned() (gas: 75605) WithdrawMaxAndTransfer_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 14162) -WithdrawMaxAndTransfer_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamNotTransferable() (gas: 265080) -WithdrawMaxAndTransfer_LockupDynamic_Integration_Concrete_Test:test_WithdrawMaxAndTransfer() (gas: 156711) -WithdrawMaxAndTransfer_LockupDynamic_Integration_Concrete_Test:test_WithdrawMaxAndTransfer_WithdrawableAmountZero() (gas: 101492) -WithdrawMaxAndTransfer_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawMaxAndTransfer(uint256,address) (runs: 50, μ: 131073, ~: 112693) -WithdrawMaxAndTransfer_LockupLinear_Integration_Concrete_Test:test_RevertGiven_NFTBurned() (gas: 75509) -WithdrawMaxAndTransfer_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 14170) -WithdrawMaxAndTransfer_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamNotTransferable() (gas: 189310) -WithdrawMaxAndTransfer_LockupLinear_Integration_Concrete_Test:test_WithdrawMaxAndTransfer() (gas: 109710) -WithdrawMaxAndTransfer_LockupLinear_Integration_Concrete_Test:test_WithdrawMaxAndTransfer_WithdrawableAmountZero() (gas: 101736) -WithdrawMaxAndTransfer_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawMaxAndTransfer(uint256,address) (runs: 50, μ: 99903, ~: 108188) -WithdrawMax_LockupDynamic_Integration_Concrete_Test:test_WithdrawMax() (gas: 134665) -WithdrawMax_LockupDynamic_Integration_Concrete_Test:test_WithdrawMax_EndTimeNotInTheFuture() (gas: 79744) -WithdrawMax_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawMax(uint256) (runs: 50, μ: 116864, ~: 119983) -WithdrawMax_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawMax_EndTimeNotInTheFuture(uint256) (runs: 50, μ: 82259, ~: 82427) -WithdrawMax_LockupLinear_Integration_Concrete_Test:test_WithdrawMax() (gas: 74005) -WithdrawMax_LockupLinear_Integration_Concrete_Test:test_WithdrawMax_EndTimeNotInTheFuture() (gas: 80017) -WithdrawMax_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawMax(uint256) (runs: 50, μ: 72948, ~: 73116) -WithdrawMax_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawMax_EndTimeNotInTheFuture(uint256) (runs: 50, μ: 82490, ~: 82584) -WithdrawMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_AllStatusesDepleted() (gas: 73926) -WithdrawMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_OnlyNull() (gas: 21069) -WithdrawMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_SomeNull() (gas: 124805) -WithdrawMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_SomeStatusesDepleted() (gas: 83399) -WithdrawMultiple_LockupDynamic_Integration_Concrete_Test:test_WithdrawMultiple() (gas: 1823420) +WithdrawMaxAndTransfer_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamNotTransferable() (gas: 265104) +WithdrawMaxAndTransfer_LockupDynamic_Integration_Concrete_Test:test_WithdrawMaxAndTransfer() (gas: 159929) +WithdrawMaxAndTransfer_LockupDynamic_Integration_Concrete_Test:test_WithdrawMaxAndTransfer_WithdrawableAmountZero() (gas: 101818) +WithdrawMaxAndTransfer_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawMaxAndTransfer(uint256,address) (runs: 50, μ: 136606, ~: 156340) +WithdrawMaxAndTransfer_LockupLinear_Integration_Concrete_Test:test_RevertGiven_NFTBurned() (gas: 75850) +WithdrawMaxAndTransfer_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 14179) +WithdrawMaxAndTransfer_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamNotTransferable() (gas: 189368) +WithdrawMaxAndTransfer_LockupLinear_Integration_Concrete_Test:test_WithdrawMaxAndTransfer() (gas: 112917) +WithdrawMaxAndTransfer_LockupLinear_Integration_Concrete_Test:test_WithdrawMaxAndTransfer_WithdrawableAmountZero() (gas: 102105) +WithdrawMaxAndTransfer_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawMaxAndTransfer(uint256,address) (runs: 50, μ: 99893, ~: 111263) +WithdrawMax_LockupDynamic_Integration_Concrete_Test:test_WithdrawMax() (gas: 135385) +WithdrawMax_LockupDynamic_Integration_Concrete_Test:test_WithdrawMax_EndTimeNotInTheFuture() (gas: 80455) +WithdrawMax_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawMax(uint256) (runs: 50, μ: 117789, ~: 120819) +WithdrawMax_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawMax_EndTimeNotInTheFuture(uint256) (runs: 50, μ: 83083, ~: 83237) +WithdrawMax_LockupLinear_Integration_Concrete_Test:test_WithdrawMax() (gas: 74722) +WithdrawMax_LockupLinear_Integration_Concrete_Test:test_WithdrawMax_EndTimeNotInTheFuture() (gas: 80725) +WithdrawMax_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawMax(uint256) (runs: 50, μ: 73792, ~: 73934) +WithdrawMax_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawMax_EndTimeNotInTheFuture(uint256) (runs: 50, μ: 83366, ~: 83507) +WithdrawMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_AllStatusesDepleted() (gas: 74062) +WithdrawMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_OnlyNull() (gas: 21063) +WithdrawMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_SomeNull() (gas: 125083) +WithdrawMultiple_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_SomeStatusesDepleted() (gas: 83535) +WithdrawMultiple_LockupDynamic_Integration_Concrete_Test:test_WithdrawMultiple() (gas: 1832166) WithdrawMultiple_LockupDynamic_Integration_Concrete_Test:test_WithdrawMultiple_ArrayCountsZero() (gas: 9109) -WithdrawMultiple_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawMultiple(uint256,address,uint128) (runs: 50, μ: 2741367, ~: 2742123) -WithdrawMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_AllStatusesDepleted() (gas: 74068) -WithdrawMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_OnlyNull() (gas: 20978) -WithdrawMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_SomeNull() (gas: 105128) -WithdrawMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_SomeStatusesDepleted() (gas: 83541) -WithdrawMultiple_LockupLinear_Integration_Concrete_Test:test_WithdrawMultiple() (gas: 1256080) +WithdrawMultiple_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawMultiple(uint256,address,uint128) (runs: 50, μ: 2746451, ~: 2747082) +WithdrawMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_AllStatusesDepleted() (gas: 74210) +WithdrawMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_OnlyNull() (gas: 20981) +WithdrawMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_SomeNull() (gas: 105595) +WithdrawMultiple_LockupLinear_Integration_Concrete_Test:test_RevertGiven_SomeStatusesDepleted() (gas: 83683) +WithdrawMultiple_LockupLinear_Integration_Concrete_Test:test_WithdrawMultiple() (gas: 1265450) WithdrawMultiple_LockupLinear_Integration_Concrete_Test:test_WithdrawMultiple_ArrayCountsZero() (gas: 9126) -WithdrawMultiple_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawMultiple(uint256,address,uint128) (runs: 50, μ: 1770198, ~: 1770012) -Withdraw_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 19909) -Withdraw_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamDepleted() (gas: 67687) -Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw() (gas: 384728) -Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_CallerApprovedOperator() (gas: 112603) -Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_CallerRecipient() (gas: 81162) -Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_EndTimeNotInTheFuture() (gas: 72576) -Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_RecipientDoesNotImplementHook() (gas: 362862) -Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_RecipientNotContract() (gas: 122264) -Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_RecipientReentrancy() (gas: 390093) -Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_RecipientReverts() (gas: 363417) -Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_StreamHasBeenCanceled() (gas: 382275) -Withdraw_LockupDynamic_Integration_Fuzz_Test:testFuzz_Withdraw(uint256,address,uint128) (runs: 50, μ: 123360, ~: 98089) -Withdraw_LockupDynamic_Integration_Fuzz_Test:testFuzz_Withdraw_CallerApprovedOperator(address) (runs: 50, μ: 145346, ~: 145346) -Withdraw_LockupDynamic_Integration_Fuzz_Test:testFuzz_Withdraw_SegmentFuzing(((uint128,uint64,uint40)[],uint256,address)) (runs: 50, μ: 3957016, ~: 3848156) -Withdraw_LockupDynamic_Integration_Fuzz_Test:testFuzz_Withdraw_StreamHasBeenCanceled(uint256,address,uint128) (runs: 50, μ: 158686, ~: 158963) +WithdrawMultiple_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawMultiple(uint256,address,uint128) (runs: 50, μ: 1775333, ~: 1775230) +Withdraw_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 19915) +Withdraw_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_StreamDepleted() (gas: 68019) +Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw() (gas: 385370) +Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_CallerApprovedOperator() (gas: 112905) +Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_CallerRecipient() (gas: 81464) +Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_EndTimeNotInTheFuture() (gas: 72694) +Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_RecipientDoesNotImplementHook() (gas: 363017) +Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_RecipientNotContract() (gas: 122875) +Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_RecipientReentrancy() (gas: 390550) +Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_RecipientReverts() (gas: 363572) +Withdraw_LockupDynamic_Integration_Concrete_Test:test_Withdraw_StreamHasBeenCanceled() (gas: 382375) +Withdraw_LockupDynamic_Integration_Fuzz_Test:testFuzz_Withdraw(uint256,address,uint128) (runs: 50, μ: 126673, ~: 98881) +Withdraw_LockupDynamic_Integration_Fuzz_Test:testFuzz_Withdraw_CallerApprovedOperator(address) (runs: 50, μ: 145648, ~: 145648) +Withdraw_LockupDynamic_Integration_Fuzz_Test:testFuzz_Withdraw_SegmentFuzing(((uint128,uint64,uint40)[],uint256,address)) (runs: 50, μ: 3946677, ~: 3885668) +Withdraw_LockupDynamic_Integration_Fuzz_Test:testFuzz_Withdraw_StreamHasBeenCanceled(uint256,address,uint128) (runs: 50, μ: 160521, ~: 160725) Withdraw_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 19917) -Withdraw_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamDepleted() (gas: 67928) -Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw() (gas: 268028) -Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_CallerApprovedOperator() (gas: 93000) -Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_CallerRecipient() (gas: 61548) -Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_EndTimeNotInTheFuture() (gas: 72811) -Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_RecipientDoesNotImplementHook() (gas: 259830) -Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_RecipientNotContract() (gas: 75345) -Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_RecipientReentrancy() (gas: 273458) -Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_RecipientReverts() (gas: 260385) -Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_StreamHasBeenCanceled() (gas: 292783) -Withdraw_LockupLinear_Integration_Fuzz_Test:testFuzz_Withdraw(uint256,address,uint128) (runs: 50, μ: 98684, ~: 98686) -Withdraw_LockupLinear_Integration_Fuzz_Test:testFuzz_Withdraw_CallerApprovedOperator(address) (runs: 50, μ: 112119, ~: 112119) -Withdraw_LockupLinear_Integration_Fuzz_Test:testFuzz_Withdraw_StreamHasBeenCanceled(uint256,address,uint128) (runs: 50, μ: 139252, ~: 139121) +Withdraw_LockupLinear_Integration_Concrete_Test:test_RevertGiven_StreamDepleted() (gas: 68251) +Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw() (gas: 268659) +Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_CallerApprovedOperator() (gas: 93323) +Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_CallerRecipient() (gas: 61871) +Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_EndTimeNotInTheFuture() (gas: 72950) +Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_RecipientDoesNotImplementHook() (gas: 259958) +Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_RecipientNotContract() (gas: 75977) +Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_RecipientReentrancy() (gas: 273925) +Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_RecipientReverts() (gas: 260513) +Withdraw_LockupLinear_Integration_Concrete_Test:test_Withdraw_StreamHasBeenCanceled() (gas: 292880) +Withdraw_LockupLinear_Integration_Fuzz_Test:testFuzz_Withdraw(uint256,address,uint128) (runs: 50, μ: 99550, ~: 99500) +Withdraw_LockupLinear_Integration_Fuzz_Test:testFuzz_Withdraw_CallerApprovedOperator(address) (runs: 50, μ: 112442, ~: 112442) +Withdraw_LockupLinear_Integration_Fuzz_Test:testFuzz_Withdraw_StreamHasBeenCanceled(uint256,address,uint128) (runs: 50, μ: 141061, ~: 140960) WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 12045) -WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf() (gas: 378217) -WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_NoPreviousWithdrawals() (gas: 347660) -WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StartTimeInThePresent() (gas: 337237) -WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusDepleted() (gas: 363787) -WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusPending() (gas: 333986) -WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusSettled() (gas: 340209) -WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 378252) -WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 400432) -WithdrawableAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawableAmountOf(uint40,uint128) (runs: 50, μ: 332238, ~: 313851) -WithdrawableAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawableAmountOf_NoPreviousWithdrawals(uint40) (runs: 50, μ: 298230, ~: 289755) +WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf() (gas: 378359) +WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_NoPreviousWithdrawals() (gas: 347684) +WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StartTimeInThePresent() (gas: 337261) +WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusDepleted() (gas: 363953) +WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusPending() (gas: 334010) +WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusSettled() (gas: 340233) +WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 378264) +WithdrawableAmountOf_LockupDynamic_Integration_Concrete_Test:test_WithdrawableAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 400586) +WithdrawableAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawableAmountOf(uint40,uint128) (runs: 50, μ: 332863, ~: 313993) +WithdrawableAmountOf_LockupDynamic_Integration_Fuzz_Test:testFuzz_WithdrawableAmountOf_NoPreviousWithdrawals(uint40) (runs: 50, μ: 296253, ~: 289779) WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_RevertGiven_Null() (gas: 12076) -WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_CliffTimeInTheFuture() (gas: 253643) -WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_NoPreviousWithdrawals() (gas: 263514) -WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusDepleted() (gas: 288779) -WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusPending() (gas: 258715) -WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusSettled() (gas: 265068) -WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 299774) -WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 321876) -WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_WithWithdrawals() (gas: 287157) -WithdrawableAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawableAmountOf(uint40,uint128,uint128) (runs: 50, μ: 464146, ~: 464993) -WithdrawableAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawableAmountOf_CliffTimeInTheFuture(uint40) (runs: 50, μ: 263735, ~: 263984) -WithdrawableAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawableAmountOf_NoPreviousWithdrawals(uint40,uint128) (runs: 50, μ: 440223, ~: 441015) \ No newline at end of file +WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_CliffTimeInTheFuture() (gas: 253655) +WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_NoPreviousWithdrawals() (gas: 263526) +WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusDepleted() (gas: 288930) +WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusPending() (gas: 258727) +WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_StatusSettled() (gas: 265080) +WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_StreamHasBeenCanceled_StatusCanceled() (gas: 299746) +WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_StreamHasBeenCanceled_StatusDepleted() (gas: 321987) +WithdrawableAmountOf_LockupLinear_Integration_Concrete_Test:test_WithdrawableAmountOf_WithWithdrawals() (gas: 287308) +WithdrawableAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawableAmountOf(uint40,uint128,uint128) (runs: 50, μ: 464049, ~: 463390) +WithdrawableAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawableAmountOf_CliffTimeInTheFuture(uint40) (runs: 50, μ: 263747, ~: 263996) +WithdrawableAmountOf_LockupLinear_Integration_Fuzz_Test:testFuzz_WithdrawableAmountOf_NoPreviousWithdrawals(uint40,uint128) (runs: 50, μ: 440270, ~: 441039) \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index bca470ec3..03ba64f04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ The format is based on [Common Changelog](https://common-changelog.org/). ### Changed +- **Breaking**: Remove ability to `cancel` for recipients ([#710](https://github.com/sablier-labs/v2-core/pull/710)) - Replace the streamed amount with the deposit amount in the NFT descriptor ([#692](https://github.com/sablier-labs/v2-core/pull/692)) - Upgrade Solidity to `0.8.21` ([#688](https://github.com/sablier-labs/v2-core/pull/688)) diff --git a/shell/prepare-artifacts.sh b/shell/prepare-artifacts.sh index 04ca4f002..06ab4fe97 100755 --- a/shell/prepare-artifacts.sh +++ b/shell/prepare-artifacts.sh @@ -45,7 +45,6 @@ cp out-optimized/IERC721Metadata.sol/IERC721Metadata.json $erc721 hooks=./artifacts/interfaces/hooks cp out-optimized/ISablierV2LockupRecipient.sol/ISablierV2LockupRecipient.json $hooks -cp out-optimized/ISablierV2LockupSender.sol/ISablierV2LockupSender.json $hooks libraries=./artifacts/libraries cp out-optimized/Errors.sol/Errors.json $libraries diff --git a/src/SablierV2LockupDynamic.sol b/src/SablierV2LockupDynamic.sol index 00374611d..4e571acef 100644 --- a/src/SablierV2LockupDynamic.sol +++ b/src/SablierV2LockupDynamic.sol @@ -14,7 +14,6 @@ import { ISablierV2Comptroller } from "./interfaces/ISablierV2Comptroller.sol"; import { ISablierV2Lockup } from "./interfaces/ISablierV2Lockup.sol"; import { ISablierV2LockupDynamic } from "./interfaces/ISablierV2LockupDynamic.sol"; import { ISablierV2LockupRecipient } from "./interfaces/hooks/ISablierV2LockupRecipient.sol"; -import { ISablierV2LockupSender } from "./interfaces/hooks/ISablierV2LockupSender.sol"; import { ISablierV2NFTDescriptor } from "./interfaces/ISablierV2NFTDescriptor.sol"; import { Errors } from "./libraries/Errors.sol"; import { Helpers } from "./libraries/Helpers.sol"; @@ -507,38 +506,25 @@ contract SablierV2LockupDynamic is address sender = _streams[streamId].sender; address recipient = _ownerOf(streamId); + // Retrieve the ERC-20 asset from storage. + IERC20 asset = _streams[streamId].asset; + // Interactions: refund the sender. - _streams[streamId].asset.safeTransfer({ to: sender, value: senderAmount }); - - // Interactions: if `msg.sender` is the sender and the recipient is a contract, try to invoke the cancel - // hook on the recipient without reverting if the hook is not implemented, and without bubbling up any - // potential revert. - if (msg.sender == sender) { - if (recipient.code.length > 0) { - try ISablierV2LockupRecipient(recipient).onStreamCanceled({ - streamId: streamId, - sender: sender, - senderAmount: senderAmount, - recipientAmount: recipientAmount - }) { } catch { } - } - } - // Interactions: if `msg.sender` is the recipient and the sender is a contract, try to invoke the cancel - // hook on the sender without reverting if the hook is not implemented, and also without bubbling up any - // potential revert. - else { - if (sender.code.length > 0) { - try ISablierV2LockupSender(sender).onStreamCanceled({ - streamId: streamId, - recipient: recipient, - senderAmount: senderAmount, - recipientAmount: recipientAmount - }) { } catch { } - } + asset.safeTransfer({ to: sender, value: senderAmount }); + + // Interactions: if the recipient is a contract, try to invoke the cancel hook on the recipient without + // reverting if the hook is not implemented, and without bubbling up any potential revert. + if (recipient.code.length > 0) { + try ISablierV2LockupRecipient(recipient).onStreamCanceled({ + streamId: streamId, + sender: sender, + senderAmount: senderAmount, + recipientAmount: recipientAmount + }) { } catch { } } // Log the cancellation. - emit ISablierV2Lockup.CancelLockupStream(streamId, sender, recipient, senderAmount, recipientAmount); + emit ISablierV2Lockup.CancelLockupStream(streamId, sender, recipient, asset, senderAmount, recipientAmount); } /// @dev See the documentation for the user-facing functions that call this internal function. @@ -650,7 +636,13 @@ contract SablierV2LockupDynamic is _streams[streamId].isCancelable = false; } + // Retrieve the ERC-20 asset from storage. + IERC20 asset = _streams[streamId].asset; + // Interactions: perform the ERC-20 transfer. - _streams[streamId].asset.safeTransfer({ to: to, value: amount }); + asset.safeTransfer({ to: to, value: amount }); + + // Log the withdrawal. + emit ISablierV2Lockup.WithdrawFromLockupStream(streamId, to, asset, amount); } } diff --git a/src/SablierV2LockupLinear.sol b/src/SablierV2LockupLinear.sol index 09d9b4fd1..5644ddd78 100644 --- a/src/SablierV2LockupLinear.sol +++ b/src/SablierV2LockupLinear.sol @@ -12,7 +12,6 @@ import { ISablierV2Lockup } from "./interfaces/ISablierV2Lockup.sol"; import { ISablierV2LockupLinear } from "./interfaces/ISablierV2LockupLinear.sol"; import { ISablierV2NFTDescriptor } from "./interfaces/ISablierV2NFTDescriptor.sol"; import { ISablierV2LockupRecipient } from "./interfaces/hooks/ISablierV2LockupRecipient.sol"; -import { ISablierV2LockupSender } from "./interfaces/hooks/ISablierV2LockupSender.sol"; import { Errors } from "./libraries/Errors.sol"; import { Helpers } from "./libraries/Helpers.sol"; import { Lockup, LockupLinear } from "./types/DataTypes.sol"; @@ -422,38 +421,25 @@ contract SablierV2LockupLinear is address sender = _streams[streamId].sender; address recipient = _ownerOf(streamId); + // Retrieve the ERC-20 asset from storage. + IERC20 asset = _streams[streamId].asset; + // Interactions: refund the sender. - _streams[streamId].asset.safeTransfer({ to: sender, value: senderAmount }); - - // Interactions: if `msg.sender` is the sender and the recipient is a contract, try to invoke the cancel - // hook on the recipient without reverting if the hook is not implemented, and without bubbling up any - // potential revert. - if (msg.sender == sender) { - if (recipient.code.length > 0) { - try ISablierV2LockupRecipient(recipient).onStreamCanceled({ - streamId: streamId, - sender: sender, - senderAmount: senderAmount, - recipientAmount: recipientAmount - }) { } catch { } - } - } - // Interactions: if `msg.sender` is the recipient and the sender is a contract, try to invoke the cancel - // hook on the sender without reverting if the hook is not implemented, and also without bubbling up any - // potential revert. - else { - if (sender.code.length > 0) { - try ISablierV2LockupSender(sender).onStreamCanceled({ - streamId: streamId, - recipient: recipient, - senderAmount: senderAmount, - recipientAmount: recipientAmount - }) { } catch { } - } + asset.safeTransfer({ to: sender, value: senderAmount }); + + // Interactions: if the recipient is a contract, try to invoke the cancel hook on the recipient without + // reverting if the hook is not implemented, and without bubbling up any potential revert. + if (recipient.code.length > 0) { + try ISablierV2LockupRecipient(recipient).onStreamCanceled({ + streamId: streamId, + sender: sender, + senderAmount: senderAmount, + recipientAmount: recipientAmount + }) { } catch { } } // Log the cancellation. - emit ISablierV2Lockup.CancelLockupStream(streamId, sender, recipient, senderAmount, recipientAmount); + emit ISablierV2Lockup.CancelLockupStream(streamId, sender, recipient, asset, senderAmount, recipientAmount); } /// @dev See the documentation for the user-facing functions that call this internal function. @@ -556,7 +542,13 @@ contract SablierV2LockupLinear is _streams[streamId].isCancelable = false; } + // Retrieve the ERC-20 asset from storage. + IERC20 asset = _streams[streamId].asset; + // Interactions: perform the ERC-20 transfer. - _streams[streamId].asset.safeTransfer({ to: to, value: amount }); + asset.safeTransfer({ to: to, value: amount }); + + // Log the withdrawal. + emit ISablierV2Lockup.WithdrawFromLockupStream(streamId, to, asset, amount); } } diff --git a/src/abstracts/SablierV2Lockup.sol b/src/abstracts/SablierV2Lockup.sol index e269e5c54..5f82c6a72 100644 --- a/src/abstracts/SablierV2Lockup.sol +++ b/src/abstracts/SablierV2Lockup.sol @@ -158,8 +158,8 @@ abstract contract SablierV2Lockup is revert Errors.SablierV2Lockup_StreamCanceled(streamId); } - // Checks: `msg.sender` is either the stream's sender or the stream's recipient (i.e. the NFT owner). - if (!_isCallerStreamSender(streamId) && msg.sender != _ownerOf(streamId)) { + // Checks: `msg.sender` is the stream's sender. + if (!_isCallerStreamSender(streamId)) { revert Errors.SablierV2Lockup_Unauthorized(streamId, msg.sender); } @@ -291,9 +291,6 @@ abstract contract SablierV2Lockup is amount: amount }) { } catch { } } - - // Log the withdrawal. - emit ISablierV2Lockup.WithdrawFromLockupStream(streamId, to, amount); } /// @inheritdoc ISablierV2Lockup diff --git a/src/interfaces/ISablierV2Lockup.sol b/src/interfaces/ISablierV2Lockup.sol index 94b8fb5b3..3bb304a3c 100644 --- a/src/interfaces/ISablierV2Lockup.sol +++ b/src/interfaces/ISablierV2Lockup.sol @@ -22,14 +22,16 @@ interface ISablierV2Lockup is /// @param streamId The id of the stream. /// @param sender The address of the stream's sender. /// @param recipient The address of the stream's recipient. + /// @param asset The contract address of the ERC-20 asset used for streaming. /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's /// decimals. /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the /// asset's decimals. event CancelLockupStream( - uint256 indexed streamId, + uint256 streamId, address indexed sender, address indexed recipient, + IERC20 indexed asset, uint128 senderAmount, uint128 recipientAmount ); @@ -49,8 +51,9 @@ interface ISablierV2Lockup is /// @notice Emitted when assets are withdrawn from a stream. /// @param streamId The id of the stream. /// @param to The address that has received the withdrawn assets. + /// @param asset The contract address of the ERC-20 asset used for streaming. /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals. - event WithdrawFromLockupStream(uint256 indexed streamId, address indexed to, uint128 amount); + event WithdrawFromLockupStream(uint256 indexed streamId, address indexed to, IERC20 indexed asset, uint128 amount); /*////////////////////////////////////////////////////////////////////////// CONSTANT FUNCTIONS @@ -187,7 +190,7 @@ interface ISablierV2Lockup is /// Requirements: /// - Must not be delegate called. /// - The stream must be warm and cancelable. - /// - `msg.sender` must be either the stream's sender or the stream's recipient (i.e. the NFT owner). + /// - `msg.sender` must be the stream's sender. /// /// @param streamId The id of the stream to cancel. function cancel(uint256 streamId) external; diff --git a/src/interfaces/hooks/ISablierV2LockupSender.sol b/src/interfaces/hooks/ISablierV2LockupSender.sol deleted file mode 100644 index c3ba379a8..000000000 --- a/src/interfaces/hooks/ISablierV2LockupSender.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; - -/// @title ISablierV2LockupSender -/// @notice Interface for sender contracts capable of reacting to cancellations. -/// @dev Implementation of this interface is optional. If a sender contract doesn't implement this interface, -/// function execution will not revert. -interface ISablierV2LockupSender { - /// @notice Responds to recipient-triggered cancellations. - /// - /// @dev Notes: - /// - This function may revert, but the Sablier contract will ignore the revert. - /// - /// @param streamId The id of the canceled stream. - /// @param recipient The stream's recipient, who canceled the stream. - /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's - /// decimals. - /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the - /// asset's decimals. - function onStreamCanceled( - uint256 streamId, - address recipient, - uint128 senderAmount, - uint128 recipientAmount - ) - external; -} diff --git a/test/Base.t.sol b/test/Base.t.sol index d64cc6355..beca5a0c1 100644 --- a/test/Base.t.sol +++ b/test/Base.t.sol @@ -18,7 +18,6 @@ import { ERC20MissingReturn } from "./mocks/erc20/ERC20MissingReturn.sol"; import { GoodFlashLoanReceiver } from "./mocks/flash-loan/GoodFlashLoanReceiver.sol"; import { Noop } from "./mocks/Noop.sol"; import { GoodRecipient } from "./mocks/hooks/GoodRecipient.sol"; -import { GoodSender } from "./mocks/hooks/GoodSender.sol"; import { Assertions } from "./utils/Assertions.sol"; import { Calculations } from "./utils/Calculations.sol"; import { Constants } from "./utils/Constants.sol"; @@ -44,7 +43,6 @@ abstract contract Base_Test is Assertions, Calculations, Constants, Events, Fuzz Defaults internal defaults; GoodFlashLoanReceiver internal goodFlashLoanReceiver; GoodRecipient internal goodRecipient; - GoodSender internal goodSender; ISablierV2LockupDynamic internal lockupDynamic; ISablierV2LockupLinear internal lockupLinear; ISablierV2NFTDescriptor internal nftDescriptor; @@ -60,7 +58,6 @@ abstract contract Base_Test is Assertions, Calculations, Constants, Events, Fuzz dai = new ERC20("Dai Stablecoin", "DAI"); goodFlashLoanReceiver = new GoodFlashLoanReceiver(); goodRecipient = new GoodRecipient(); - goodSender = new GoodSender(); noop = new Noop(); usdt = new ERC20MissingReturn("Tether USD", "USDT", 6); @@ -68,7 +65,6 @@ abstract contract Base_Test is Assertions, Calculations, Constants, Events, Fuzz vm.label({ account: address(dai), newLabel: "DAI" }); vm.label({ account: address(goodFlashLoanReceiver), newLabel: "Good Flash Loan Receiver" }); vm.label({ account: address(goodRecipient), newLabel: "Good Recipient" }); - vm.label({ account: address(goodSender), newLabel: "Good Sender" }); vm.label({ account: address(nftDescriptor), newLabel: "NFT Descriptor" }); vm.label({ account: address(noop), newLabel: "Noop" }); vm.label({ account: address(usdt), newLabel: "USDT" }); diff --git a/test/fork/LockupDynamic.t.sol b/test/fork/LockupDynamic.t.sol index 5300f05e8..7a02372ba 100644 --- a/test/fork/LockupDynamic.t.sol +++ b/test/fork/LockupDynamic.t.sol @@ -288,6 +288,7 @@ abstract contract LockupDynamic_Fork_Test is Fork_Test { emit WithdrawFromLockupStream({ streamId: vars.streamId, to: params.recipient, + asset: ASSET, amount: params.withdrawAmount }); vm.expectEmit({ emitter: address(lockupDynamic) }); @@ -351,7 +352,7 @@ abstract contract LockupDynamic_Fork_Test is Fork_Test { vars.senderAmount = lockupDynamic.refundableAmountOf(vars.streamId); vars.recipientAmount = lockupDynamic.withdrawableAmountOf(vars.streamId); emit CancelLockupStream( - vars.streamId, params.sender, params.recipient, vars.senderAmount, vars.recipientAmount + vars.streamId, params.sender, params.recipient, ASSET, vars.senderAmount, vars.recipientAmount ); vm.expectEmit({ emitter: address(lockupDynamic) }); emit MetadataUpdate({ _tokenId: vars.streamId }); diff --git a/test/fork/LockupLinear.t.sol b/test/fork/LockupLinear.t.sol index e7962d1ba..bd6016c64 100644 --- a/test/fork/LockupLinear.t.sol +++ b/test/fork/LockupLinear.t.sol @@ -274,6 +274,7 @@ abstract contract LockupLinear_Fork_Test is Fork_Test { emit WithdrawFromLockupStream({ streamId: vars.streamId, to: params.recipient, + asset: ASSET, amount: params.withdrawAmount }); vm.expectEmit({ emitter: address(lockupLinear) }); @@ -335,7 +336,7 @@ abstract contract LockupLinear_Fork_Test is Fork_Test { vars.senderAmount = lockupLinear.refundableAmountOf(vars.streamId); vars.recipientAmount = lockupLinear.withdrawableAmountOf(vars.streamId); emit CancelLockupStream( - vars.streamId, params.sender, params.recipient, vars.senderAmount, vars.recipientAmount + vars.streamId, params.sender, params.recipient, ASSET, vars.senderAmount, vars.recipientAmount ); vm.expectEmit({ emitter: address(lockupLinear) }); emit MetadataUpdate({ _tokenId: vars.streamId }); diff --git a/test/integration/Integration.t.sol b/test/integration/Integration.t.sol index eaeba7b0d..2e0c62ab9 100644 --- a/test/integration/Integration.t.sol +++ b/test/integration/Integration.t.sol @@ -7,9 +7,7 @@ import { Base_Test } from "../Base.t.sol"; import { FaultyFlashLoanReceiver } from "../mocks/flash-loan/FaultyFlashLoanReceiver.sol"; import { ReentrantFlashLoanReceiver } from "../mocks/flash-loan/ReentrantFlashLoanReceiver.sol"; import { ReentrantRecipient } from "../mocks/hooks/ReentrantRecipient.sol"; -import { ReentrantSender } from "../mocks/hooks/ReentrantSender.sol"; import { RevertingRecipient } from "../mocks/hooks/RevertingRecipient.sol"; -import { RevertingSender } from "../mocks/hooks/RevertingSender.sol"; /// @notice Common logic needed by all integration tests, both concrete and fuzz tests. abstract contract Integration_Test is Base_Test { @@ -20,9 +18,7 @@ abstract contract Integration_Test is Base_Test { FaultyFlashLoanReceiver internal faultyFlashLoanReceiver = new FaultyFlashLoanReceiver(); ReentrantFlashLoanReceiver internal reentrantFlashLoanReceiver = new ReentrantFlashLoanReceiver(); ReentrantRecipient internal reentrantRecipient = new ReentrantRecipient(); - ReentrantSender internal reentrantSender = new ReentrantSender(); RevertingRecipient internal revertingRecipient = new RevertingRecipient(); - RevertingSender internal revertingSender = new RevertingSender(); /*////////////////////////////////////////////////////////////////////////// SET-UP FUNCTION @@ -53,9 +49,7 @@ abstract contract Integration_Test is Base_Test { vm.label({ account: address(faultyFlashLoanReceiver), newLabel: "Faulty Flash Loan Receiver" }); vm.label({ account: address(reentrantFlashLoanReceiver), newLabel: "Reentrant Flash Loan Receiver" }); vm.label({ account: address(reentrantRecipient), newLabel: "Reentrant Lockup Recipient" }); - vm.label({ account: address(reentrantSender), newLabel: "Reentrant Lockup Sender" }); vm.label({ account: address(revertingRecipient), newLabel: "Reverting Lockup Recipient" }); - vm.label({ account: address(revertingSender), newLabel: "Reverting Lockup Sender" }); } /*////////////////////////////////////////////////////////////////////////// diff --git a/test/integration/concrete/lockup/burn/burn.t.sol b/test/integration/concrete/lockup/burn/burn.t.sol index 219f6ae86..f73493e41 100644 --- a/test/integration/concrete/lockup/burn/burn.t.sol +++ b/test/integration/concrete/lockup/burn/burn.t.sol @@ -83,7 +83,9 @@ abstract contract Burn_Integration_Concrete_Test is Integration_Test, Lockup_Int givenStreamHasNotBeenDepleted { vm.warp({ timestamp: defaults.CLIFF_TIME() }); + changePrank({ msgSender: users.sender }); lockup.cancel(streamId); + changePrank({ msgSender: users.recipient }); vm.expectRevert(abi.encodeWithSelector(Errors.SablierV2Lockup_StreamNotDepleted.selector, streamId)); lockup.burn(streamId); } diff --git a/test/integration/concrete/lockup/cancel-multiple/cancelMultiple.t.sol b/test/integration/concrete/lockup/cancel-multiple/cancelMultiple.t.sol index 67103ba5d..4aab9c7c5 100644 --- a/test/integration/concrete/lockup/cancel-multiple/cancelMultiple.t.sol +++ b/test/integration/concrete/lockup/cancel-multiple/cancelMultiple.t.sol @@ -72,7 +72,7 @@ abstract contract CancelMultiple_Integration_Concrete_Test is lockup.cancelMultiple(testStreamIds); } - function test_RevertWhen_CallerUnauthorizedAllStreams_ApprovedOperator() + function test_RevertWhen_CallerUnauthorizedAllStreams_Recipient() external whenNotDelegateCalled whenArrayCountNotZero @@ -80,32 +80,8 @@ abstract contract CancelMultiple_Integration_Concrete_Test is givenAllStreamsWarm whenCallerUnauthorized { - // Approve the operator for all streams. + // Make the Recipient the caller in this test. changePrank({ msgSender: users.recipient }); - lockup.setApprovalForAll({ operator: users.operator, approved: true }); - - // Make the approved operator the caller in this test. - changePrank({ msgSender: users.operator }); - - // Run the test. - vm.expectRevert( - abi.encodeWithSelector(Errors.SablierV2Lockup_Unauthorized.selector, testStreamIds[0], users.operator) - ); - lockup.cancelMultiple(testStreamIds); - } - - function test_RevertWhen_CallerUnauthorizedAllStreams_FormerRecipient() - external - whenNotDelegateCalled - whenArrayCountNotZero - givenNoNull - givenAllStreamsWarm - whenCallerUnauthorized - { - // Transfer the streams to Alice. - changePrank({ msgSender: users.recipient }); - lockup.transferFrom({ from: users.recipient, to: users.alice, tokenId: testStreamIds[0] }); - lockup.transferFrom({ from: users.recipient, to: users.alice, tokenId: testStreamIds[1] }); // Run the test. vm.expectRevert( @@ -135,29 +111,7 @@ abstract contract CancelMultiple_Integration_Concrete_Test is lockup.cancelMultiple(streamIds); } - function test_RevertWhen_CallerUnauthorizedSomeStreams_ApprovedOperator() - external - whenNotDelegateCalled - whenArrayCountNotZero - givenNoNull - givenAllStreamsWarm - whenCallerUnauthorized - { - // Approve the operator to handle the first stream. - changePrank({ msgSender: users.recipient }); - lockup.approve({ to: users.operator, tokenId: testStreamIds[0] }); - - // Make the approved operator the caller in this test. - changePrank({ msgSender: users.operator }); - - // Run the test. - vm.expectRevert( - abi.encodeWithSelector(Errors.SablierV2Lockup_Unauthorized.selector, testStreamIds[0], users.operator) - ); - lockup.cancelMultiple(testStreamIds); - } - - function test_RevertWhen_CallerUnauthorizedSomeStreams_FormerRecipient() + function test_RevertWhen_CallerUnauthorizedSomeStreams_Recipient() external whenNotDelegateCalled whenArrayCountNotZero @@ -165,9 +119,8 @@ abstract contract CancelMultiple_Integration_Concrete_Test is givenAllStreamsWarm whenCallerUnauthorized { - // Transfer the first stream to Eve. + // Make the Recipient the caller in this test. changePrank({ msgSender: users.recipient }); - lockup.transferFrom({ from: users.recipient, to: users.alice, tokenId: testStreamIds[0] }); // Run the test. vm.expectRevert( @@ -229,6 +182,7 @@ abstract contract CancelMultiple_Integration_Concrete_Test is streamId: testStreamIds[0], sender: users.sender, recipient: users.recipient, + asset: dai, senderAmount: senderAmount0, recipientAmount: defaults.DEPOSIT_AMOUNT() - senderAmount0 }); @@ -237,6 +191,7 @@ abstract contract CancelMultiple_Integration_Concrete_Test is streamId: testStreamIds[1], sender: users.sender, recipient: users.recipient, + asset: dai, senderAmount: senderAmount1, recipientAmount: defaults.DEPOSIT_AMOUNT() - senderAmount1 }); diff --git a/test/integration/concrete/lockup/cancel-multiple/cancelMultiple.tree b/test/integration/concrete/lockup/cancel-multiple/cancelMultiple.tree index 2b7439c4b..2cd6a411f 100644 --- a/test/integration/concrete/lockup/cancel-multiple/cancelMultiple.tree +++ b/test/integration/concrete/lockup/cancel-multiple/cancelMultiple.tree @@ -18,16 +18,12 @@ cancelMultiple.t.sol ├── when the caller is unauthorized for all streams │ ├── when the caller is a malicious third party │ │ └── it should revert - │ ├── when the caller is an approved third party - │ │ └── it should revert - │ └── when the caller is a former recipient + │ └── when the caller is the recipient │ └── it should revert ├── when the caller is unauthorized for some streams │ ├── when the caller is a malicious third party │ │ └── it should revert - │ ├── when the caller is an approved third party - │ │ └── it should revert - │ └── when the caller is a former recipient + │ └── when the caller is the recipient │ └── it should revert └── when the caller is authorized for all streams ├── given all streams are not cancelable @@ -35,13 +31,7 @@ cancelMultiple.t.sol ├── given some streams are not cancelable │ └── it should revert └── given all streams are cancelable - ├── when the caller is the sender - │ ├── it should cancel the streams - │ ├── it should refund the sender - │ ├── it should update the refunded amounts - │ └── it should emit {CancelLockupStream} events - └── when the caller is the recipient - ├── it should cancel the streams - ├── it should refund the sender - ├── it should update the refunded amounts - └── it should emit {CancelLockupStream} events + ├── it should cancel the streams + ├── it should refund the sender + ├── it should update the refunded amounts + └── it should emit {CancelLockupStream} events diff --git a/test/integration/concrete/lockup/cancel/cancel.t.sol b/test/integration/concrete/lockup/cancel/cancel.t.sol index 50b5e5012..616e864ee 100644 --- a/test/integration/concrete/lockup/cancel/cancel.t.sol +++ b/test/integration/concrete/lockup/cancel/cancel.t.sol @@ -3,7 +3,6 @@ pragma solidity >=0.8.19 <0.9.0; import { ISablierV2Lockup } from "src/interfaces/ISablierV2Lockup.sol"; import { ISablierV2LockupRecipient } from "src/interfaces/hooks/ISablierV2LockupRecipient.sol"; -import { ISablierV2LockupSender } from "src/interfaces/hooks/ISablierV2LockupSender.sol"; import { Errors } from "src/libraries/Errors.sol"; import { Lockup } from "src/types/DataTypes.sol"; @@ -65,37 +64,15 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I lockup.cancel(defaultStreamId); } - function test_RevertWhen_CallerUnauthorized_ApprovedOperator() + function test_RevertWhen_CallerUnauthorized_Recipient() external whenNotDelegateCalled givenNotNull givenStreamWarm whenCallerUnauthorized { - // Approve Alice for the stream. + // Make the Recipient the caller in this test. changePrank({ msgSender: users.recipient }); - lockup.approve({ to: users.operator, tokenId: defaultStreamId }); - - // Make Alice the caller in this test. - changePrank({ msgSender: users.operator }); - - // Run the test. - vm.expectRevert( - abi.encodeWithSelector(Errors.SablierV2Lockup_Unauthorized.selector, defaultStreamId, users.operator) - ); - lockup.cancel(defaultStreamId); - } - - function test_RevertWhen_CallerUnauthorized_FormerRecipient() - external - whenNotDelegateCalled - givenNotNull - givenStreamWarm - whenCallerUnauthorized - { - // Transfer the stream to Alice. - changePrank({ msgSender: users.recipient }); - lockup.transferFrom({ from: users.recipient, to: users.alice, tokenId: defaultStreamId }); // Run the test. vm.expectRevert( @@ -133,7 +110,7 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I assertFalse(isCancelable, "isCancelable"); } - function test_Cancel_CallerSender_RecipientNotContract() + function test_Cancel_RecipientNotContract() external whenNotDelegateCalled givenNotNull @@ -141,7 +118,6 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I whenCallerAuthorized givenStreamCancelable givenStatusStreaming - whenCallerSender { lockup.cancel(defaultStreamId); Lockup.Status actualStatus = lockup.statusOf(defaultStreamId); @@ -149,7 +125,7 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I assertEq(actualStatus, expectedStatus); } - function test_Cancel_CallerSender_RecipientDoesNotImplementHook() + function test_Cancel_RecipientDoesNotImplementHook() external whenNotDelegateCalled givenNotNull @@ -157,7 +133,6 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I whenCallerAuthorized givenStreamCancelable givenStatusStreaming - whenCallerSender givenRecipientContract { // Create the stream with a no-op contract as the recipient. @@ -182,7 +157,7 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I assertEq(actualStatus, expectedStatus); } - function test_Cancel_CallerSender_RecipientReverts() + function test_Cancel_RecipientReverts() external whenNotDelegateCalled givenNotNull @@ -190,7 +165,6 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I whenCallerAuthorized givenStreamCancelable givenStatusStreaming - whenCallerSender givenRecipientContract givenRecipientImplementsHook { @@ -216,7 +190,7 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I assertEq(actualStatus, expectedStatus); } - function test_Cancel_CallerSender_RecipientReentrancy() + function test_Cancel_RecipientReentrancy() external whenNotDelegateCalled givenNotNull @@ -224,7 +198,6 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I whenCallerAuthorized givenStreamCancelable givenStatusStreaming - whenCallerSender givenRecipientContract givenRecipientImplementsHook whenRecipientDoesNotRevert @@ -251,7 +224,7 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I assertEq(actualStatus, expectedStatus); } - function test_Cancel_CallerSender() + function test_Cancel() external whenNotDelegateCalled givenNotNull @@ -259,7 +232,6 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I whenCallerAuthorized givenStreamCancelable givenStatusStreaming - whenCallerSender givenRecipientContract givenRecipientImplementsHook whenRecipientDoesNotRevert @@ -283,7 +255,7 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I // Expect the relevant events to be emitted. vm.expectEmit({ emitter: address(lockup) }); - emit CancelLockupStream(streamId, users.sender, address(goodRecipient), senderAmount, recipientAmount); + emit CancelLockupStream(streamId, users.sender, address(goodRecipient), dai, senderAmount, recipientAmount); vm.expectEmit({ emitter: address(lockup) }); emit MetadataUpdate({ _tokenId: streamId }); @@ -309,181 +281,4 @@ abstract contract Cancel_Integration_Concrete_Test is Integration_Test, Cancel_I address expectedNFTOwner = address(goodRecipient); assertEq(actualNFTOwner, expectedNFTOwner, "NFT owner"); } - - function test_Cancel_CallerRecipient_SenderNotContract() - external - whenNotDelegateCalled - givenNotNull - givenStreamWarm - whenCallerAuthorized - givenStreamCancelable - givenStatusStreaming - whenCallerRecipient - { - lockup.cancel(defaultStreamId); - Lockup.Status actualStatus = lockup.statusOf(defaultStreamId); - Lockup.Status expectedStatus = Lockup.Status.CANCELED; - assertEq(actualStatus, expectedStatus); - } - - function test_Cancel_CallerRecipient_SenderDoesNotImplementHook() - external - whenNotDelegateCalled - givenNotNull - givenStreamWarm - whenCallerAuthorized - givenStreamCancelable - givenStatusStreaming - whenCallerRecipient - givenSenderContract - { - // Create a stream with a no-op contract as the stream's sender. - uint256 streamId = createDefaultStreamWithSender(address(noop)); - - // Expect a call to the hook. - uint128 senderAmount = lockup.refundableAmountOf(streamId); - uint128 recipientAmount = lockup.withdrawableAmountOf(streamId); - vm.expectCall( - address(noop), - abi.encodeCall( - ISablierV2LockupSender.onStreamCanceled, (streamId, users.recipient, senderAmount, recipientAmount) - ) - ); - - // Cancel the stream. - lockup.cancel(streamId); - - // Assert that the stream's status is "CANCELED". - Lockup.Status actualStatus = lockup.statusOf(streamId); - Lockup.Status expectedStatus = Lockup.Status.CANCELED; - assertEq(actualStatus, expectedStatus); - } - - function test_Cancel_CallerRecipient_SenderReverts() - external - whenNotDelegateCalled - givenNotNull - givenStreamWarm - whenCallerAuthorized - givenStreamCancelable - givenStatusStreaming - whenCallerRecipient - givenSenderContract - givenSenderImplementsHook - { - // Create a stream with a reverting contract as the stream's sender. - uint256 streamId = createDefaultStreamWithSender(address(revertingSender)); - - // Expect a call to the hook. - uint128 senderAmount = lockup.refundableAmountOf(streamId); - uint128 recipientAmount = lockup.withdrawableAmountOf(streamId); - vm.expectCall( - address(revertingSender), - abi.encodeCall( - ISablierV2LockupSender.onStreamCanceled, (streamId, users.recipient, senderAmount, recipientAmount) - ) - ); - - // Cancel the stream. - lockup.cancel(streamId); - - // Assert that the stream's status is "CANCELED". - Lockup.Status actualStatus = lockup.statusOf(streamId); - Lockup.Status expectedStatus = Lockup.Status.CANCELED; - assertEq(actualStatus, expectedStatus); - } - - function test_Cancel_CallerRecipient_SenderReentrancy() - external - whenNotDelegateCalled - givenNotNull - givenStreamWarm - whenCallerAuthorized - givenStreamCancelable - givenStatusStreaming - whenCallerRecipient - givenSenderContract - givenSenderImplementsHook - whenSenderDoesNotRevert - { - // Create a stream with a reentrant contract as the stream's sender. - uint256 streamId = createDefaultStreamWithSender(address(reentrantSender)); - - // Expect a call to the hook. - uint128 senderAmount = lockup.refundableAmountOf(streamId); - uint128 recipientAmount = lockup.withdrawableAmountOf(streamId); - vm.expectCall( - address(reentrantSender), - abi.encodeCall( - ISablierV2LockupSender.onStreamCanceled, (streamId, users.recipient, senderAmount, recipientAmount) - ) - ); - - // Cancel the stream. - lockup.cancel(streamId); - - // Assert that the stream's status is "CANCELED". - Lockup.Status actualStatus = lockup.statusOf(streamId); - Lockup.Status expectedStatus = Lockup.Status.CANCELED; - assertEq(actualStatus, expectedStatus); - } - - function test_Cancel_CallerRecipient() - external - whenNotDelegateCalled - givenNotNull - givenStreamWarm - whenCallerAuthorized - givenStreamCancelable - givenStatusStreaming - whenCallerRecipient - givenSenderContract - givenSenderImplementsHook - whenSenderDoesNotRevert - whenNoSenderReentrancy - { - // Create the stream. - uint256 streamId = createDefaultStreamWithSender(address(goodSender)); - - // Expect the assets to be refunded to the sender contract. - uint128 senderAmount = lockup.refundableAmountOf(streamId); - expectCallToTransfer({ to: address(goodSender), amount: senderAmount }); - - // Expect a call to the hook. - uint128 recipientAmount = lockup.withdrawableAmountOf(streamId); - vm.expectCall( - address(goodSender), - abi.encodeCall( - ISablierV2LockupSender.onStreamCanceled, (streamId, users.recipient, senderAmount, recipientAmount) - ) - ); - - // Expect the relevant events to be emitted. - vm.expectEmit({ emitter: address(lockup) }); - emit CancelLockupStream(streamId, address(goodSender), users.recipient, senderAmount, recipientAmount); - vm.expectEmit({ emitter: address(lockup) }); - emit MetadataUpdate({ _tokenId: streamId }); - - // Cancel the stream. - lockup.cancel(streamId); - - // Assert that the stream's status is "CANCELED". - Lockup.Status actualStatus = lockup.statusOf(streamId); - Lockup.Status expectedStatus = Lockup.Status.CANCELED; - assertEq(actualStatus, expectedStatus); - - // Assert that the stream is not cancelable anymore. - bool isCancelable = lockup.isCancelable(streamId); - assertFalse(isCancelable, "isCancelable"); - - // Assert that the refunded amount has been updated. - uint128 actualRefundedAmount = lockup.getRefundedAmount(streamId); - uint128 expectedRefundedAmount = senderAmount; - assertEq(actualRefundedAmount, expectedRefundedAmount, "refundedAmount"); - - // Assert that the NFT has not been burned. - address actualNFTOwner = lockup.ownerOf({ tokenId: streamId }); - address expectedNFTOwner = users.recipient; - assertEq(actualNFTOwner, expectedNFTOwner, "NFT owner"); - } } diff --git a/test/integration/concrete/lockup/cancel/cancel.tree b/test/integration/concrete/lockup/cancel/cancel.tree index c1fda77c5..491c3f2e3 100644 --- a/test/integration/concrete/lockup/cancel/cancel.tree +++ b/test/integration/concrete/lockup/cancel/cancel.tree @@ -16,9 +16,7 @@ cancel.t.sol ├── when the caller is unauthorized │ ├── when the caller is a malicious third party │ │ └── it should revert - │ ├── when the caller is an approved third party - │ │ └── it should revert - │ └── when the caller is a former recipient + │ └── when the caller is the recipient │ └── it should revert └── when the caller is authorized ├── given the stream is not cancelable @@ -29,65 +27,34 @@ cancel.t.sol │ ├── it should mark the stream as depleted │ └── it should make the stream not cancelable └── given the stream's status is "STREAMING" - ├── when the caller is the sender - │ ├── given the recipient is not a contract - │ │ ├── it should cancel the stream - │ │ └── it should mark the stream as canceled - │ └── given the recipient is a contract - │ ├── given the recipient does not implement the hook - │ │ ├── it should cancel the stream - │ │ ├── it should mark the stream as canceled - │ │ ├── it should call the recipient hook - │ │ └── it should ignore the revert - │ └── given the recipient implements the hook - │ ├── when the recipient reverts - │ │ ├── it should cancel the stream - │ │ ├── it should mark the stream as canceled - │ │ ├── it should call the recipient hook - │ │ └── it should ignore the revert - │ └── when the recipient does not revert - │ ├── when there is reentrancy - │ │ ├── it should cancel the stream - │ │ ├── it should mark the stream as canceled - │ │ ├── it should call the recipient hook - │ │ └── it should ignore the revert - │ └── when there is no reentrancy - │ ├── it should cancel the stream - │ ├── it should mark the stream as canceled - │ ├── it should make the stream not cancelable - │ ├── it should update the refunded amount - │ ├── it should refund the sender - │ ├── it should call the recipient hook - │ ├── it should emit a {CancelLockupStream} event - │ └── it should emit a {MetadataUpdate} event - └── when the caller is the recipient - ├── given the sender is not a contract + ├── given the recipient is not a contract + │ ├── it should cancel the stream + │ └── it should mark the stream as canceled + └── given the recipient is a contract + ├── given the recipient does not implement the hook │ ├── it should cancel the stream - │ └── it should mark the stream as canceled - └── given the sender is a contract - ├── given the sender does not implement the hook - │ ├── it should cancel the stream - │ ├── it should mark the stream as canceled - │ ├── it should call the sender hook - │ └── it should ignore the revert - └── given the sender implements the hook - ├── when the sender reverts + │ ├── it should mark the stream as canceled + │ ├── it should call the recipient hook + │ └── it should ignore the revert + └── given the recipient implements the hook + ├── when the recipient reverts + │ ├── it should cancel the stream + │ ├── it should mark the stream as canceled + │ ├── it should call the recipient hook + │ └── it should ignore the revert + └── when the recipient does not revert + ├── when there is reentrancy │ ├── it should cancel the stream │ ├── it should mark the stream as canceled - │ ├── it should call the sender hook + │ ├── it should call the recipient hook │ └── it should ignore the revert - └── when the sender does not revert - ├── when there is reentrancy - │ ├── it should cancel the stream - │ ├── it should mark the stream as canceled - │ ├── it should call the sender hook - │ └── it should ignore the revert - └── when there is no reentrancy - ├── it should cancel the stream - ├── it should mark the stream as canceled - ├── it should make the stream not cancelable - ├── it should update the refunded amount - ├── it should refund the sender - ├── it should call the sender hook - ├── it should emit a {MetadataUpdate} event - └── it should emit a {CancelLockupStream} event + └── when there is no reentrancy + ├── it should cancel the stream + ├── it should mark the stream as canceled + ├── it should make the stream not cancelable + ├── it should update the refunded amount + ├── it should refund the sender + ├── it should call the recipient hook + ├── it should emit a {MetadataUpdate} event + └── it should emit a {CancelLockupStream} event + \ No newline at end of file diff --git a/test/integration/concrete/lockup/withdraw-max-and-transfer/withdrawMaxAndTransfer.t.sol b/test/integration/concrete/lockup/withdraw-max-and-transfer/withdrawMaxAndTransfer.t.sol index 9709e5827..5d2faa48d 100644 --- a/test/integration/concrete/lockup/withdraw-max-and-transfer/withdrawMaxAndTransfer.t.sol +++ b/test/integration/concrete/lockup/withdraw-max-and-transfer/withdrawMaxAndTransfer.t.sol @@ -100,7 +100,12 @@ abstract contract WithdrawMaxAndTransfer_Integration_Concrete_Test is // Expect the relevant events to be emitted. vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream({ streamId: defaultStreamId, to: users.recipient, amount: withdrawAmount }); + emit WithdrawFromLockupStream({ + streamId: defaultStreamId, + to: users.recipient, + amount: withdrawAmount, + asset: dai + }); vm.expectEmit({ emitter: address(lockup) }); emit Transfer({ from: users.recipient, to: users.alice, tokenId: defaultStreamId }); vm.expectEmit({ emitter: address(lockup) }); diff --git a/test/integration/concrete/lockup/withdraw-max/withdrawMax.t.sol b/test/integration/concrete/lockup/withdraw-max/withdrawMax.t.sol index e6f83c856..2721c5654 100644 --- a/test/integration/concrete/lockup/withdraw-max/withdrawMax.t.sol +++ b/test/integration/concrete/lockup/withdraw-max/withdrawMax.t.sol @@ -23,7 +23,8 @@ abstract contract WithdrawMax_Integration_Concrete_Test is Integration_Test, Wit emit WithdrawFromLockupStream({ streamId: defaultStreamId, to: users.recipient, - amount: defaults.DEPOSIT_AMOUNT() + amount: defaults.DEPOSIT_AMOUNT(), + asset: dai }); // Make the max withdrawal. @@ -61,7 +62,12 @@ abstract contract WithdrawMax_Integration_Concrete_Test is Integration_Test, Wit // Expect the relevant event to be emitted. vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream({ streamId: defaultStreamId, to: users.recipient, amount: withdrawAmount }); + emit WithdrawFromLockupStream({ + streamId: defaultStreamId, + to: users.recipient, + amount: withdrawAmount, + asset: dai + }); // Make the max withdrawal. lockup.withdrawMax({ streamId: defaultStreamId, to: users.recipient }); diff --git a/test/integration/concrete/lockup/withdraw-multiple/withdrawMultiple.t.sol b/test/integration/concrete/lockup/withdraw-multiple/withdrawMultiple.t.sol index 25eb3b761..33173b6a5 100644 --- a/test/integration/concrete/lockup/withdraw-multiple/withdrawMultiple.t.sol +++ b/test/integration/concrete/lockup/withdraw-multiple/withdrawMultiple.t.sol @@ -294,7 +294,7 @@ abstract contract WithdrawMultiple_Integration_Concrete_Test is vm.warp({ timestamp: earlyStopTime }); // Cancel the 3rd stream. - changePrank({ msgSender: users.recipient }); + changePrank({ msgSender: users.sender }); lockup.cancel(testStreamIds[2]); // Run the test with the caller provided in {whenCallerAuthorizedAllStreams}. @@ -307,11 +307,26 @@ abstract contract WithdrawMultiple_Integration_Concrete_Test is // Expect the relevant events to be emitted. vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream({ streamId: testStreamIds[0], to: users.recipient, amount: testAmounts[0] }); + emit WithdrawFromLockupStream({ + streamId: testStreamIds[0], + to: users.recipient, + asset: dai, + amount: testAmounts[0] + }); vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream({ streamId: testStreamIds[1], to: users.recipient, amount: testAmounts[1] }); + emit WithdrawFromLockupStream({ + streamId: testStreamIds[1], + to: users.recipient, + asset: dai, + amount: testAmounts[1] + }); vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream({ streamId: testStreamIds[2], to: users.recipient, amount: testAmounts[2] }); + emit WithdrawFromLockupStream({ + streamId: testStreamIds[2], + to: users.recipient, + asset: dai, + amount: testAmounts[2] + }); // Make the withdrawals. lockup.withdrawMultiple({ streamIds: testStreamIds, to: users.recipient, amounts: testAmounts }); diff --git a/test/integration/concrete/lockup/withdraw/withdraw.t.sol b/test/integration/concrete/lockup/withdraw/withdraw.t.sol index 88faa15d5..fbbeca2f6 100644 --- a/test/integration/concrete/lockup/withdraw/withdraw.t.sol +++ b/test/integration/concrete/lockup/withdraw/withdraw.t.sol @@ -296,7 +296,12 @@ abstract contract Withdraw_Integration_Concrete_Test is Integration_Test, Withdr // Expect the relevant event to be emitted. vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream({ streamId: defaultStreamId, to: users.recipient, amount: withdrawAmount }); + emit WithdrawFromLockupStream({ + streamId: defaultStreamId, + to: users.recipient, + asset: dai, + amount: withdrawAmount + }); // Make the withdrawal. lockup.withdraw({ streamId: defaultStreamId, to: users.recipient, amount: withdrawAmount }); @@ -491,7 +496,12 @@ abstract contract Withdraw_Integration_Concrete_Test is Integration_Test, Withdr // Expect the relevant events to be emitted. vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream({ streamId: streamId, to: address(goodRecipient), amount: withdrawAmount }); + emit WithdrawFromLockupStream({ + streamId: streamId, + to: address(goodRecipient), + asset: dai, + amount: withdrawAmount + }); vm.expectEmit({ emitter: address(lockup) }); emit MetadataUpdate({ _tokenId: streamId }); diff --git a/test/integration/concrete/nft-descriptor/generateAccentColor.t.sol b/test/integration/concrete/nft-descriptor/generateAccentColor.t.sol index f1edb0951..4e956be9c 100644 --- a/test/integration/concrete/nft-descriptor/generateAccentColor.t.sol +++ b/test/integration/concrete/nft-descriptor/generateAccentColor.t.sol @@ -7,7 +7,7 @@ contract GenerateAccentColor_Integration_Concrete_Test is NFTDescriptor_Integrat function test_GenerateAccentColor() external { // Passing a dummy contract instead of a real Sablier contract to make this test easy to maintain. string memory actualColor = nftDescriptorMock.generateAccentColor_({ sablier: address(noop), streamId: 1337 }); - string memory expectedColor = "hsl(6,51%,82%)"; + string memory expectedColor = "hsl(302,69%,44%)"; assertEq(actualColor, expectedColor, "accentColor"); } } diff --git a/test/integration/fuzz/lockup-dynamic/withdraw.t.sol b/test/integration/fuzz/lockup-dynamic/withdraw.t.sol index 04177f618..196ac96cb 100644 --- a/test/integration/fuzz/lockup-dynamic/withdraw.t.sol +++ b/test/integration/fuzz/lockup-dynamic/withdraw.t.sol @@ -98,7 +98,7 @@ contract Withdraw_LockupDynamic_Integration_Fuzz_Test is // Expect the relevant events to be emitted. vm.expectEmit({ emitter: address(lockupDynamic) }); - emit WithdrawFromLockupStream({ streamId: vars.streamId, to: params.to, amount: vars.withdrawAmount }); + emit WithdrawFromLockupStream({ streamId: vars.streamId, to: params.to, amount: vars.withdrawAmount, asset: dai }); vm.expectEmit({ emitter: address(lockupDynamic) }); emit MetadataUpdate({ _tokenId: vars.streamId }); diff --git a/test/integration/fuzz/lockup/cancel.t.sol b/test/integration/fuzz/lockup/cancel.t.sol index f83f7ec00..d59082cb5 100644 --- a/test/integration/fuzz/lockup/cancel.t.sol +++ b/test/integration/fuzz/lockup/cancel.t.sol @@ -41,7 +41,7 @@ abstract contract Cancel_Integration_Fuzz_Test is Integration_Test, Cancel_Integ /// /// - Multiple values for the current time /// - With and without withdrawals - function testFuzz_Cancel_CallerSender( + function testFuzz_Cancel( uint256 timeJump, uint128 withdrawAmount ) @@ -52,7 +52,6 @@ abstract contract Cancel_Integration_Fuzz_Test is Integration_Test, Cancel_Integ whenCallerAuthorized givenStreamCancelable givenStatusStreaming - whenCallerSender givenRecipientContract givenRecipientImplementsHook whenRecipientDoesNotRevert @@ -82,7 +81,7 @@ abstract contract Cancel_Integration_Fuzz_Test is Integration_Test, Cancel_Integ // Expect the relevant events to be emitted. uint128 recipientAmount = lockup.withdrawableAmountOf(streamId); vm.expectEmit({ emitter: address(lockup) }); - emit CancelLockupStream(streamId, users.sender, address(goodRecipient), senderAmount, recipientAmount); + emit CancelLockupStream(streamId, users.sender, address(goodRecipient), dai, senderAmount, recipientAmount); vm.expectEmit({ emitter: address(lockup) }); emit MetadataUpdate({ _tokenId: streamId }); @@ -103,69 +102,4 @@ abstract contract Cancel_Integration_Fuzz_Test is Integration_Test, Cancel_Integ address expectedNFTOwner = address(goodRecipient); assertEq(actualNFTOwner, expectedNFTOwner, "NFT owner"); } - - /// @dev Given enough fuzz runs, all of the following scenarios will be fuzzed: - /// - /// - Multiple values for the current time - /// - With and without withdrawals - function testFuzz_Cancel_CallerRecipient( - uint256 timeJump, - uint128 withdrawAmount - ) - external - whenNotDelegateCalled - givenNotNull - givenStreamWarm - whenCallerAuthorized - givenStreamCancelable - givenStatusStreaming - whenCallerRecipient - givenSenderContract - givenSenderImplementsHook - whenSenderDoesNotRevert - whenNoSenderReentrancy - { - timeJump = _bound(timeJump, defaults.CLIFF_DURATION(), defaults.TOTAL_DURATION() - 1); - - // Create the stream. - uint256 streamId = createDefaultStreamWithSender(address(goodSender)); - - // Simulate the passage of time. - vm.warp({ timestamp: defaults.START_TIME() + timeJump }); - - // Bound the withdraw amount. - uint128 streamedAmount = lockup.streamedAmountOf(streamId); - withdrawAmount = boundUint128(withdrawAmount, 0, streamedAmount - 1); - - // Make the withdrawal only if the amount is greater than zero. - if (withdrawAmount > 0) { - lockup.withdraw({ streamId: streamId, to: users.recipient, amount: withdrawAmount }); - } - - // Expect the assets to be refunded to the sender contract. - uint128 senderAmount = lockup.refundableAmountOf(streamId); - expectCallToTransfer({ to: address(goodSender), amount: senderAmount }); - - // Expect the relevant event to be emitted. - uint128 recipientAmount = lockup.withdrawableAmountOf(streamId); - vm.expectEmit({ emitter: address(lockup) }); - emit CancelLockupStream(streamId, address(goodSender), users.recipient, senderAmount, recipientAmount); - - // Cancel the stream. - lockup.cancel(streamId); - - // Assert that the stream's status is "CANCELED". - Lockup.Status actualStatus = lockup.statusOf(streamId); - Lockup.Status expectedStatus = Lockup.Status.CANCELED; - assertEq(actualStatus, expectedStatus); - - // Assert that the stream is not cancelable anymore. - bool isCancelable = lockup.isCancelable(streamId); - assertFalse(isCancelable, "isCancelable"); - - // Assert that the NFT has not been burned. - address actualNFTOwner = lockup.ownerOf({ tokenId: streamId }); - address expectedNFTOwner = users.recipient; - assertEq(actualNFTOwner, expectedNFTOwner, "NFT owner"); - } } diff --git a/test/integration/fuzz/lockup/cancelMultiple.t.sol b/test/integration/fuzz/lockup/cancelMultiple.t.sol index e78a71803..a5333106e 100644 --- a/test/integration/fuzz/lockup/cancelMultiple.t.sol +++ b/test/integration/fuzz/lockup/cancelMultiple.t.sol @@ -48,6 +48,7 @@ abstract contract CancelMultiple_Integration_Fuzz_Test is Integration_Test, Canc streamId: streamIds[0], sender: users.sender, recipient: users.recipient, + asset: dai, senderAmount: senderAmount0, recipientAmount: defaults.DEPOSIT_AMOUNT() - senderAmount0 }); @@ -56,6 +57,7 @@ abstract contract CancelMultiple_Integration_Fuzz_Test is Integration_Test, Canc streamId: streamIds[1], sender: users.sender, recipient: users.recipient, + asset: dai, senderAmount: senderAmount1, recipientAmount: defaults.DEPOSIT_AMOUNT() - senderAmount1 }); diff --git a/test/integration/fuzz/lockup/withdraw.t.sol b/test/integration/fuzz/lockup/withdraw.t.sol index fea5abecb..3ef2815c4 100644 --- a/test/integration/fuzz/lockup/withdraw.t.sol +++ b/test/integration/fuzz/lockup/withdraw.t.sol @@ -75,7 +75,9 @@ abstract contract Withdraw_Integration_Fuzz_Test is Integration_Test, Withdraw_I vm.warp({ timestamp: defaults.START_TIME() + timeJump }); // Cancel the stream. + changePrank({ msgSender: users.sender }); lockup.cancel({ streamId: defaultStreamId }); + changePrank({ msgSender: users.recipient }); // Bound the withdraw amount. uint128 withdrawableAmount = lockup.withdrawableAmountOf(defaultStreamId); @@ -86,7 +88,7 @@ abstract contract Withdraw_Integration_Fuzz_Test is Integration_Test, Withdraw_I // Expect the relevant events to be emitted. vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream(defaultStreamId, to, withdrawAmount); + emit WithdrawFromLockupStream(defaultStreamId, to, dai, withdrawAmount); vm.expectEmit({ emitter: address(lockup) }); emit MetadataUpdate({ _tokenId: defaultStreamId }); @@ -150,7 +152,7 @@ abstract contract Withdraw_Integration_Fuzz_Test is Integration_Test, Withdraw_I // Expect the relevant events to be emitted. vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream(defaultStreamId, to, withdrawAmount); + emit WithdrawFromLockupStream(defaultStreamId, to, dai, withdrawAmount); vm.expectEmit({ emitter: address(lockup) }); emit MetadataUpdate({ _tokenId: defaultStreamId }); diff --git a/test/integration/fuzz/lockup/withdrawMax.t.sol b/test/integration/fuzz/lockup/withdrawMax.t.sol index de6199755..60b631199 100644 --- a/test/integration/fuzz/lockup/withdrawMax.t.sol +++ b/test/integration/fuzz/lockup/withdrawMax.t.sol @@ -25,6 +25,7 @@ abstract contract WithdrawMax_Integration_Fuzz_Test is Integration_Test, Withdra emit WithdrawFromLockupStream({ streamId: defaultStreamId, to: users.recipient, + asset: dai, amount: defaults.DEPOSIT_AMOUNT() }); @@ -65,7 +66,12 @@ abstract contract WithdrawMax_Integration_Fuzz_Test is Integration_Test, Withdra // Expect the relevant event to be emitted. vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream({ streamId: defaultStreamId, to: users.recipient, amount: withdrawAmount }); + emit WithdrawFromLockupStream({ + streamId: defaultStreamId, + to: users.recipient, + asset: dai, + amount: withdrawAmount + }); // Make the max withdrawal. lockup.withdrawMax({ streamId: defaultStreamId, to: users.recipient }); diff --git a/test/integration/fuzz/lockup/withdrawMaxAndTransfer.t.sol b/test/integration/fuzz/lockup/withdrawMaxAndTransfer.t.sol index 00ddfca1d..8aef73118 100644 --- a/test/integration/fuzz/lockup/withdrawMaxAndTransfer.t.sol +++ b/test/integration/fuzz/lockup/withdrawMaxAndTransfer.t.sol @@ -42,7 +42,12 @@ abstract contract WithdrawMaxAndTransfer_Integration_Fuzz_Test is // Expect the relevant event to be emitted. vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream({ streamId: defaultStreamId, to: users.recipient, amount: withdrawAmount }); + emit WithdrawFromLockupStream({ + streamId: defaultStreamId, + to: users.recipient, + asset: dai, + amount: withdrawAmount + }); } // Expect the relevant event to be emitted. diff --git a/test/integration/fuzz/lockup/withdrawMultiple.t.sol b/test/integration/fuzz/lockup/withdrawMultiple.t.sol index 8b38c8cdd..eff464020 100644 --- a/test/integration/fuzz/lockup/withdrawMultiple.t.sol +++ b/test/integration/fuzz/lockup/withdrawMultiple.t.sol @@ -64,9 +64,9 @@ abstract contract WithdrawMultiple_Integration_Fuzz_Test is // Expect the relevant events to be emitted. vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream({ streamId: ongoingStreamId, to: to, amount: ongoingWithdrawAmount }); + emit WithdrawFromLockupStream({ streamId: ongoingStreamId, to: to, asset: dai, amount: ongoingWithdrawAmount }); vm.expectEmit({ emitter: address(lockup) }); - emit WithdrawFromLockupStream({ streamId: settledStreamId, to: to, amount: settledWithdrawAmount }); + emit WithdrawFromLockupStream({ streamId: settledStreamId, to: to, asset: dai, amount: settledWithdrawAmount }); // Make the withdrawals. uint256[] memory streamIds = Solarray.uint256s(ongoingStreamId, settledStreamId); diff --git a/test/integration/shared/lockup/cancel.t.sol b/test/integration/shared/lockup/cancel.t.sol index b808ab233..eba14f6ac 100644 --- a/test/integration/shared/lockup/cancel.t.sol +++ b/test/integration/shared/lockup/cancel.t.sol @@ -8,7 +8,7 @@ abstract contract Cancel_Integration_Shared_Test is Lockup_Integration_Shared_Te function setUp() public virtual override { defaultStreamId = createDefaultStream(); - changePrank({ msgSender: users.recipient }); + changePrank({ msgSender: users.sender }); } modifier whenNotDelegateCalled() { @@ -47,11 +47,6 @@ abstract contract Cancel_Integration_Shared_Test is Lockup_Integration_Shared_Te _; } - modifier whenCallerSender() { - changePrank({ msgSender: users.sender }); - _; - } - modifier givenRecipientContract() { _; } @@ -67,25 +62,4 @@ abstract contract Cancel_Integration_Shared_Test is Lockup_Integration_Shared_Te modifier whenNoRecipientReentrancy() { _; } - - modifier whenCallerRecipient() { - changePrank({ msgSender: users.recipient }); - _; - } - - modifier givenSenderContract() { - _; - } - - modifier givenSenderImplementsHook() { - _; - } - - modifier whenSenderDoesNotRevert() { - _; - } - - modifier whenNoSenderReentrancy() { - _; - } } diff --git a/test/integration/shared/lockup/cancelMultiple.t.sol b/test/integration/shared/lockup/cancelMultiple.t.sol index 6efc4de97..f5f366c8b 100644 --- a/test/integration/shared/lockup/cancelMultiple.t.sol +++ b/test/integration/shared/lockup/cancelMultiple.t.sol @@ -48,7 +48,7 @@ abstract contract CancelMultiple_Integration_Shared_Test is Lockup_Integration_S _; vm.warp({ timestamp: originalTime }); createTestStreams(); - changePrank({ msgSender: users.recipient }); + changePrank({ msgSender: users.sender }); _; } diff --git a/test/mocks/hooks/GoodSender.sol b/test/mocks/hooks/GoodSender.sol deleted file mode 100644 index 0710741d8..000000000 --- a/test/mocks/hooks/GoodSender.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; - -import { ISablierV2LockupSender } from "../../../src/interfaces/hooks/ISablierV2LockupSender.sol"; - -contract GoodSender is ISablierV2LockupSender { - function onStreamCanceled( - uint256 streamId, - address recipient, - uint128 senderAmount, - uint128 recipientAmount - ) - external - pure - { - streamId; - recipient; - senderAmount; - recipientAmount; - } -} diff --git a/test/mocks/hooks/ReentrantSender.sol b/test/mocks/hooks/ReentrantSender.sol deleted file mode 100644 index 10baf18e7..000000000 --- a/test/mocks/hooks/ReentrantSender.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; - -import { ISablierV2Lockup } from "../../../src/interfaces/ISablierV2Lockup.sol"; -import { ISablierV2LockupSender } from "../../../src/interfaces/hooks/ISablierV2LockupSender.sol"; - -contract ReentrantSender is ISablierV2LockupSender { - function onStreamCanceled( - uint256 streamId, - address recipient, - uint128 senderAmount, - uint128 recipientAmount - ) - external - { - streamId; - senderAmount; - recipient; - recipientAmount; - ISablierV2Lockup(msg.sender).cancel(streamId); - } -} diff --git a/test/mocks/hooks/RevertingSender.sol b/test/mocks/hooks/RevertingSender.sol deleted file mode 100644 index 1b4863d4e..000000000 --- a/test/mocks/hooks/RevertingSender.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; - -import { ISablierV2LockupSender } from "../../../src/interfaces/hooks/ISablierV2LockupSender.sol"; - -contract RevertingSender is ISablierV2LockupSender { - function onStreamCanceled( - uint256 streamId, - address recipient, - uint128 senderAmount, - uint128 recipientAmount - ) - external - pure - { - streamId; - recipient; - senderAmount; - recipientAmount; - revert("You shall not pass"); - } -} diff --git a/test/utils/Events.sol b/test/utils/Events.sol index f20981d0f..13192c7a9 100644 --- a/test/utils/Events.sol +++ b/test/utils/Events.sol @@ -69,9 +69,10 @@ abstract contract Events { //////////////////////////////////////////////////////////////////////////*/ event CancelLockupStream( - uint256 indexed streamId, + uint256 streamId, address indexed sender, address indexed recipient, + IERC20 indexed asset, uint128 senderAmount, uint128 recipientAmount ); @@ -82,7 +83,7 @@ abstract contract Events { address indexed admin, ISablierV2NFTDescriptor oldNFTDescriptor, ISablierV2NFTDescriptor newNFTDescriptor ); - event WithdrawFromLockupStream(uint256 indexed streamId, address indexed to, uint128 amount); + event WithdrawFromLockupStream(uint256 indexed streamId, address indexed to, IERC20 indexed asset, uint128 amount); /*////////////////////////////////////////////////////////////////////////// SABLIER-V2-LOCKUP-DYNAMIC diff --git a/test/utils/Precompiles.sol b/test/utils/Precompiles.sol index f6185614f..5fca66eed 100644 --- a/test/utils/Precompiles.sol +++ b/test/utils/Precompiles.sol @@ -27,9 +27,9 @@ contract Precompiles { bytes public constant BYTECODE_COMPTROLLER = hex"60803461009857601f6104a638819003918201601f19168301916001600160401b0383118484101761009d5780849260209460405283398101031261009857516001600160a01b0381169081900361009857600080546001600160a01b0319168217815560405191907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808180a36103f290816100b48239f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe608060408181526004918236101561001657600080fd5b600092833560e01c9182634d81e51d1461039d5750816375829def146102e5578163907a267b14610253578163b5b3ca2c146101ab578163cb01e30e146100f957508063dcf844a7146100c3578063e07df5b4146100a55763f851a4401461007d57600080fd5b346100a157816003193601126100a1576001600160a01b0360209254169051908152f35b5080fd5b50346100a157816003193601126100a1576020906001549051908152f35b50346100a15760203660031901126100a157806020926001600160a01b036100e96103d7565b1681526003845220549051908152f35b9050346101a75760203660031901126101a7576101146103d7565b6001600160a01b03918285541633810361017a575050169081835260026020528083209081549160ff8316159260ff84169060ff1916179055519081527f8cd3a7bc46b26a3b0c07a05a47af78abcaa647626f631d92ea64f8867b23bbec60203392a380f35b84516331b339a960e21b81526001600160a01b039091169181019182523360208301529081906040010390fd5b8280fd5b9050346101a757816003193601126101a7576101c56103d7565b90602435916001600160a01b039182865416338103610226575050907f371789a3d97098f3070492613273a065a7e8a19e009fd1ae92a4b4d4c71ed62d9116928385526003602052808520928084549455815193845260208401523392a380f35b85516331b339a960e21b81526001600160a01b039091169181019182523360208301529081906040010390fd5b919050346101a75760203660031901126101a7578135916001600160a01b038454163381036102b85750507fc059ba3e07a1c4d1fa8845bdb2af2dd85e844684e0a59e6073499e4338788465906001549280600155815193845260208401523392a280f35b82516331b339a960e21b81526001600160a01b039091169181019182523360208301529081906040010390fd5b919050346101a75760203660031901126101a7578135916001600160a01b03918284168094036103995784549283169033820361036d575050507fffffffffffffffffffffffff00000000000000000000000000000000000000001681178255337fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808380a380f35b516331b339a960e21b81526001600160a01b039091169181019182523360208301529081906040010390fd5b8480fd5b849084346101a75760203660031901126101a75760ff906020936001600160a01b036103c76103d7565b1681526002855220541615158152f35b600435906001600160a01b03821682036103ed57565b600080fd"; bytes public constant BYTECODE_LOCKUP_DYNAMIC = - hex"60c0346200046e57601f6200600238819003918201601f19168301916001600160401b038311848410176200032b578084926080946040528339810103126200046e5780516001600160a01b038082169290918390036200046e5760208101518281168091036200046e5760408201519183831683036200046e5760600151936200008962000473565b90601d82527f5361626c696572205632204c6f636b75702044796e616d6963204e46540000006020830152620000be62000473565b601181527029a0a116ab1916a627a1a5aaa816a22ca760791b602082015230608052600080546001600160a01b03199081168417825560018054909116909517909455927fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808180a38051906001600160401b0382116200032b5760035490600182811c9216801562000463575b60208310146200044d5781601f849311620003d8575b50602090601f83116001146200034d5760009262000341575b50508160011b916000199060031b1c1916176003555b80516001600160401b0381116200032b576004918254600181811c9116801562000320575b60208210146200030b579081601f849311620002b3575b50602090601f831160011462000248576000926200023c575b50508160011b916000199060031b1c19161790555b1660018060a01b0319600a541617600a5560a0526001600955604051615b6e9081620004948239608051816155de015260a0518181816112850152614b330152f35b015190503880620001e5565b6000858152602081209350601f198516905b8181106200029a575090846001959493921062000280575b505050811b019055620001fa565b015160001960f88460031b161c1916905538808062000272565b929360206001819287860151815501950193016200025a565b909150836000526020600020601f840160051c8101916020851062000300575b90601f859493920160051c01905b818110620002f05750620001cc565b60008155849350600101620002e1565b9091508190620002d3565b602284634e487b7160e01b6000525260246000fd5b90607f1690620001b5565b634e487b7160e01b600052604160045260246000fd5b0151905038806200017a565b600360009081527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b9350601f198516905b818110620003bf5750908460019594939210620003a5575b505050811b0160035562000190565b015160001960f88460031b161c1916905538808062000396565b929360206001819287860151815501950193016200037e565b60036000529091507fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b601f840160051c8101916020851062000442575b90601f859493920160051c01905b81811062000432575062000161565b6000815584935060010162000423565b909150819062000415565b634e487b7160e01b600052602260045260246000fd5b91607f16916200014b565b600080fd5b60408051919082016001600160401b038111838210176200032b5760405256fe608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a714612c365750806306fdde0314612b73578063081812fc14612b55578063095ea7b3146129c15780631400ecec1461291c57806316844456146126a15780631c1cdd4c1461263b5780631e99d5691461261d57806323b872dd146125f457806339a73c03146125b157806340e58ee514612219578063425d30dd146121fb57806342842e0e146121ab57806342966c681461204d5780634857501f14611fd75780634869e12d14611f9b5780635fe3b56714611f745780636352211e14611f455780636d0cee7514611eed57806370a0823114611e4357806375829def14611db15780637cad6cd114611cdf5780637de6b1db14611ab65780638659c27014611667578063894e9a0d146113fa5780638bad38dd1461137e5780638f69b993146112fb5780639067b677146112a85780639188ec841461126d57806395d89b411461115f578063a22cb4651461108e578063a2ffb89714610f95578063a6202bf214610e95578063a80fc07114610e40578063ad35efd414610ddd578063b256456914610dbf578063b637b86514610d5f578063b88d4fde14610cd4578063b8a3be6614610c9d578063b971302a14610c4b578063bc063e1a14610c28578063bc2be1be14610bd5578063c156a11d14610ae7578063c33cd35e146109d2578063c87b56dd1461089f578063cc364f4814610805578063d4dbd20b146107b0578063d511609f14610761578063d975dfed14610714578063e985e9c5146106bd578063ea5ead191461066c578063eac8f5b814610600578063f590c176146105d8578063f851a440146105b15763fdd46d601461027c57600080fd5b346104a65760603660031901126104a657600435610298612d63565b6001600160801b036044358181169391928482036104a6576102b86155d4565b6102c183613651565b610599576102e583600052600b6020526001600160a01b0360406000205416331490565b90811580610589575b6105665783600052602094600586526001600160a01b03908160406000205416938061055a575b6105345781831694851561052357881561050b578161033388615696565b16808a116104e75750916103ca939161038f6103638b958a600052600b8c5260026040600020015460801c61597e565b89600052600b8b52600260406000200190836001600160801b031983549260801b1691161781556135e6565b906103ab818b8401511692826040818351169201511690613688565b1611156104b5575b86600052600b885260016040600020015416615630565b80331415806104ab575b61041d575b50817ffa54f9f9bdcdd28778cbb9f78490df6691cc4e2729588e10f4cc0a26c465686a84600080516020615b4283398151915296604051908152a3604051908152a1005b803b156104a6577ffa54f9f9bdcdd28778cbb9f78490df6691cc4e2729588e10f4cc0a26c465686a84600080516020615b428339815191529660008087956084604051809481936313375c3b60e01b83528a60048401523360248401528b60448401528760648401525af1610497575b50965050506103d9565b6104a090612ed6565b3861048d565b600080fd5b50803b15156103d4565b86600052600b8852604060002060018101600160a01b60ff60a01b1982541617905560ff60f01b1981541690556103b3565b876064918b6040519263287ecaef60e21b8452600484015260248301526044820152fd5b6024876040519063d2aabcd960e01b82526004820152fd5b600460405163630d074f60e11b8152fd5b606486838560405192632dcbf6b960e11b84526004840152336024840152166044820152fd5b50838284161415610315565b60405163216caf0d60e01b815260048101859052336024820152604490fd5b0390fd5b5061059384615999565b156102ee565b60248360405190634a5541ef60e01b82526004820152fd5b346104a65760003660031901126104a65760206001600160a01b0360005416604051908152f35b346104a65760203660031901126104a65760206105f66004356136a1565b6040519015158152f35b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557600052600b60205260206001600160a01b0360016040600020015416604051908152f35b6024906040519062b8e7e760e51b82526004820152fd5b346104a65760403660031901126104a657600080516020615b4283398151915260206004356106b461069c612d63565b6106a583615696565b906106ae6155d4565b836156ce565b604051908152a1005b346104a65760403660031901126104a6576106d6612d4d565b6106de612d63565b906001600160a01b03809116600052600860205260406000209116600052602052602060ff604060002054166040519015158152f35b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557610750602091615696565b6001600160801b0360405191168152f35b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557600052600b602052602060026040600020015460801c604051908152f35b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557600052600b60205260206001600160801b0360036040600020015416604051908152f35b346104a65760203660031901126104a6576004356000602060405161082981612e9d565b828152015280600052600b60205260ff60016040600020015460a81c161561065557600052600b6020526040806000205464ffffffffff82519161086c83612e9d565b818160a01c16835260c81c16602082015261089d825180926020908164ffffffffff91828151168552015116910152565bf35b346104a6576020806003193601126104a657600435906108dd6108d88360005260056020526001600160a01b0360406000205416151590565b612f3c565b60006001600160a01b03600a5416926044604051809581937fe9dc637500000000000000000000000000000000000000000000000000000000835230600484015260248301525afa9182156109c65760009261094d575b50610949604051928284938452830190612d28565b0390f35b9091503d806000833e6109608183612eea565b81019082818303126104a65780519067ffffffffffffffff82116104a6570181601f820112156104a657805161099581612f0c565b926109a36040519485612eea565b8184528482840101116104a6576109bf91848085019101612d05565b9082610934565b6040513d6000823e3d90fd5b346104a6576003196020368201126104a6576004359067ffffffffffffffff908183116104a6576101409083360301126104a657610a0e6155d4565b60405191610a1b83612e80565b610a2781600401612d79565b8352610a35602482016136d2565b6020840152610a4660448201612e57565b6040840152610a5760648201612e57565b6060840152610a6860848201612d79565b6080840152610a7960a48201612f28565b60a0840152610a8a60c48201612d79565b60c0840152610a9c3660e483016137b8565b60e08401526101248101359182116104a65701366023820112156104a657602091610ad4610adf9236906024600482013591016136e4565b610100820152614a84565b604051908152f35b346104a65760403660031901126104a657600435610b03612d63565b610b0b6155d4565b81600052600b60205260ff60016040600020015460a81c1615610bbe578160005260056020526001600160a01b0360406000205416803303610b9f57916106b481602093600080516020615b4283398151915295610b6883615696565b6001600160801b038116610b7d575b506131cf565b610b9090610b896155d4565b82856156ce565b8686604051858152a187610b77565b60405163216caf0d60e01b815260048101849052336024820152604490fd5b6024826040519062b8e7e760e51b82526004820152fd5b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557600052600b602052602064ffffffffff60406000205460a01c16604051908152f35b346104a65760003660031901126104a657602060405167016345785d8a00008152f35b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557600052600b60205260206001600160a01b0360406000205416604051908152f35b346104a65760203660031901126104a657600435600052600b602052602060ff60016040600020015460a81c166040519015158152f35b346104a65760803660031901126104a657610ced612d4d565b610cf5612d63565b6064359167ffffffffffffffff83116104a657366023840112156104a657826004013591610d2283612f0c565b92610d306040519485612eea565b80845236602482870101116104a6576020816000926024610d5d980183880137850101526044359161305a565b005b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557600052600b602052610949610dab6004604060002001613539565b604051918291602083526020830190612df3565b346104a65760203660031901126104a65760206105f660043561361a565b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557610e1790614988565b6040516005821015610e2a576020918152f35b634e487b7160e01b600052602160045260246000fd5b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557600052600b60205260206001600160801b0360026040600020015416604051908152f35b346104a65760203660031901126104a657610eae612d4d565b6001600160a01b038060005416338103610f6c57508116908160005260026020526001600160801b0360406000205416908115610f3b5781610f0d9184600052600260205260406000206001600160801b031981541690553390615630565b6040519081527fca7a4a65a94ed2f37538814e00e1cd4c41a78261561e3f3794592f11409cf5af60203392a3005b602483604051907f8410168c0000000000000000000000000000000000000000000000000000000082526004820152fd5b6040516331b339a960e21b81526001600160a01b03919091166004820152336024820152604490fd5b346104a65760603660031901126104a65767ffffffffffffffff6004358181116104a657610fc7903690600401612dc2565b610fcf612d63565b926044359081116104a657610fe8903690600401612dc2565b9190610ff26155d4565b8282036110575760005b82811061100557005b80600080516020615b428339815191526020611024600194878a6156be565b3561104a61103b611036868b8a6156be565b6137a4565b6110436155d4565b8b836156ce565b604051908152a101610ffc565b50604491604051917faec9344000000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b346104a65760403660031901126104a6576110a7612d4d565b602435908115158092036104a6576001600160a01b03169081331461111b57336000526008602052604060002082600052602052604060002060ff1981541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b606460405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152fd5b346104a65760003660031901126104a657604051600060045490600182811c91818416918215611263575b602094858510841461124d57858794868652918260001461122d5750506001146111d0575b506111bc92500383612eea565b610949604051928284938452830190612d28565b84915060046000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b906000915b8583106112155750506111bc9350820101856111af565b805483890185015287945086939092019181016111fe565b60ff1916858201526111bc95151560051b85010192508791506111af9050565b634e487b7160e01b600052602260045260246000fd5b92607f169261118a565b346104a65760003660031901126104a65760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557600052600b602052602064ffffffffff60406000205460c81c16604051908152f35b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c16156106555761133590614988565b600581101580610e2a5760028214908115611371575b811561135f575b6020826040519015158152f35b9050610e2a5760046020911482611352565b505060038114600061134b565b346104a65760203660031901126104a6576004356001600160a01b03908181168091036104a6578160005416338103610f6c575060015491816001600160a01b03198416176001556040519216825260208201527fdcb09aef4bf01068924ccce937981cbe59d25ba08380cf941aaaea4e4bd3960d60403392a2005b346104a65760203660031901126104a657606061014060405161141c81612eb9565b60008152600060208201526000604082015260008382015260006080820152600060a0820152600060c0820152600060e082015260006101008201526114606135c7565b6101208201520152600435600052600b60205260ff60016040600020015460a81c161561164f57600435600052600b60205260406000206115436004604051926114a984612eb9565b80546001600160a01b038116855264ffffffffff8160a01c16602086015264ffffffffff8160c81c16604086015260ff8160f01c161515606086015260f81c1515608085015260ff60018201546001600160a01b03811660a0870152818160a01c16151560c0870152818160a81c16151560e087015260b01c161515610100850152611537600282016135e6565b61012085015201613539565b610140820152611554600435614988565b906005821015610e2a5760026101409214611643575b610949604051928392602084526001600160a01b03815116602085015264ffffffffff602082015116604085015264ffffffffff60408201511660608501526060810151151560808501526080810151151560a08501526001600160a01b0360a08201511660c085015260c0810151151560e085015260e08101511515610100850152610100810151151561012085015261162f61012082015183860190604090816001600160801b0391828151168552826020820151166020860152015116910152565b01516101a0808401526101c0830190612df3565b6000606082015261156a565b602460405162b8e7e760e51b81526004356004820152fd5b346104a6576020806003193601126104a65760043567ffffffffffffffff81116104a657611699903690600401612dc2565b906116a26155d4565b6000915b8083106116af57005b6116ba8382846156be565b35926116c46155d4565b6116cd84613651565b156116ea5760248460405190634a5541ef60e01b82526004820152fd5b6116f6849293946136a1565b611a9e5761171a82600052600b6020526001600160a01b0360406000205416331490565b1580611a7e575b611a5f5761172e826137e7565b82600052600b9283875261174860026040600020016135e6565b936001600160801b0392838651168482161015611a47578260005281895260ff60406000205460f01c1615611a2f579061179782858b61178d819796838c5116613688565b9901511690613688565b93826000528184526040600020966003885498600160f81b7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8b1617815583881615611a15575b0191811691826001600160801b03198254161790556118216001600160a01b03809916926005875289604060002054169487528360019a8b6040600020015416615630565b33820361193257823b61188e575b7f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd2600080516020615b428339815191529685925b604080516001600160801b03928316815292909116602083015290a4604051908152a10191906116a6565b9350813b156104a6576040516372eba20360e01b8152600481018490526001600160a01b03821660248201526001600160801b03858116604483015286166064820152600080516020615b42833981519152958b9585927f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd2929190600081608481838b5af1611923575b50925096505061182f565b61192c90612ed6565b8e611918565b813b611971575b7f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd2600080516020615b42833981519152968592611863565b9350803b156104a6576040516372eba20360e01b8152600481018490526001600160a01b03831660248201526001600160801b03858116604483015286166064820152600080516020615b42833981519152958b9585927f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd2929190600081608481838a5af1611a06575b509250965050611939565b611a0f90612ed6565b8e6119fb565b60018101600160a01b60ff60a01b198254161790556117dc565b602483604051906339c6dc7360e21b82526004820152fd5b602483604051906322cad1af60e11b82526004820152fd5b60405163216caf0d60e01b815260048101839052336024820152604490fd5b5081600052600585526001600160a01b0360406000205416331415611721565b6024826040519063fe19f19f60e01b82526004820152fd5b346104a6576020806003193601126104a657600435611ad36155d4565b80600052600b825260ff60016040600020015460a81c161561065557611af881614988565b916000926005811015610e2a5760048103611b255760248360405190634a5541ef60e01b82526004820152fd5b60038103611b45576024836040519063fe19f19f60e01b82526004820152fd5b916002849314611cc757611b6f81600052600b6020526001600160a01b0360406000205416331490565b15611ca75780600052600b825260ff60406000205460f01c1615611c8f5780600052600b8252604060002060ff60f01b198154169055600582526001600160a01b0360406000205416803b611bfd575b50807f0eb069207093cd3e51cd1370d2d369770057fbe29947e577e5fb428c6c6fc78f84600080516020615b4283398151915295a2604051908152a1005b803b156104a657600080516020615b428339815191529360008084936024604051809481937f341a0bd90000000000000000000000000000000000000000000000000000000083528860048401525af1611c5a575b509350611bbf565b9050611c669150612ed6565b8060007f0eb069207093cd3e51cd1370d2d369770057fbe29947e577e5fb428c6c6fc78f611c52565b602490604051906339c6dc7360e21b82526004820152fd5b60405163216caf0d60e01b81526004810191909152336024820152604490fd5b602490604051906322cad1af60e11b82526004820152fd5b346104a65760203660031901126104a6576004356001600160a01b03908181168091036104a6578160005416338103610f6c5750600a5491816001600160a01b0319841617600a556040519216825260208201527fa2548bd4b805e907c1558a47b5858324fe8bb4a2e1ddfca647eecbf65610eebc60403392a26009546000198101908111611d9b5760407f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c91815190600182526020820152a1005b634e487b7160e01b600052601160045260246000fd5b346104a65760203660031901126104a657611dca612d4d565b6000546001600160a01b0380821692338403611e1c576001600160a01b03199350169182911617600055337fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80600080a3005b6040516331b339a960e21b81526001600160a01b0385166004820152336024820152604490fd5b346104a65760203660031901126104a6576001600160a01b03611e64612d4d565b168015611e835760005260066020526020604060002054604051908152f35b608460405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152fd5b346104a65760203660031901126104a657600435611f246108d88260005260056020526001600160a01b0360406000205416151590565b600052600560205260206001600160a01b0360406000205416604051908152f35b346104a65760203660031901126104a6576020611f63600435612f87565b6001600160a01b0360405191168152f35b346104a65760003660031901126104a65760206001600160a01b0360015416604051908152f35b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557610750602091614a09565b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c161561065557600061201382614988565b6005811015610e2a57600203612031575b6020906040519015158152f35b50600052600b602052602060ff60406000205460f01c16612024565b346104a65760203660031901126104a6576004356120696155d4565b61207281613651565b1561217a5761208081615999565b15611ca75761208e81612f87565b6120978261361a565b159081612171575b8161215e575b50612146576020816120c5600080516020615b4283398151915293612f87565b9080600052600783526001600160a01b036040600020926001600160a01b031993848154169055169182600052600684526040600020600019815401905581600052600584526040600020908154169055806000604051937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a48152a1005b602490604051906378630aa960e01b82526004820152fd5b6001600160a01b039150161515826120a5565b6000915061209f565b602490604051907f817cd6390000000000000000000000000000000000000000000000000000000082526004820152fd5b346104a6576121b936612d8d565b60405191602083019383851067ffffffffffffffff8611176121e557610d5d946040526000845261305a565b634e487b7160e01b600052604160045260246000fd5b346104a65760203660031901126104a65760206105f6600435613651565b346104a6576020806003193601126104a657600435906122376155d4565b61224082613651565b1561225d5760248260405190634a5541ef60e01b82526004820152fd5b612266826136a1565b611a9e5761228a82600052600b6020526001600160a01b0360406000205416331490565b1580612591575b611a5f5761229e826137e7565b9180600052600b82526122b760026040600020016135e6565b926001600160801b0390818551168282161015611a475782600052600b845260ff60406000205460f01c1615611a2f578082856122fa61230494838a5116613688565b9701511690613688565b9082600052600b84526040600020916003835493600160f81b7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff861617815583831615612577575b0191861691826001600160801b031982541617905561238f6001600160a01b03809416926005875283856040600020541695600b895260016040600020015416615630565b33820361249757823b6123f6575b7f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd28491600080516020615b42833981519152975b604080516001600160801b03928316815292909116602083015290a4604051908152a1005b823b156104a6576040516372eba20360e01b8152600481018590526001600160a01b03831660248201526001600160801b03878116604483015282166064820152600080516020615b428339815191529685927f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd292909190600081608481838b5af1612488575b50975091505061239d565b61249190612ed6565b8961247d565b813b6124d6575b7f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd28491600080516020615b42833981519152976123d1565b813b156104a6576040516372eba20360e01b8152600481018590526001600160a01b03841660248201526001600160801b03878116604483015282166064820152600080516020615b428339815191529685927f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd292909190600081608481838a5af1612568575b50975091505061249e565b61257190612ed6565b8961255d565b60018101600160a01b60ff60a01b1982541617905561234a565b5081600052600581526001600160a01b0360406000205416331415612291565b346104a65760203660031901126104a6576001600160a01b036125d2612d4d565b16600052600260205260206001600160801b0360406000205416604051908152f35b346104a657610d5d61260536612d8d565b9161261861261384336130f0565b612fe9565b6131cf565b346104a65760003660031901126104a6576020600954604051908152f35b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c16156106555761267590614988565b6005811015610e2a578060209115908115612696575b506040519015158152f35b60019150148261268b565b346104a657602060031981813601126104a6576004359067ffffffffffffffff908183116104a657610120833603918201126104a6576126df6155d4565b61010483013590602219018112156104a65782016004810135908282116104a65760240160608202360381136104a65761271a9136916136e4565b9182519061272782613521565b916127356040519384612eea565b808352601f1961274482613521565b018660005b8281106129065750505064ffffffffff90814216946001600160801b03968761277182613852565b515116828a61277f84613852565b510151168580604061279086613852565b510151168a011690604051926127a584612e64565b83528b83015260408201526127b987613852565b526127c386613852565b5060019386855b8a8c87831061288557908b846001600160a01b038c60a4810135828116908190036104a657610adf95612845956128759461280760248601613783565b61281360448701613783565b61281f60648801613790565b9161282c88600401613790565b948461283a60848b016137a4565b966040519d8e612e80565b168c528d8c0152151560408b0152151560608a01521660808801521660a086015260c085015260c43691016137b8565b60e0830152610100820152614a84565b8893858060406128b98b866128a98a8e9a6128a0828d613875565b5151169a613875565b5101511694600019890190613875565b510151168160406128ca888c613875565b51015116011691604051936128de85612e64565b845283015260408201526128f2828b613875565b526128fd818a613875565b500187906127ca565b61290e6135c7565b828288010152018790612749565b346104a65760203660031901126104a65760043580600052600b60205260ff60016040600020015460a81c16156106555760209060009080600052600b8352604060002060ff815460f01c16806129af575b612986575b50506001600160801b0360405191168152f35b6129a892506001600160801b0360026129a292015416916137e7565b90613688565b8280612973565b5060ff600182015460a01c161561296e565b346104a65760403660031901126104a6576129da612d4d565b602435906001600160a01b0380806129f185612f87565b16921691808314612aeb57803314908115612ac6575b5015612a5c578260005260076020526040600020826001600160a01b0319825416179055612a3483612f87565b167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600080a4005b608460405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152fd5b9050600052600860205260406000203360005260205260ff6040600020541684612a07565b608460405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152fd5b346104a65760203660031901126104a6576020611f63600435612fac565b346104a65760003660031901126104a657604051600060035490600182811c91818416918215612c2c575b602094858510841461124d57858794868652918260001461122d575050600114612bcf57506111bc92500383612eea565b84915060036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b906000915b858310612c145750506111bc9350820101856111af565b80548389018501528794508693909201918101612bfd565b92607f1692612b9e565b346104a65760203660031901126104a657600435907fffffffff0000000000000000000000000000000000000000000000000000000082168092036104a657817f80ac58cd0000000000000000000000000000000000000000000000000000000060209314908115612cdb575b8115612cb1575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483612caa565b7f5b5e139f0000000000000000000000000000000000000000000000000000000081149150612ca3565b60005b838110612d185750506000910152565b8181015183820152602001612d08565b90602091612d4181518092818552858086019101612d05565b601f01601f1916010190565b600435906001600160a01b03821682036104a657565b602435906001600160a01b03821682036104a657565b35906001600160a01b03821682036104a657565b60609060031901126104a6576001600160a01b039060043582811681036104a6579160243590811681036104a6579060443590565b9181601f840112156104a65782359167ffffffffffffffff83116104a6576020808501948460051b0101116104a657565b90815180825260208080930193019160005b828110612e13575050505090565b835180516001600160801b031686528083015167ffffffffffffffff168684015260409081015164ffffffffff169086015260609094019392810192600101612e05565b359081151582036104a657565b6060810190811067ffffffffffffffff8211176121e557604052565b610120810190811067ffffffffffffffff8211176121e557604052565b6040810190811067ffffffffffffffff8211176121e557604052565b610160810190811067ffffffffffffffff8211176121e557604052565b67ffffffffffffffff81116121e557604052565b90601f8019910116810190811067ffffffffffffffff8211176121e557604052565b67ffffffffffffffff81116121e557601f01601f191660200190565b35906001600160801b03821682036104a657565b15612f4357565b606460405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152fd5b60005260056020526001600160a01b0360406000205416612fa9811515612f3c565b90565b612fcf6108d88260005260056020526001600160a01b0360406000205416151590565b60005260076020526001600160a01b036040600020541690565b15612ff057565b608460405162461bcd60e51b815260206004820152602d60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206f7220617070726f766564000000000000000000000000000000000000006064820152fd5b9061307e93929161306e61261384336130f0565b6130798383836131cf565b613388565b1561308557565b60405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608490fd5b906001600160a01b03808061310484612f87565b16931691838314938415613137575b508315613121575b50505090565b61312d91929350612fac565b161438808061311b565b909350600052600860205260406000208260005260205260ff604060002054169238613113565b1561316557565b608460405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152fd5b906131f892916131de83612f87565b916001600160a01b0394859384809416968791161461315e565b16908115806132ef5761320a8461361a565b1590816132e6575b50806132dd575b6132c55791808492613247600080516020615b428339815191529660209661324085612f87565b161461315e565b60009382855260078652604085206001600160a01b031990818154169055818652600687526040862060001981540190558286526040862060018154019055838652600587528260408720918254161790557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6040519580a48152a1565b602483604051906378630aa960e01b82526004820152fd5b50831515613219565b90501538613212565b608460405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152fd5b3d15613383573d9061336982612f0c565b916133776040519384612eea565b82523d6000602084013e565b606090565b9290803b15613518576133f2916020916001600160a01b0394604051809581948293897f150b7a02000000000000000000000000000000000000000000000000000000009b8c86523360048701521660248501526044840152608060648401526084830190612d28565b03916000968791165af1908290826134b1575b505061348b57613413613358565b805190816134865760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608490fd5b602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000161490565b909192506020813d8211613510575b816134cd60209383612eea565b8101031261350c5751907fffffffff00000000000000000000000000000000000000000000000000000000821682036135095750903880613405565b80fd5b5080fd5b3d91506134c0565b50505050600190565b67ffffffffffffffff81116121e55760051b60200190565b90815461354581613521565b9260409361355585519182612eea565b828152809460208092019260005281600020906000935b85851061357b57505050505050565b6001848192845161358b81612e64565b64ffffffffff87546001600160801b038116835267ffffffffffffffff8160801c168584015260c01c168682015281520193019401939161356c565b604051906135d482612e64565b60006040838281528260208201520152565b906040516135f381612e64565b6040819360018154916001600160801b0392838116865260801c6020860152015416910152565b80600052600b60205260ff60016040600020015460a81c161561065557600052600b60205260ff60016040600020015460b01c1690565b80600052600b60205260ff60016040600020015460a81c161561065557600052600b60205260ff60016040600020015460a01c1690565b6001600160801b039182169082160391908211611d9b57565b80600052600b60205260ff60016040600020015460a81c161561065557600052600b60205260406000205460f81c90565b359064ffffffffff821682036104a657565b9291926136f082613521565b6040946136ff86519283612eea565b819584835260208093019160608096028501948186116104a657925b85841061372b5750505050505050565b86848303126104a65782519061374082612e64565b61374985612f28565b8252858501359067ffffffffffffffff821682036104a657828792838b9501526137748688016136d2565b8682015281520193019261371b565b3580151581036104a65790565b356001600160a01b03811681036104a65790565b356001600160801b03811681036104a65790565b91908260409103126104a6576040516137d081612e9d565b60208082946137de81612d79565b84520135910152565b64ffffffffff80421682600052600b602052604060002091825482828260a01c1610156138485760c81c16111561383657600401546001101561382d57612fa990613889565b612fa9906148b9565b6001600160801b039150600201541690565b5050505050600090565b80511561385f5760200190565b634e487b7160e01b600052603260045260246000fd5b805182101561385f5760209160051b010190565b64ffffffffff90814216906000908152600b6020526040908181208251936138b085612eb9565b8154956001600160a01b039182881687526020870197828160a01c168952828160c81c168789015260ff8160f01c161515606089015260f81c1515608088015260ff6001938486015490811660a08a0152818160a01c16151560c08a0152818160a81c16151560e08a015260b01c16151561010088015261014061394a600461393b600288016135e6565b966101208b0197885201613539565b970191878352808761395c889a613852565b5101511693828288965b1610613a405750916139f06139f5928488816139fa98976001600160801b039e8f6139928b8a51613875565b5151169d8a8f9b60206139af67ffffffffffffffff928d51613875565b510151169984836139c1848451613875565b5101511696508115613a34576139df92935051906000190190613875565b5101511680925b0316920316613ab4565b613e23565b613c86565b928313613a13575050613a0d8391613a78565b16011690565b516020015192939283169284168310159150613a2f9050575090565b905090565b505050511680926139e6565b8094986001600160801b039081613a588c8851613875565b51511601169801938282808a613a6f898951613875565b51015116613966565b60008112613a835790565b602490604051907f2463f3d50000000000000000000000000000000000000000000000000000000082526004820152fd5b90600160ff1b808314908115613b9c575b50613b72576000821215613b6957613aee826000035b6000831215613b62578260000390613ba6565b917f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311613b2c5760009160001991181315613b28575090565b0390565b604491604051917fd49c26b300000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b8290613ba6565b613aee82613adb565b60046040517f9fe2b450000000000000000000000000000000000000000000000000000000008152fd5b9050811438613ac5565b670de0b6b3a7640000916000198383099280830292838086109503948086039514613c625782851015613c2657908291096001821901821680920460028082600302188083028203028083028203028083028203028083028203028083028203028092029003029360018380600003040190848311900302920304170290565b82606492604051927f63a05778000000000000000000000000000000000000000000000000000000008452600484015260248301526044820152fd5b505080925015613c70570490565b634e487b7160e01b600052601260045260246000fd5b90600160ff1b808314908115613d6a575b50613d40576000821215613d3757613cc0826000035b6000831215613d30578260000390613d74565b917f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311613cfa5760009160001991181315613b28575090565b604491604051917f120b5b4300000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b8290613d74565b613cc082613cad565b60046040517fa6070c25000000000000000000000000000000000000000000000000000000008152fd5b9050811438613c97565b90919060001983820983820291828083109203918083039214613e1257670de0b6b3a76400009081831015613ddb57947faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac1066994950990828211900360ee1b910360121c170290565b60449086604051917f5173648d00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b5050670de0b6b3a764000090049150565b80613e3d5750600090612fa95750670de0b6b3a764000090565b90670de0b6b3a7640000808314613e8a575080613e62575050670de0b6b3a764000090565b670de0b6b3a76400008114613e8657613e81906139f5612fa993614764565b613eaa565b5090565b91505090565b8015613c70576ec097ce7bc90715b34b9f10000000000590565b6000811215613edf5768033dd1780914b97114198112613ed957613ed090600003613eaa565b612fa990613e90565b50600090565b680a688906bd8affffff811361473357670de0b6b3a764000080604092831b05907780000000000000000000000000000000000000000000000067ff000000000000008316614616575b66ff000000000000831661450e575b65ff0000000000831661440e575b64ff000000008316614316575b63ff0000008316614226575b62ff0000831661413e575b61ff00831661405e575b60ff8316613f87575b02911c60bf031c90565b6080831661404c575b83831661403a575b60208316614028575b60108316614016575b60088316614004575b60048316613ff2575b60028316613fe0575b6001831615613f7d576801000000000000000102831c613f7d565b6801000000000000000102831c613fc5565b6801000000000000000302831c613fbc565b6801000000000000000602831c613fb3565b6801000000000000000b02831c613faa565b6801000000000000001602831c613fa1565b6801000000000000002c02831c613f98565b6801000000000000005902831c613f90565b618000831661412c575b614000831661411a575b6120008316614108575b61100083166140f6575b61080083166140e4575b61040083166140d2575b61020083166140c0575b610100831615613f7457680100000000000000b102831c613f74565b6801000000000000016302831c6140a4565b680100000000000002c602831c61409a565b6801000000000000058c02831c614090565b68010000000000000b1702831c614086565b6801000000000000162e02831c61407c565b68010000000000002c5d02831c614072565b680100000000000058b902831c614068565b628000008316614214575b624000008316614202575b6220000083166141f0575b6210000083166141de575b6208000083166141cc575b6204000083166141ba575b6202000083166141a8575b62010000831615613f6a576801000000000000b17202831c613f6a565b680100000000000162e402831c61418b565b6801000000000002c5c802831c614180565b68010000000000058b9102831c614175565b680100000000000b172102831c61416a565b68010000000000162e4302831c61415f565b680100000000002c5c8602831c614154565b6801000000000058b90c02831c614149565b63800000008316614304575b634000000083166142f2575b632000000083166142e0575b631000000083166142ce575b630800000083166142bc575b630400000083166142aa575b63020000008316614298575b6301000000831615613f5f5768010000000000b1721802831c613f5f565b6801000000000162e43002831c61427a565b68010000000002c5c86002831c61426e565b680100000000058b90c002831c614262565b6801000000000b17217f02831c614256565b680100000000162e42ff02831c61424a565b6801000000002c5c85fe02831c61423e565b68010000000058b90bfc02831c614232565b64800000000083166143fc575b64400000000083166143ea575b64200000000083166143d8575b64100000000083166143c6575b64080000000083166143b4575b64040000000083166143a2575b6402000000008316614390575b640100000000831615613f5357680100000000b17217f802831c613f53565b68010000000162e42ff102831c614371565b680100000002c5c85fe302831c614364565b6801000000058b90bfce02831c614357565b68010000000b17217fbb02831c61434a565b6801000000162e42fff002831c61433d565b68010000002c5c8601cc02831c614330565b680100000058b90c0b4902831c614323565b6580000000000083166144fc575b6540000000000083166144ea575b6520000000000083166144d8575b6510000000000083166144c6575b6508000000000083166144b4575b6504000000000083166144a2575b650200000000008316614490575b65010000000000831615613f46576801000000b17218355102831c613f46565b680100000162e430e5a202831c614470565b6801000002c5c863b73f02831c614462565b68010000058b90cf1e6e02831c614454565b680100000b1721bcfc9a02831c614446565b68010000162e43f4f83102831c614438565b680100002c5c89d5ec6d02831c61442a565b6801000058b91b5bc9ae02831c61441c565b66800000000000008316614604575b664000000000000083166145f2575b662000000000000083166145e0575b661000000000000083166145ce575b660800000000000083166145bc575b660400000000000083166145aa575b66020000000000008316614598575b6601000000000000831615613f385768010000b17255775c0402831c613f38565b6801000162e525ee054702831c614577565b68010002c5cc37da949202831c614568565b680100058ba01fb9f96d02831c614559565b6801000b175effdc76ba02831c61454a565b680100162f3904051fa102831c61453b565b6801002c605e2e8cec5002831c61452c565b68010058c86da1c09ea202831c61451d565b6780000000000000008316614714575b6740000000000000008316614702575b67200000000000000083166146f0575b67100000000000000083166146de575b67080000000000000083166146cc575b67040000000000000083166146ba575b67020000000000000083166146a8575b670100000000000000831615613f2957680100b1afa5abcbed6102831c613f29565b68010163da9fb33356d802831c614686565b680102c9a3e778060ee702831c614676565b6801059b0d31585743ae02831c614666565b68010b5586cf9890f62a02831c614656565b6801172b83c7d517adce02831c614646565b6801306fe0a31b7152df02831c614636565b5077b504f333f9de648480000000000000000000000000000000614626565b602490604051907f0360d0280000000000000000000000000000000000000000000000000000000082526004820152fd5b8060008083131561488857670de0b6b3a76400009283811261485157506001925b808305906001600160801b03821160071b91821c9167ffffffffffffffff831160061b92831c63ffffffff811160051b90811c61ffff811160041b90811c60ff811160031b90811c91600f831160021b92831c936001978860038711811b96871c11961717171717171781810294811d9082821461484557506706f05b59d3b20000905b8482136148195750505050500290565b808391020590671bc16d674ec80000821215614838575b831d90614809565b8091950194831d90614830565b93505093925050020290565b6000199392508015614874576ec097ce7bc90715b34b9f10000000000591614785565b602482634e487b7160e01b81526012600452fd5b602483604051907f059b101b0000000000000000000000000000000000000000000000000000000082526004820152fd5b64ffffffffff6148ee600091838352600b60205280806040852054818160a01c1693849160c81c160316918142160316613ab4565b91808252600b602052600460408320018054156149745790829167ffffffffffffffff93526149466020832054828452600b6020526139f56001600160801b03968760026040882001541696879360801c1690613e23565b92831361495c57505061495890613a78565b1690565b60029350604092508152600b60205220015460801c90565b602483634e487b7160e01b81526032600452fd5b80600052600b602052604060002060ff600182015460a01c166000146149af575050600490565b805460f81c614a02575460a01c64ffffffffff164210613ed9576149d2816137e7565b90600052600b6020526001600160801b0380600260406000200154169116106000146149fd57600190565b600290565b5050600390565b80600052600b602052614a2260026040600020016135e6565b81600052600b602052604060002060ff600182015460a01c16600014614a5557506001600160801b039150602001511690565b5460f81c614a675750612fa9906137e7565b612fa991506001600160801b036040818351169201511690613688565b906001600160a01b036001541660206001600160a01b0360c0850151166024604051809481937fdcf844a700000000000000000000000000000000000000000000000000000000835260048301525afa80156109c657600090615343575b614b0591506001600160801b0360a08501511690602060e0860151015191615a02565b6001600160801b038151166101008401519064ffffffffff602086015116811561531957825180156152ef577f000000000000000000000000000000000000000000000000000000000000000081116152be575064ffffffffff6040614b6a85613852565b510151168110156152675750600091829083815185905b8082106151d4575050505064ffffffffff421664ffffffffff82168110156151945750506001600160801b03821681036151525750506009549283600052600b6020526040600020916001600160801b0381511660028401906001600160801b03198254161790556001600160a01b0360c083015116600184015490750100000000000000000000000000000000000000000060408501511515928654927fffffffffffffffffff0000ff000000000000000000000000000000000000000076ff000000000000000000000000000000000000000000006060890151151560b01b16921617171760018601556001600160a01b0384511691610100850151926040614c93855195600019870190613875565b510151927fff000000000000000000000000000000000000000000000000000000000000007eff0000000000000000000000000000000000000000000000000000000000007dffffffffff0000000000000000000000000000000000000000000000000078ffffffffff000000000000000000000000000000000000000060208b015160a01b169660c81b169460f01b16911617171717845560005b818110615082575050600185016009556001600160a01b0360c08301511660005260026020526001600160801b0380604060002054168160208401511601166001600160a01b0360c0840151166000526040600020906001600160801b03198254161790556001600160a01b03608083015116801561503e57614dd1614dcb8760005260056020526001600160a01b0360406000205416151590565b156154f1565b614dda8661361a565b1580615035575b8061502d575b615015576020600080516020615b4283398151915291614e20614dcb8960005260056020526001600160a01b0360406000205416151590565b806000526006825260406000206001815401905587600052600582526040600020816001600160a01b0319825416179055876040519160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4878152a1614eb06001600160a01b0360c0840151166001600160801b03808451168160208601511601169030903390615377565b6001600160801b0360408201511680614fe6575b507fef3d668acee46576ad5d407c42ab4d0cde13f3cd70b28f09a0fb9e3bf5bf09cb614fa36001600160a01b03845116926001600160a01b03608086015116946001600160a01b0360c08201511696614fdb614fbb60408401511515928c606086015115156001600160a01b0360e061010089015194549864ffffffffff6040519a614f4f8c612e9d565b818160a01c168c5260c81c1660208b01520151511695604051998a99610160948b523360208c015260408b0190604090816001600160801b0391828151168552826020820151166020860152015116910152565b60a089015260c08801528060e0880152860190612df3565b926101008501906020908164ffffffffff91828151168552015116910152565b6101408301520390a4565b61500f906001600160a01b0360c0850151166001600160a01b0360e08601515116903390615377565b38614ec4565b602486604051906378630aa960e01b82526004820152fd5b506000614de7565b50801515614de1565b606460405162461bcd60e51b815260206004820152602060248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152fd5b61509181610100860151613875565b5190600486015491680100000000000000008310156121e5576001830180600489015583101561385f5760019260048801600052602060002001906001600160801b03815116908254917fffffff00000000000000000000000000000000000000000000000000000000007cffffffffff000000000000000000000000000000000000000000000000604077ffffffffffffffff00000000000000000000000000000000602086015160801b1694015160c01b169316171717905501614d2f565b6040517fd90b7e390000000000000000000000000000000000000000000000000000000081526001600160801b03918216600482015291166024820152604490fd5b6040517f210aec0e00000000000000000000000000000000000000000000000000000000815264ffffffffff918216600482015291166024820152604490fd5b91935091946151f8906001600160801b036151ef8589613875565b5151169061597e565b9464ffffffffff80604061520c8685613875565b5101511694168085111561522a575060018493019192919092614b81565b8385606492604051927f7b0bada8000000000000000000000000000000000000000000000000000000008452600484015260248301526044820152fd5b64ffffffffff604061527885613852565b5101516040517fb4c9e52c00000000000000000000000000000000000000000000000000000000815264ffffffffff938416600482015291169091166024820152604490fd5b602490604051907f4757689b0000000000000000000000000000000000000000000000000000000082526004820152fd5b60046040517f3952c64e000000000000000000000000000000000000000000000000000000008152fd5b60046040517f6095d3bc000000000000000000000000000000000000000000000000000000008152fd5b6020823d60201161536f575b8161535c60209383612eea565b810103126135095750614b059051614ae2565b3d915061534f565b9290604051927f23b872dd0000000000000000000000000000000000000000000000000000000060208501526001600160a01b03809216602485015216604483015260648201526064815260a081019181831067ffffffffffffffff8411176121e5576153e6926040526153e8565b565b6001600160a01b03169061544860405161540181612e9d565b6020938482527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564858301526000808587829751910182855af1615442613358565b9161553c565b8051918215918483156154cd575b5050509050156154635750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152fd5b91938180945001031261350c57820151908115158203613509575080388084615456565b156154f857565b606460405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152fd5b9192901561559d5750815115615550575090565b3b156155595790565b606460405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156155b05750805190602001fd5b6105859060405191829162461bcd60e51b8352602060048401526024830190612d28565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361560657565b60046040517fa1c0d6e5000000000000000000000000000000000000000000000000000000008152fd5b916001600160a01b03604051927fa9059cbb000000000000000000000000000000000000000000000000000000006020850152166024830152604482015260448152608081019181831067ffffffffffffffff8411176121e5576153e6926040526153e8565b612fa9906156a381614a09565b90600052600b60205260026040600020015460801c90613688565b919081101561385f5760051b0190565b9291926156da81613651565b615966576156fe81600052600b6020526001600160a01b0360406000205416331490565b91821580615956575b611a5f57600094828652602091600583526001600160a01b039460409186838a205416918061594a575b61592557868116968715615915576001600160801b038086169586156158fe578161575b8a615696565b168088116158db5750916157e993916157b28a60028f80600b8e6157908f9b8f9588905283835286868620015460801c61597e565b95835252200190836001600160801b031983549260801b1691161781556135e6565b906157cd818b8401511692828a818351169201511690613688565b1611156158ac575b888c52600b88526001868d20015416615630565b80331415806158a2575b615826575b507ffa54f9f9bdcdd28778cbb9f78490df6691cc4e2729588e10f4cc0a26c465686a939495965051908152a3565b803b1561589e5796807ffa54f9f9bdcdd28778cbb9f78490df6691cc4e2729588e10f4cc0a26c465686a9596979860848451809481936313375c3b60e01b83528b60048401523360248401528c60448401528860648401525af161588f575b87969594506157f8565b61589890612ed6565b38615885565b8780fd5b50803b15156157f3565b888c52600b8852858c2060018101600160a01b60ff60a01b1982541617905560ff60f01b1981541690556157d5565b896064918989519263287ecaef60e21b8452600484015260248301526044820152fd5b60248987519063d2aabcd960e01b82526004820152fd5b6004845163630d074f60e11b8152fd5b8587606492855192632dcbf6b960e11b84526004840152336024840152166044820152fd5b50818782161415615731565b5061596082615999565b15615707565b60249060405190634a5541ef60e01b82526004820152fd5b9190916001600160801b0380809416911601918211611d9b57565b60009080825260056020526001600160a01b0380604084205416928333149384156159de575b505082156159cc57505090565b9091506159d93392612fac565b161490565b60ff92945090604091815260086020528181203382526020522054169138806159bf565b909291615a0d6135c7565b936001600160801b0392838116918215615b195767016345785d8a0000808211615ae257808511615aab5750615a5785615a48819386613d74565b16946020890195865284613d74565b169184615a6e60408901948086528287511661597e565b161015615a9557615a87849182615a9095511690613688565b91511690613688565b168252565b634e487b7160e01b600052600160045260246000fd5b84604491604051917f4fea5c1a00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b60449250604051917f47152d6700000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b50505050509050604051615b2c81612e64565b6000815260006020820152600060408201529056fef8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7a164736f6c6343000815000a"; + hex"60c0346200046e57601f62005db438819003918201601f19168301916001600160401b038311848410176200032b578084926080946040528339810103126200046e5780516001600160a01b038082169290918390036200046e5760208101518281168091036200046e5760408201519183831683036200046e5760600151936200008962000473565b90601d82527f5361626c696572205632204c6f636b75702044796e616d6963204e46540000006020830152620000be62000473565b601181527029a0a116ab1916a627a1a5aaa816a22ca760791b602082015230608052600080546001600160a01b03199081168417825560018054909116909517909455927fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808180a38051906001600160401b0382116200032b5760035490600182811c9216801562000463575b60208310146200044d5781601f849311620003d8575b50602090601f83116001146200034d5760009262000341575b50508160011b916000199060031b1c1916176003555b80516001600160401b0381116200032b576004918254600181811c9116801562000320575b60208210146200030b579081601f849311620002b3575b50602090601f831160011462000248576000926200023c575b50508160011b916000199060031b1c19161790555b1660018060a01b0319600a541617600a5560a05260016009556040516159209081620004948239608051816153a9015260a05181818161126b01526149090152f35b015190503880620001e5565b6000858152602081209350601f198516905b8181106200029a575090846001959493921062000280575b505050811b019055620001fa565b015160001960f88460031b161c1916905538808062000272565b929360206001819287860151815501950193016200025a565b909150836000526020600020601f840160051c8101916020851062000300575b90601f859493920160051c01905b818110620002f05750620001cc565b60008155849350600101620002e1565b9091508190620002d3565b602284634e487b7160e01b6000525260246000fd5b90607f1690620001b5565b634e487b7160e01b600052604160045260246000fd5b0151905038806200017a565b600360009081527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b9350601f198516905b818110620003bf5750908460019594939210620003a5575b505050811b0160035562000190565b015160001960f88460031b161c1916905538808062000396565b929360206001819287860151815501950193016200037e565b60036000529091507fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b601f840160051c8101916020851062000442575b90601f859493920160051c01905b81811062000432575062000161565b6000815584935060010162000423565b909150819062000415565b634e487b7160e01b600052602260045260246000fd5b91607f16916200014b565b600080fd5b60408051919082016001600160401b038111838210176200032b5760405256fe608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a714612a0d5750806306fdde031461294a578063081812fc1461292c578063095ea7b3146127985780631400ecec146126f357806316844456146124785780631c1cdd4c146124125780631e99d569146123f457806323b872dd146123cb57806339a73c031461238857806340e58ee514612108578063425d30dd146120ea57806342842e0e1461209a57806342966c6814611f3c5780634857501f14611ec65780634869e12d14611e8a5780635fe3b56714611e635780636352211e14611e345780636d0cee7514611ddc57806370a0823114611d3257806375829def14611ca05780637cad6cd114611bce5780637de6b1db146119a55780638659c2701461164d578063894e9a0d146113e05780638bad38dd146113645780638f69b993146112e15780639067b6771461128e5780639188ec841461125357806395d89b4114611145578063a22cb46514611074578063a2ffb89714610f7b578063a6202bf214610e7b578063a80fc07114610e26578063ad35efd414610dc3578063b256456914610da5578063b637b86514610d45578063b88d4fde14610cba578063b8a3be6614610c83578063b971302a14610c31578063bc063e1a14610c0e578063bc2be1be14610bbb578063c156a11d14610acd578063c33cd35e146109b8578063c87b56dd14610885578063cc364f48146107eb578063d4dbd20b14610796578063d511609f14610747578063d975dfed146106fa578063e985e9c5146106a3578063ea5ead1914610652578063eac8f5b8146105e6578063f590c176146105be578063f851a440146105975763fdd46d601461027c57600080fd5b3461048057606036600319011261048057600435610298612b3a565b604435916001600160801b039182841693848103610480576102b861539f565b6102c183613428565b61057f576102e583600052600b6020526001600160a01b0360406000205416331490565b9182158061056f575b6105505783600052602094600586526001600160a01b039081604060002054169480610544575b61051e5781831693841561050d5788156104f55761033287615461565b8281168a116104c1575091889161038e6103626103cb958a600052600b8c5260026040600020015460801c615730565b89600052600b8b52600260406000200190836001600160801b031983549260801b1691161781556133bd565b906103aa818b840151169282604081835116920151169061345f565b16111561048f575b86600052600b88526001604060002001541692836153fb565b81847f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d876040518a8152a48133141580610485575b61041f575b6000805160206158f48339815191528484604051908152a1005b813b15610480576000805160206158f48339815191529460846000928360405195869485936313375c3b60e01b8552896004860152336024860152604485015260648401525af1610471575b80610405565b61047a90612cad565b3861046b565b600080fd5b50813b1515610400565b86600052600b8852604060002060018101600160a01b60ff60a01b1982541617905560ff60f01b1981541690556103b2565b60405163287ecaef60e21b8152600481018990526001600160801b03928316602482015291166044820152606490fd5b0390fd5b6024876040519063d2aabcd960e01b82526004820152fd5b600460405163630d074f60e11b8152fd5b606486838560405192632dcbf6b960e11b84526004840152336024840152166044820152fd5b50848284161415610315565b60405163216caf0d60e01b815260048101859052336024820152604490fd5b506105798461574b565b156102ee565b60248360405190634a5541ef60e01b82526004820152fd5b346104805760003660031901126104805760206001600160a01b0360005416604051908152f35b346104805760203660031901126104805760206105dc600435613478565b6040519015158152f35b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b57600052600b60205260206001600160a01b0360016040600020015416604051908152f35b6024906040519062b8e7e760e51b82526004820152fd5b34610480576040366003190112610480576000805160206158f4833981519152602060043561069a610682612b3a565b61068b83615461565b9061069461539f565b83615499565b604051908152a1005b34610480576040366003190112610480576106bc612b24565b6106c4612b3a565b906001600160a01b03809116600052600860205260406000209116600052602052602060ff604060002054166040519015158152f35b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b57610736602091615461565b6001600160801b0360405191168152f35b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b57600052600b602052602060026040600020015460801c604051908152f35b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b57600052600b60205260206001600160801b0360036040600020015416604051908152f35b34610480576020366003190112610480576004356000602060405161080f81612c74565b828152015280600052600b60205260ff60016040600020015460a81c161561063b57600052600b6020526040806000205464ffffffffff82519161085283612c74565b818160a01c16835260c81c166020820152610883825180926020908164ffffffffff91828151168552015116910152565bf35b346104805760208060031936011261048057600435906108c36108be8360005260056020526001600160a01b0360406000205416151590565b612d13565b60006001600160a01b03600a5416926044604051809581937fe9dc637500000000000000000000000000000000000000000000000000000000835230600484015260248301525afa9182156109ac57600092610933575b5061092f604051928284938452830190612aff565b0390f35b9091503d806000833e6109468183612cc1565b81019082818303126104805780519067ffffffffffffffff8211610480570181601f8201121561048057805161097b81612ce3565b926109896040519485612cc1565b818452848284010111610480576109a591848085019101612adc565b908261091a565b6040513d6000823e3d90fd5b3461048057600319602036820112610480576004359067ffffffffffffffff9081831161048057610140908336030112610480576109f461539f565b60405191610a0183612c57565b610a0d81600401612b50565b8352610a1b602482016134a9565b6020840152610a2c60448201612c2e565b6040840152610a3d60648201612c2e565b6060840152610a4e60848201612b50565b6080840152610a5f60a48201612cff565b60a0840152610a7060c48201612b50565b60c0840152610a823660e4830161358f565b60e084015261012481013591821161048057013660238201121561048057602091610aba610ac59236906024600482013591016134bb565b61010082015261485b565b604051908152f35b3461048057604036600319011261048057600435610ae9612b3a565b610af161539f565b81600052600b60205260ff60016040600020015460a81c1615610ba4578160005260056020526001600160a01b0360406000205416803303610b85579161069a816020936000805160206158f483398151915295610b4e83615461565b6001600160801b038116610b63575b50612fa6565b610b7690610b6f61539f565b8285615499565b8686604051858152a187610b5d565b60405163216caf0d60e01b815260048101849052336024820152604490fd5b6024826040519062b8e7e760e51b82526004820152fd5b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b57600052600b602052602064ffffffffff60406000205460a01c16604051908152f35b3461048057600036600319011261048057602060405167016345785d8a00008152f35b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b57600052600b60205260206001600160a01b0360406000205416604051908152f35b3461048057602036600319011261048057600435600052600b602052602060ff60016040600020015460a81c166040519015158152f35b3461048057608036600319011261048057610cd3612b24565b610cdb612b3a565b6064359167ffffffffffffffff8311610480573660238401121561048057826004013591610d0883612ce3565b92610d166040519485612cc1565b8084523660248287010111610480576020816000926024610d439801838801378501015260443591612e31565b005b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b57600052600b60205261092f610d916004604060002001613310565b604051918291602083526020830190612bca565b346104805760203660031901126104805760206105dc6004356133f1565b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b57610dfd9061475f565b6040516005821015610e10576020918152f35b634e487b7160e01b600052602160045260246000fd5b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b57600052600b60205260206001600160801b0360026040600020015416604051908152f35b3461048057602036600319011261048057610e94612b24565b6001600160a01b038060005416338103610f5257508116908160005260026020526001600160801b0360406000205416908115610f215781610ef39184600052600260205260406000206001600160801b0319815416905533906153fb565b6040519081527fca7a4a65a94ed2f37538814e00e1cd4c41a78261561e3f3794592f11409cf5af60203392a3005b602483604051907f8410168c0000000000000000000000000000000000000000000000000000000082526004820152fd5b6040516331b339a960e21b81526001600160a01b03919091166004820152336024820152604490fd5b346104805760603660031901126104805767ffffffffffffffff60043581811161048057610fad903690600401612b99565b610fb5612b3a565b9260443590811161048057610fce903690600401612b99565b9190610fd861539f565b82820361103d5760005b828110610feb57005b806000805160206158f4833981519152602061100a600194878a615489565b3561103061102161101c868b8a615489565b61357b565b61102961539f565b8b83615499565b604051908152a101610fe2565b50604491604051917faec9344000000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b346104805760403660031901126104805761108d612b24565b60243590811515809203610480576001600160a01b03169081331461110157336000526008602052604060002082600052602052604060002060ff1981541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b606460405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152fd5b3461048057600036600319011261048057604051600060045490600182811c91818416918215611249575b60209485851084146112335785879486865291826000146112135750506001146111b6575b506111a292500383612cc1565b61092f604051928284938452830190612aff565b84915060046000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b906000915b8583106111fb5750506111a2935082010185611195565b805483890185015287945086939092019181016111e4565b60ff1916858201526111a295151560051b85010192508791506111959050565b634e487b7160e01b600052602260045260246000fd5b92607f1692611170565b346104805760003660031901126104805760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b57600052600b602052602064ffffffffff60406000205460c81c16604051908152f35b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b5761131b9061475f565b600581101580610e105760028214908115611357575b8115611345575b6020826040519015158152f35b9050610e105760046020911482611338565b5050600381146000611331565b34610480576020366003190112610480576004356001600160a01b0390818116809103610480578160005416338103610f52575060015491816001600160a01b03198416176001556040519216825260208201527fdcb09aef4bf01068924ccce937981cbe59d25ba08380cf941aaaea4e4bd3960d60403392a2005b3461048057602036600319011261048057606061014060405161140281612c90565b60008152600060208201526000604082015260008382015260006080820152600060a0820152600060c0820152600060e0820152600061010082015261144661339e565b6101208201520152600435600052600b60205260ff60016040600020015460a81c161561163557600435600052600b602052604060002061152960046040519261148f84612c90565b80546001600160a01b038116855264ffffffffff8160a01c16602086015264ffffffffff8160c81c16604086015260ff8160f01c161515606086015260f81c1515608085015260ff60018201546001600160a01b03811660a0870152818160a01c16151560c0870152818160a81c16151560e087015260b01c16151561010085015261151d600282016133bd565b61012085015201613310565b61014082015261153a60043561475f565b906005821015610e105760026101409214611629575b61092f604051928392602084526001600160a01b03815116602085015264ffffffffff602082015116604085015264ffffffffff60408201511660608501526060810151151560808501526080810151151560a08501526001600160a01b0360a08201511660c085015260c0810151151560e085015260e08101511515610100850152610100810151151561012085015261161561012082015183860190604090816001600160801b0391828151168552826020820151166020860152015116910152565b01516101a0808401526101c0830190612bca565b60006060820152611550565b602460405162b8e7e760e51b81526004356004820152fd5b346104805760203660031901126104805760043567ffffffffffffffff81116104805761167e903690600401612b99565b61168661539f565b6000905b80821061169357005b61169e828285615489565b35916116a861539f565b6116b183613428565b156116ce5760248360405190634a5541ef60e01b82526004820152fd5b6116d9839293613478565b61198d576116fd82600052600b6020526001600160a01b0360406000205416331490565b1561196e5761170b826135be565b82600052600b928360205261172660026040600020016133bd565b936001600160801b039283865116848216101561195657826000528160205260ff60406000205460f01c161561193e578084602061176a61177494838b511661345f565b980151169061345f565b9482600052816020526040600020958654600160f81b7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82161788556003868316988915611924575b0195831695866001600160801b03198254161790556001600160a01b03916005602052826040600020541694602052600198838a604060002001541697611805818686168b6153fb565b863b611888575b505060209594926000805160206158f48339815191529794926118777f5edb27d6c1a327513b90a792050debf074b7194444885e3144d4decc5caaaa509360405193849316958984916040919493606084019584526001600160801b03809216602085015216910152565b0390a4604051908152a1019061168a565b9196959390979492843b15610480576118776020987f5edb27d6c1a327513b90a792050debf074b7194444885e3144d4decc5caaaa50946000805160206158f48339815191529b604051916372eba20360e01b83528b6004840152868616602484015260448301526064820152600081608481838c5af1611915575b50935050929497819496975061180c565b61191e90612cad565b8f611904565b60018101600160a01b60ff60a01b198254161790556117bb565b602483604051906339c6dc7360e21b82526004820152fd5b602483604051906322cad1af60e11b82526004820152fd5b60405163216caf0d60e01b815260048101839052336024820152604490fd5b6024826040519063fe19f19f60e01b82526004820152fd5b3461048057602080600319360112610480576004356119c261539f565b80600052600b825260ff60016040600020015460a81c161561063b576119e78161475f565b916000926005811015610e105760048103611a145760248360405190634a5541ef60e01b82526004820152fd5b60038103611a34576024836040519063fe19f19f60e01b82526004820152fd5b916002849314611bb657611a5e81600052600b6020526001600160a01b0360406000205416331490565b15611b965780600052600b825260ff60406000205460f01c1615611b7e5780600052600b8252604060002060ff60f01b198154169055600582526001600160a01b0360406000205416803b611aec575b50807f0eb069207093cd3e51cd1370d2d369770057fbe29947e577e5fb428c6c6fc78f846000805160206158f483398151915295a2604051908152a1005b803b15610480576000805160206158f48339815191529360008084936024604051809481937f341a0bd90000000000000000000000000000000000000000000000000000000083528860048401525af1611b49575b509350611aae565b9050611b559150612cad565b8060007f0eb069207093cd3e51cd1370d2d369770057fbe29947e577e5fb428c6c6fc78f611b41565b602490604051906339c6dc7360e21b82526004820152fd5b60405163216caf0d60e01b81526004810191909152336024820152604490fd5b602490604051906322cad1af60e11b82526004820152fd5b34610480576020366003190112610480576004356001600160a01b0390818116809103610480578160005416338103610f525750600a5491816001600160a01b0319841617600a556040519216825260208201527fa2548bd4b805e907c1558a47b5858324fe8bb4a2e1ddfca647eecbf65610eebc60403392a26009546000198101908111611c8a5760407f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c91815190600182526020820152a1005b634e487b7160e01b600052601160045260246000fd5b3461048057602036600319011261048057611cb9612b24565b6000546001600160a01b0380821692338403611d0b576001600160a01b03199350169182911617600055337fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf80600080a3005b6040516331b339a960e21b81526001600160a01b0385166004820152336024820152604490fd5b34610480576020366003190112610480576001600160a01b03611d53612b24565b168015611d725760005260066020526020604060002054604051908152f35b608460405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152fd5b3461048057602036600319011261048057600435611e136108be8260005260056020526001600160a01b0360406000205416151590565b600052600560205260206001600160a01b0360406000205416604051908152f35b34610480576020366003190112610480576020611e52600435612d5e565b6001600160a01b0360405191168152f35b346104805760003660031901126104805760206001600160a01b0360015416604051908152f35b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b576107366020916147e0565b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b576000611f028261475f565b6005811015610e1057600203611f20575b6020906040519015158152f35b50600052600b602052602060ff60406000205460f01c16611f13565b3461048057602036600319011261048057600435611f5861539f565b611f6181613428565b1561206957611f6f8161574b565b15611b9657611f7d81612d5e565b611f86826133f1565b159081612060575b8161204d575b5061203557602081611fb46000805160206158f483398151915293612d5e565b9080600052600783526001600160a01b036040600020926001600160a01b031993848154169055169182600052600684526040600020600019815401905581600052600584526040600020908154169055806000604051937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a48152a1005b602490604051906378630aa960e01b82526004820152fd5b6001600160a01b03915016151582611f94565b60009150611f8e565b602490604051907f817cd6390000000000000000000000000000000000000000000000000000000082526004820152fd5b34610480576120a836612b64565b60405191602083019383851067ffffffffffffffff8611176120d457610d439460405260008452612e31565b634e487b7160e01b600052604160045260246000fd5b346104805760203660031901126104805760206105dc600435613428565b3461048057602080600319360112610480576004359061212661539f565b61212f82613428565b1561214c5760248260405190634a5541ef60e01b82526004820152fd5b61215582613478565b61198d5761217982600052600b6020526001600160a01b0360406000205416331490565b1561196e57612187826135be565b9180600052600b82526121a060026040600020016133bd565b926001600160801b03908185511682821610156119565782600052600b845260ff60406000205460f01c161561193e578082856121e36121ed94838a511661345f565b970151169061345f565b82600052600b8452604060002091825491600160f81b7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8416178455600382821694851561236e575b0191871691826001600160801b03198254161790556001600160a01b038093169160058752836040600020541693600b8852600160406000200154169461227c8285886153fb565b843b6122e6575b5050604080518681526001600160801b03988916602082015291909716968101969096526000805160206158f4833981519152957f5edb27d6c1a327513b90a792050debf074b7194444885e3144d4decc5caaaa5090606090a4604051908152a1005b919097843b15610480576000805160206158f4833981519152987f5edb27d6c1a327513b90a792050debf074b7194444885e3144d4decc5caaaa5093604051916372eba20360e01b835289600484015286602484015260448301526064820152600081608481838a5af161235f575b5097819250612283565b61236890612cad565b89612355565b60018101600160a01b60ff60a01b19825416179055612234565b34610480576020366003190112610480576001600160a01b036123a9612b24565b16600052600260205260206001600160801b0360406000205416604051908152f35b3461048057610d436123dc36612b64565b916123ef6123ea8433612ec7565b612dc0565b612fa6565b34610480576000366003190112610480576020600954604051908152f35b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b5761244c9061475f565b6005811015610e1057806020911590811561246d575b506040519015158152f35b600191501482612462565b346104805760206003198181360112610480576004359067ffffffffffffffff908183116104805761012083360391820112610480576124b661539f565b6101048301359060221901811215610480578201600481013590828211610480576024016060820236038113610480576124f19136916134bb565b918251906124fe826132f8565b9161250c6040519384612cc1565b808352601f1961251b826132f8565b018660005b8281106126dd5750505064ffffffffff90814216946001600160801b03968761254882613629565b515116828a61255684613629565b510151168580604061256786613629565b510151168a0116906040519261257c84612c3b565b83528b830152604082015261259087613629565b5261259a86613629565b5060019386855b8a8c87831061265c57908b846001600160a01b038c60a48101358281169081900361048057610ac59561261c9561264c946125de6024860161355a565b6125ea6044870161355a565b6125f660648801613567565b9161260388600401613567565b948461261160848b0161357b565b966040519d8e612c57565b168c528d8c0152151560408b0152151560608a01521660808801521660a086015260c085015260c436910161358f565b60e083015261010082015261485b565b8893858060406126908b866126808a8e9a612677828d61364c565b5151169a61364c565b510151169460001989019061364c565b510151168160406126a1888c61364c565b51015116011691604051936126b585612c3b565b845283015260408201526126c9828b61364c565b526126d4818a61364c565b500187906125a1565b6126e561339e565b828288010152018790612520565b346104805760203660031901126104805760043580600052600b60205260ff60016040600020015460a81c161561063b5760209060009080600052600b8352604060002060ff815460f01c1680612786575b61275d575b50506001600160801b0360405191168152f35b61277f92506001600160801b03600261277992015416916135be565b9061345f565b828061274a565b5060ff600182015460a01c1615612745565b34610480576040366003190112610480576127b1612b24565b602435906001600160a01b0380806127c885612d5e565b169216918083146128c25780331490811561289d575b5015612833578260005260076020526040600020826001600160a01b031982541617905561280b83612d5e565b167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600080a4005b608460405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152fd5b9050600052600860205260406000203360005260205260ff60406000205416846127de565b608460405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152fd5b34610480576020366003190112610480576020611e52600435612d83565b3461048057600036600319011261048057604051600060035490600182811c91818416918215612a03575b60209485851084146112335785879486865291826000146112135750506001146129a657506111a292500383612cc1565b84915060036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b906000915b8583106129eb5750506111a2935082010185611195565b805483890185015287945086939092019181016129d4565b92607f1692612975565b3461048057602036600319011261048057600435907fffffffff00000000000000000000000000000000000000000000000000000000821680920361048057817f80ac58cd0000000000000000000000000000000000000000000000000000000060209314908115612ab2575b8115612a88575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483612a81565b7f5b5e139f0000000000000000000000000000000000000000000000000000000081149150612a7a565b60005b838110612aef5750506000910152565b8181015183820152602001612adf565b90602091612b1881518092818552858086019101612adc565b601f01601f1916010190565b600435906001600160a01b038216820361048057565b602435906001600160a01b038216820361048057565b35906001600160a01b038216820361048057565b6060906003190112610480576001600160a01b0390600435828116810361048057916024359081168103610480579060443590565b9181601f840112156104805782359167ffffffffffffffff8311610480576020808501948460051b01011161048057565b90815180825260208080930193019160005b828110612bea575050505090565b835180516001600160801b031686528083015167ffffffffffffffff168684015260409081015164ffffffffff169086015260609094019392810192600101612bdc565b3590811515820361048057565b6060810190811067ffffffffffffffff8211176120d457604052565b610120810190811067ffffffffffffffff8211176120d457604052565b6040810190811067ffffffffffffffff8211176120d457604052565b610160810190811067ffffffffffffffff8211176120d457604052565b67ffffffffffffffff81116120d457604052565b90601f8019910116810190811067ffffffffffffffff8211176120d457604052565b67ffffffffffffffff81116120d457601f01601f191660200190565b35906001600160801b038216820361048057565b15612d1a57565b606460405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152fd5b60005260056020526001600160a01b0360406000205416612d80811515612d13565b90565b612da66108be8260005260056020526001600160a01b0360406000205416151590565b60005260076020526001600160a01b036040600020541690565b15612dc757565b608460405162461bcd60e51b815260206004820152602d60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206f7220617070726f766564000000000000000000000000000000000000006064820152fd5b90612e55939291612e456123ea8433612ec7565b612e50838383612fa6565b61315f565b15612e5c57565b60405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608490fd5b906001600160a01b038080612edb84612d5e565b16931691838314938415612f0e575b508315612ef8575b50505090565b612f0491929350612d83565b1614388080612ef2565b909350600052600860205260406000208260005260205260ff604060002054169238612eea565b15612f3c57565b608460405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152fd5b90612fcf9291612fb583612d5e565b916001600160a01b03948593848094169687911614612f35565b16908115806130c657612fe1846133f1565b1590816130bd575b50806130b4575b61309c579180849261301e6000805160206158f48339815191529660209661301785612d5e565b1614612f35565b60009382855260078652604085206001600160a01b031990818154169055818652600687526040862060001981540190558286526040862060018154019055838652600587528260408720918254161790557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6040519580a48152a1565b602483604051906378630aa960e01b82526004820152fd5b50831515612ff0565b90501538612fe9565b608460405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152fd5b3d1561315a573d9061314082612ce3565b9161314e6040519384612cc1565b82523d6000602084013e565b606090565b9290803b156132ef576131c9916020916001600160a01b0394604051809581948293897f150b7a02000000000000000000000000000000000000000000000000000000009b8c86523360048701521660248501526044840152608060648401526084830190612aff565b03916000968791165af190829082613288575b5050613262576131ea61312f565b8051908161325d5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608490fd5b602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000161490565b909192506020813d82116132e7575b816132a460209383612cc1565b810103126132e35751907fffffffff00000000000000000000000000000000000000000000000000000000821682036132e057509038806131dc565b80fd5b5080fd5b3d9150613297565b50505050600190565b67ffffffffffffffff81116120d45760051b60200190565b90815461331c816132f8565b9260409361332c85519182612cc1565b828152809460208092019260005281600020906000935b85851061335257505050505050565b6001848192845161336281612c3b565b64ffffffffff87546001600160801b038116835267ffffffffffffffff8160801c168584015260c01c1686820152815201930194019391613343565b604051906133ab82612c3b565b60006040838281528260208201520152565b906040516133ca81612c3b565b6040819360018154916001600160801b0392838116865260801c6020860152015416910152565b80600052600b60205260ff60016040600020015460a81c161561063b57600052600b60205260ff60016040600020015460b01c1690565b80600052600b60205260ff60016040600020015460a81c161561063b57600052600b60205260ff60016040600020015460a01c1690565b6001600160801b039182169082160391908211611c8a57565b80600052600b60205260ff60016040600020015460a81c161561063b57600052600b60205260406000205460f81c90565b359064ffffffffff8216820361048057565b9291926134c7826132f8565b6040946134d686519283612cc1565b8195848352602080930191606080960285019481861161048057925b8584106135025750505050505050565b86848303126104805782519061351782612c3b565b61352085612cff565b8252858501359067ffffffffffffffff8216820361048057828792838b95015261354b8688016134a9565b868201528152019301926134f2565b3580151581036104805790565b356001600160a01b03811681036104805790565b356001600160801b03811681036104805790565b9190826040910312610480576040516135a781612c74565b60208082946135b581612b50565b84520135910152565b64ffffffffff80421682600052600b602052604060002091825482828260a01c16101561361f5760c81c16111561360d57600401546001101561360457612d8090613660565b612d8090614690565b6001600160801b039150600201541690565b5050505050600090565b8051156136365760200190565b634e487b7160e01b600052603260045260246000fd5b80518210156136365760209160051b010190565b64ffffffffff90814216906000908152600b60205260409081812082519361368785612c90565b8154956001600160a01b039182881687526020870197828160a01c168952828160c81c168789015260ff8160f01c161515606089015260f81c1515608088015260ff6001938486015490811660a08a0152818160a01c16151560c08a0152818160a81c16151560e08a015260b01c1615156101008801526101406137216004613712600288016133bd565b966101208b0197885201613310565b9701918783528087613733889a613629565b5101511693828288965b16106138175750916137c76137cc928488816137d198976001600160801b039e8f6137698b8a5161364c565b5151169d8a8f9b602061378667ffffffffffffffff928d5161364c565b5101511699848361379884845161364c565b510151169650811561380b576137b69293505190600019019061364c565b5101511680925b031692031661388b565b613bfa565b613a5d565b9283136137ea5750506137e4839161384f565b16011690565b5160200151929392831692841683101591506138069050575090565b905090565b505050511680926137bd565b8094986001600160801b03908161382f8c885161364c565b51511601169801938282808a61384689895161364c565b5101511661373d565b6000811261385a5790565b602490604051907f2463f3d50000000000000000000000000000000000000000000000000000000082526004820152fd5b90600160ff1b808314908115613973575b50613949576000821215613940576138c5826000035b600083121561393957826000039061397d565b917f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831161390357600091600019911813156138ff575090565b0390565b604491604051917fd49c26b300000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b829061397d565b6138c5826138b2565b60046040517f9fe2b450000000000000000000000000000000000000000000000000000000008152fd5b905081143861389c565b670de0b6b3a7640000916000198383099280830292838086109503948086039514613a3957828510156139fd57908291096001821901821680920460028082600302188083028203028083028203028083028203028083028203028083028203028092029003029360018380600003040190848311900302920304170290565b82606492604051927f63a05778000000000000000000000000000000000000000000000000000000008452600484015260248301526044820152fd5b505080925015613a47570490565b634e487b7160e01b600052601260045260246000fd5b90600160ff1b808314908115613b41575b50613b17576000821215613b0e57613a97826000035b6000831215613b07578260000390613b4b565b917f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311613ad157600091600019911813156138ff575090565b604491604051917f120b5b4300000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b8290613b4b565b613a9782613a84565b60046040517fa6070c25000000000000000000000000000000000000000000000000000000008152fd5b9050811438613a6e565b90919060001983820983820291828083109203918083039214613be957670de0b6b3a76400009081831015613bb257947faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac1066994950990828211900360ee1b910360121c170290565b60449086604051917f5173648d00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b5050670de0b6b3a764000090049150565b80613c145750600090612d805750670de0b6b3a764000090565b90670de0b6b3a7640000808314613c61575080613c39575050670de0b6b3a764000090565b670de0b6b3a76400008114613c5d57613c58906137cc612d809361453b565b613c81565b5090565b91505090565b8015613a47576ec097ce7bc90715b34b9f10000000000590565b6000811215613cb65768033dd1780914b97114198112613cb057613ca790600003613c81565b612d8090613c67565b50600090565b680a688906bd8affffff811361450a57670de0b6b3a764000080604092831b05907780000000000000000000000000000000000000000000000067ff0000000000000083166143ed575b66ff00000000000083166142e5575b65ff000000000083166141e5575b64ff0000000083166140ed575b63ff0000008316613ffd575b62ff00008316613f15575b61ff008316613e35575b60ff8316613d5e575b02911c60bf031c90565b60808316613e23575b838316613e11575b60208316613dff575b60108316613ded575b60088316613ddb575b60048316613dc9575b60028316613db7575b6001831615613d54576801000000000000000102831c613d54565b6801000000000000000102831c613d9c565b6801000000000000000302831c613d93565b6801000000000000000602831c613d8a565b6801000000000000000b02831c613d81565b6801000000000000001602831c613d78565b6801000000000000002c02831c613d6f565b6801000000000000005902831c613d67565b6180008316613f03575b6140008316613ef1575b6120008316613edf575b6110008316613ecd575b6108008316613ebb575b6104008316613ea9575b6102008316613e97575b610100831615613d4b57680100000000000000b102831c613d4b565b6801000000000000016302831c613e7b565b680100000000000002c602831c613e71565b6801000000000000058c02831c613e67565b68010000000000000b1702831c613e5d565b6801000000000000162e02831c613e53565b68010000000000002c5d02831c613e49565b680100000000000058b902831c613e3f565b628000008316613feb575b624000008316613fd9575b622000008316613fc7575b621000008316613fb5575b620800008316613fa3575b620400008316613f91575b620200008316613f7f575b62010000831615613d41576801000000000000b17202831c613d41565b680100000000000162e402831c613f62565b6801000000000002c5c802831c613f57565b68010000000000058b9102831c613f4c565b680100000000000b172102831c613f41565b68010000000000162e4302831c613f36565b680100000000002c5c8602831c613f2b565b6801000000000058b90c02831c613f20565b638000000083166140db575b634000000083166140c9575b632000000083166140b7575b631000000083166140a5575b63080000008316614093575b63040000008316614081575b6302000000831661406f575b6301000000831615613d365768010000000000b1721802831c613d36565b6801000000000162e43002831c614051565b68010000000002c5c86002831c614045565b680100000000058b90c002831c614039565b6801000000000b17217f02831c61402d565b680100000000162e42ff02831c614021565b6801000000002c5c85fe02831c614015565b68010000000058b90bfc02831c614009565b64800000000083166141d3575b64400000000083166141c1575b64200000000083166141af575b641000000000831661419d575b640800000000831661418b575b6404000000008316614179575b6402000000008316614167575b640100000000831615613d2a57680100000000b17217f802831c613d2a565b68010000000162e42ff102831c614148565b680100000002c5c85fe302831c61413b565b6801000000058b90bfce02831c61412e565b68010000000b17217fbb02831c614121565b6801000000162e42fff002831c614114565b68010000002c5c8601cc02831c614107565b680100000058b90c0b4902831c6140fa565b6580000000000083166142d3575b6540000000000083166142c1575b6520000000000083166142af575b65100000000000831661429d575b65080000000000831661428b575b650400000000008316614279575b650200000000008316614267575b65010000000000831615613d1d576801000000b17218355102831c613d1d565b680100000162e430e5a202831c614247565b6801000002c5c863b73f02831c614239565b68010000058b90cf1e6e02831c61422b565b680100000b1721bcfc9a02831c61421d565b68010000162e43f4f83102831c61420f565b680100002c5c89d5ec6d02831c614201565b6801000058b91b5bc9ae02831c6141f3565b668000000000000083166143db575b664000000000000083166143c9575b662000000000000083166143b7575b661000000000000083166143a5575b66080000000000008316614393575b66040000000000008316614381575b6602000000000000831661436f575b6601000000000000831615613d0f5768010000b17255775c0402831c613d0f565b6801000162e525ee054702831c61434e565b68010002c5cc37da949202831c61433f565b680100058ba01fb9f96d02831c614330565b6801000b175effdc76ba02831c614321565b680100162f3904051fa102831c614312565b6801002c605e2e8cec5002831c614303565b68010058c86da1c09ea202831c6142f4565b67800000000000000083166144eb575b67400000000000000083166144d9575b67200000000000000083166144c7575b67100000000000000083166144b5575b67080000000000000083166144a3575b6704000000000000008316614491575b670200000000000000831661447f575b670100000000000000831615613d0057680100b1afa5abcbed6102831c613d00565b68010163da9fb33356d802831c61445d565b680102c9a3e778060ee702831c61444d565b6801059b0d31585743ae02831c61443d565b68010b5586cf9890f62a02831c61442d565b6801172b83c7d517adce02831c61441d565b6801306fe0a31b7152df02831c61440d565b5077b504f333f9de6484800000000000000000000000000000006143fd565b602490604051907f0360d0280000000000000000000000000000000000000000000000000000000082526004820152fd5b8060008083131561465f57670de0b6b3a76400009283811261462857506001925b808305906001600160801b03821160071b91821c9167ffffffffffffffff831160061b92831c63ffffffff811160051b90811c61ffff811160041b90811c60ff811160031b90811c91600f831160021b92831c936001978860038711811b96871c11961717171717171781810294811d9082821461461c57506706f05b59d3b20000905b8482136145f05750505050500290565b808391020590671bc16d674ec8000082121561460f575b831d906145e0565b8091950194831d90614607565b93505093925050020290565b600019939250801561464b576ec097ce7bc90715b34b9f1000000000059161455c565b602482634e487b7160e01b81526012600452fd5b602483604051907f059b101b0000000000000000000000000000000000000000000000000000000082526004820152fd5b64ffffffffff6146c5600091838352600b60205280806040852054818160a01c1693849160c81c16031691814216031661388b565b91808252600b6020526004604083200180541561474b5790829167ffffffffffffffff935261471d6020832054828452600b6020526137cc6001600160801b03968760026040882001541696879360801c1690613bfa565b92831361473357505061472f9061384f565b1690565b60029350604092508152600b60205220015460801c90565b602483634e487b7160e01b81526032600452fd5b80600052600b602052604060002060ff600182015460a01c16600014614786575050600490565b805460f81c6147d9575460a01c64ffffffffff164210613cb0576147a9816135be565b90600052600b6020526001600160801b0380600260406000200154169116106000146147d457600190565b600290565b5050600390565b80600052600b6020526147f960026040600020016133bd565b81600052600b602052604060002060ff600182015460a01c1660001461482c57506001600160801b039150602001511690565b5460f81c61483e5750612d80906135be565b612d8091506001600160801b03604081835116920151169061345f565b906001600160a01b036001541660206001600160a01b0360c0850151166024604051809481937fdcf844a700000000000000000000000000000000000000000000000000000000835260048301525afa80156109ac5760009061510e575b6148dc91506001600160801b0360a08501511690602060e08601510151916157b4565b6001600160801b0381511661010084015164ffffffffff60208601511682156150e457815180156150ba577f00000000000000000000000000000000000000000000000000000000000000008111615089575064ffffffffff604061494084613629565b510151168110156150325750600090819082815184905b808210614f9f575050505064ffffffffff421664ffffffffff8216811015614f5f5750506001600160801b0316808203614f285750506009549283600052600b6020526040600020916001600160801b0381511660028401906001600160801b03198254161790556001600160a01b0360c083015116600184015490750100000000000000000000000000000000000000000060408501511515928654927fffffffffffffffffff0000ff000000000000000000000000000000000000000076ff000000000000000000000000000000000000000000006060890151151560b01b16921617171760018601556001600160a01b0384511691610100850151926040614a6985519560001987019061364c565b510151927fff000000000000000000000000000000000000000000000000000000000000007eff0000000000000000000000000000000000000000000000000000000000007dffffffffff0000000000000000000000000000000000000000000000000078ffffffffff000000000000000000000000000000000000000060208b015160a01b169660c81b169460f01b16911617171717845560005b818110614e58575050600185016009556001600160a01b0360c08301511660005260026020526001600160801b0380604060002054168160208401511601166001600160a01b0360c0840151166000526040600020906001600160801b03198254161790556001600160a01b036080830151168015614e1457614ba7614ba18760005260056020526001600160a01b0360406000205416151590565b156152bc565b614bb0866133f1565b1580614e0b575b80614e03575b614deb5760206000805160206158f483398151915291614bf6614ba18960005260056020526001600160a01b0360406000205416151590565b806000526006825260406000206001815401905587600052600582526040600020816001600160a01b0319825416179055876040519160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4878152a1614c866001600160a01b0360c0840151166001600160801b03808451168160208601511601169030903390615142565b6001600160801b0360408201511680614dbc575b507fef3d668acee46576ad5d407c42ab4d0cde13f3cd70b28f09a0fb9e3bf5bf09cb614d796001600160a01b03845116926001600160a01b03608086015116946001600160a01b0360c08201511696614db1614d9160408401511515928c606086015115156001600160a01b0360e061010089015194549864ffffffffff6040519a614d258c612c74565b818160a01c168c5260c81c1660208b01520151511695604051998a99610160948b523360208c015260408b0190604090816001600160801b0391828151168552826020820151166020860152015116910152565b60a089015260c08801528060e0880152860190612bca565b926101008501906020908164ffffffffff91828151168552015116910152565b6101408301520390a4565b614de5906001600160a01b0360c0850151166001600160a01b0360e08601515116903390615142565b38614c9a565b602486604051906378630aa960e01b82526004820152fd5b506000614bbd565b50801515614bb7565b606460405162461bcd60e51b815260206004820152602060248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152fd5b614e678161010086015161364c565b5190600486015491680100000000000000008310156120d457600183018060048901558310156136365760019260048801600052602060002001906001600160801b03815116908254917fffffff00000000000000000000000000000000000000000000000000000000007cffffffffff000000000000000000000000000000000000000000000000604077ffffffffffffffff00000000000000000000000000000000602086015160801b1694015160c01b169316171717905501614b05565b60449250604051917fd90b7e3900000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b6040517f210aec0e00000000000000000000000000000000000000000000000000000000815264ffffffffff918216600482015291166024820152604490fd5b9193509193614fc3906001600160801b03614fba858861364c565b51511690615730565b9364ffffffffff806040614fd7868561364c565b51015116941680851115614ff5575060018493019192919092614957565b8385606492604051927f7b0bada8000000000000000000000000000000000000000000000000000000008452600484015260248301526044820152fd5b64ffffffffff604061504384613629565b5101516040517fb4c9e52c00000000000000000000000000000000000000000000000000000000815264ffffffffff938416600482015291169091166024820152604490fd5b602490604051907f4757689b0000000000000000000000000000000000000000000000000000000082526004820152fd5b60046040517f3952c64e000000000000000000000000000000000000000000000000000000008152fd5b60046040517f6095d3bc000000000000000000000000000000000000000000000000000000008152fd5b6020823d60201161513a575b8161512760209383612cc1565b810103126132e057506148dc90516148b9565b3d915061511a565b9290604051927f23b872dd0000000000000000000000000000000000000000000000000000000060208501526001600160a01b03809216602485015216604483015260648201526064815260a081019181831067ffffffffffffffff8411176120d4576151b1926040526151b3565b565b6001600160a01b0316906152136040516151cc81612c74565b6020938482527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564858301526000808587829751910182855af161520d61312f565b91615307565b805191821591848315615298575b50505090501561522e5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152fd5b9193818094500103126132e3578201519081151582036132e0575080388084615221565b156152c357565b606460405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152fd5b91929015615368575081511561531b575090565b3b156153245790565b606460405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b82519091501561537b5750805190602001fd5b6104f19060405191829162461bcd60e51b8352602060048401526024830190612aff565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036153d157565b60046040517fa1c0d6e5000000000000000000000000000000000000000000000000000000008152fd5b916001600160a01b03604051927fa9059cbb000000000000000000000000000000000000000000000000000000006020850152166024830152604482015260448152608081019181831067ffffffffffffffff8411176120d4576151b1926040526151b3565b612d809061546e816147e0565b90600052600b60205260026040600020015460801c9061345f565b91908110156136365760051b0190565b906154a382613428565b615718576154c782600052600b6020526001600160a01b0360406000205416331490565b91821580615708575b611b96576000928184526020600581526001600160a01b039360409185838820541693806156fc575b6156d7578582169586156156c7576001600160801b03808a16998a156156b05761552288615461565b8281168c116156815750926155d68b89946001898e7f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d978f9a6155786155a1918c8552600b8b526002868620015460801c615730565b8b8452600b8a5260028585200190836001600160801b031983549260801b1691161781556133bd565b906155bc818a8401511692828681835116920151169061345f565b161115615653575b888152600b87522001541696876153fb565b85518b8152a48133141580615649575b6155f3575b505050505050565b813b15615645576084929185915196879586946313375c3b60e01b86526004860152336024860152604485015260648401525af1615636575b80808080806155eb565b61563f90612cad565b3861562c565b8480fd5b50813b15156155e6565b888152600b8752818120838101600160a01b60ff60a01b1982541617905560ff60f01b1981541690556155c4565b865163287ecaef60e21b8152600481018a90526001600160801b03928316602482015291166044820152606490fd5b60248887519063d2aabcd960e01b82526004820152fd5b6004845163630d074f60e11b8152fd5b6064858784865192632dcbf6b960e11b84526004840152336024840152166044820152fd5b508386831614156154f9565b506157128161574b565b156154d0565b60248260405190634a5541ef60e01b82526004820152fd5b9190916001600160801b0380809416911601918211611c8a57565b60009080825260056020526001600160a01b038060408420541692833314938415615790575b5050821561577e57505090565b90915061578b3392612d83565b161490565b60ff9294509060409181526008602052818120338252602052205416913880615771565b9092916157bf61339e565b936001600160801b03928381169182156158cb5767016345785d8a00008082116158945780851161585d5750615809856157fa819386613b4b565b16946020890195865284613b4b565b169184615820604089019480865282875116615730565b161015615847576158398491826158429551169061345f565b9151169061345f565b168252565b634e487b7160e01b600052600160045260246000fd5b84604491604051917f4fea5c1a00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b60449250604051917f47152d6700000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b505050505090506040516158de81612c3b565b6000815260006020820152600060408201529056fef8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7a164736f6c6343000815000a"; bytes public constant BYTECODE_LOCKUP_LINEAR = - hex"60a034620003e757601f196001600160401b03601f62004dae3881900382810185168601919084831187841017620003ec57808792606094604052833981010312620003e75783516001600160a01b03928382169291839003620003e7576020918287015196858816809803620003e75760400151948516809503620003e7576200008962000402565b90601c82527f5361626c696572205632204c6f636b7570204c696e656172204e46540000000084830152620000bd62000402565b601181527029a0a116ab1916a627a1a5aaa816a624a760791b8582015230608052600080546001600160a01b031990811688178255600180548216909b178b5596817fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808180a38351858111620003d35760039485548c81811c91168015620003c8575b89821014620003b45790818684931162000361575b508890868311600114620002f8578492620002ec575b505060001982871b1c1916908b1b1784555b8151948511620002d8576004958654998b8b811c9b168015620002cd575b828c1014620002ba57848b1162000271575b869798999a50819487116001146200020a57505093620001fe575b505082871b92600019911b1c19161790555b600a541617600a5560095560405161498b9081620004238239608051816146950152f35b015191503880620001c8565b8883528183208c9890969594939116915b8282106200025757505085116200023c575b50505050811b019055620001da565b01519060f884600019921b161c19169055388080806200022d565b8484015187558c989096019593840193908101906200021b565b87835281832085880160051c81019b838910620002af575b860160051c019a8c905b8c8110620002a3575050620001ad565b848155018c9062000293565b909b508b9062000289565b634e487b7160e01b835260228852602483fd5b9a607f169a6200019b565b634e487b7160e01b81526041600452602490fd5b0151905038806200016b565b908c8e9416918886528a862092865b8c82821062000341575050841162000328575b505050811b0184556200017d565b015160001983891b60f8161c191690553880806200031a565b91929395968291958786015181550195019301908f959493929162000307565b9091508684528884208680850160051c8201928b8610620003aa575b918f91869594930160051c01915b8281106200039b57505062000155565b8681558594508f91016200038b565b925081926200037d565b634e487b7160e01b84526022600452602484fd5b90607f169062000140565b634e487b7160e01b82526041600452602482fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b60408051919082016001600160401b03811183821017620003ec5760405256fe608080604052600436101561001357600080fd5b600090813560e01c90816301ffc9a714612f345750806306fdde0314612e72578063081812fc14612e53578063095ea7b314612cc45780631400ecec14612c245780631c1cdd4c14612bbf5780631e99d56914612ba157806323b872dd14612b7757806339a73c0314612b3657806340e58ee51461279b578063425d30dd1461277c57806342842e0e1461272c57806342966c68146125d45780634857501f1461254a5780634869e12d1461250f5780635fe3b567146124e85780636352211e146124b85780636d0cee751461246257806370a08231146123b957806375829def14612326578063780a82c8146122d65780637cad6cd1146122055780637de6b1db146120155780638659c27014611c0a578063894e9a0d146119b65780638bad38dd146119395780638f69b9931461189d5780639067b6771461184a57806395d89b411461173d57806396ce14311461161e578063a22cb4651461154d578063a2ffb89714611186578063a6202bf214611089578063a80fc07114611037578063ab167ccc14610efe578063ad35efd414610e9c578063b256456914610e7d578063b88d4fde14610dec578063b8a3be6614610db7578063b971302a14610d68578063bc063e1a14610d45578063bc2be1be14610cf5578063c156a11d14610998578063c87b56dd1461085e578063cc364f48146107b0578063d4dbd20b1461075e578063d511609f14610712578063d975dfed146106c6578063e985e9c514610671578063ea5ead191461064b578063eac8f5b8146105e2578063f590c176146105b9578063f851a440146105935763fdd46d601461027357600080fd5b346105905760603660031901126105905760043561028f613063565b6102976131a3565b916102a061468b565b6102a981613821565b610578576102cd81600052600b6020526001600160a01b0360406000205416331490565b91821580610568575b61054557818552602092600584526001600160a01b0391826040882054169180610539575b610513578281169283156104e9576001600160801b038088169788156104d157816103258861474d565b16808a116104ad5750926103c692899261038d6103558d98978b8a52600b8d52600260408b20015460801c61479b565b8a8952600b8c52610388600260408b20019182906001600160801b036001600160801b031983549260801b169116179055565b6137b6565b906103a9818c8401511692826040818351169201511690613858565b16111561047d575b878652600b89526001604087200154166146e7565b8033141580610473575b61041b575b5050817ffa54f9f9bdcdd28778cbb9f78490df6691cc4e2729588e10f4cc0a26c465686a8460008051602061495f83398151915296604051908152a3604051908152a180f35b803b1561046f578180916084604051809481936313375c3b60e01b83528960048401523360248401528860448401528b60648401525af1156103d557610460906130df565b61046b5784386103d5565b8480fd5b5080fd5b50803b15156103d0565b878652600b89526040862060018101600160c81b60ff60c81b1982541617905560ff60f01b1981541690556103b1565b876064918b6040519263287ecaef60e21b8452600484015260248301526044820152fd5b6024876040519063d2aabcd960e01b82526004820152fd5b60046040517fc61a0e9e000000000000000000000000000000000000000000000000000000008152fd5b838360649260405192632dcbf6b960e11b84526004840152336024840152166044820152fd5b508183821614156102fb565b60405163216caf0d60e01b815260048101839052336024820152604490fd5b0390fd5b50610572826147b6565b156102d6565b60249060405190634a5541ef60e01b82526004820152fd5b80fd5b50346105905780600319360112610590576001600160a01b036020915416604051908152f35b50346105905760203660031901126105905760206105d8600435613887565b6040519015158152f35b503461059057602036600319011261059057600435808252600b60205260ff600160408420015460d01c16156106345760016040836001600160a01b039360209552600b855220015416604051908152f35b6024906040519062b8e7e760e51b82526004820152fd5b503461059057604036600319011261059057600435610668613063565b6102978261474d565b50346105905760403660031901126105905761068b61304d565b6040610695613063565b926001600160a01b0380931681526008602052209116600052602052602060ff604060002054166040519015158152f35b50346105905760203660031901126105905760ff6001604060043593848152600b60205220015460d01c16156106345761070160209161474d565b6001600160801b0360405191168152f35b503461059057602036600319011261059057600435808252600b60205260ff600160408420015460d01c16156106345760408260029260209452600b845220015460801c604051908152f35b503461059057602036600319011261059057600435808252600b60205260ff600160408420015460d01c16156106345760036040836001600160801b039360209552600b855220015416604051908152f35b5034610590576020366003190112610590576004356107cd613797565b50808252600b60205260ff600160408420015460d01c1615610634578160409160609352600b60205220600181549164ffffffffff918291015460a01c1690604051926108198461312d565b818160a01c16845260c81c166020830152604082015261085c60405180926040908164ffffffffff91828151168552826020820151166020860152015116910152565bf35b50346105905760208060031936011261046f5760043561089c6108978260005260056020526001600160a01b0360406000205416151590565b6131b9565b826001600160a01b03600a5416916044604051809481937fe9dc637500000000000000000000000000000000000000000000000000000000835230600484015260248301525afa92831561098c57809361090b575b5050610907604051928284938452830190613028565b0390f35b909192503d8082843e61091e8184613165565b820191838184031261046f5780519067ffffffffffffffff8211610988570182601f8201121561046f5780519161095483613187565b936109626040519586613165565b83855285848401011161059057509061098091848085019101613005565b9038806108f1565b8280fd5b604051903d90823e3d90fd5b5034610590576040366003190112610590576004356109b5613063565b906109be61468b565b808352602090600b825260ff600160408620015460d01c161561063457808452600582526001600160a01b038060408620541690813303610cd657610a028361474d565b6001600160801b0391828216928315928315610a40575b8960008051602061495f8339815191528989610a36818e8c61344c565b604051908152a180f35b610a4861468b565b610a5187613821565b610cbe57610a7587600052600b6020526001600160a01b0360406000205416331490565b93841580610cae575b610c8f57878b52600589528360408c2054169480610c85575b610c615786156104e9576104d15781610aaf8861474d565b16808611610c3d5750858a9493610b4b93610b12610adf8995600b8e8e8c5252600260408b20015460801c61479b565b8b8952600b8d52610388600260408b20019182906001600160801b036001600160801b031983549260801b169116179055565b90610b2e818d8401511692826040818351169201511690613858565b161115610c0d575b888652600b8a526001604087200154166146e7565b8033141580610c03575b610baf575b505060008051602061495f8339815191529482610a3693857ffa54f9f9bdcdd28778cbb9f78490df6691cc4e2729588e10f4cc0a26c465686a888296604051908152a38686604051858152a192819638610a19565b803b1561046f578180916084604051809481936313375c3b60e01b83528a60048401523360248401528960448401528860648401525af115610b5a57610bf4906130df565b610bff578538610b5a565b8580fd5b50803b1515610b55565b888652600b8a526040862060018101600160c81b60ff60c81b1982541617905560ff60f01b198154169055610b36565b87606491876040519263287ecaef60e21b8452600484015260248301526044820152fd5b6064888860405191632dcbf6b960e11b835260048301523360248301526044820152fd5b5084871415610a97565b60405163216caf0d60e01b815260048101899052336024820152604490fd5b50610cb8886147b6565b15610a7e565b60248760405190634a5541ef60e01b82526004820152fd5b60405163216caf0d60e01b815260048101849052336024820152604490fd5b503461059057602036600319011261059057600435808252600b60205260ff600160408420015460d01c16156106345760408264ffffffffff9260209452600b8452205460a01c16604051908152f35b5034610590578060031936011261059057602060405167016345785d8a00008152f35b503461059057602036600319011261059057600435808252600b60205260ff600160408420015460d01c1615610634576040826001600160a01b039260209452600b8452205416604051908152f35b50346105905760203660031901126105905760ff600160406020936004358152600b855220015460d01c166040519015158152f35b503461059057608036600319011261059057610e0661304d565b610e0e613063565b906064359067ffffffffffffffff8211610e795736602383011215610e795781600401359284610e3d85613187565b93610e4b6040519586613165565b858552366024878301011161046f5785610e76966024602093018388013785010152604435916132d7565b80f35b8380fd5b50346105905760203660031901126105905760206105d86004356137ea565b503461059057602036600319011261059057600435808252600b60205260ff600160408420015460d01c161561063457610ed590613afd565b604051906005811015610eea57602092508152f35b602483634e487b7160e01b81526021600452fd5b50346105905761014036600319011261059057610f1961468b565b610f21613797565b9064ffffffffff80421680845260c43582811681036110325781018216602085015260e4359081831682036110325701166040830152606435916001600160a01b039182841680940361059057506084358015158091036110325760a435908115158092036110325760243594848616809603611032576004359585871680970361103257604435906001600160801b0382168092036110325760405197610fc889613110565b8852602088015260408701526060860152608085015260a084015260c0830152604061010319360112611032576040519161100283613149565b610104359182168203611032578261102a9260209452610124358482015260e0820152613bff565b604051908152f35b600080fd5b503461059057602036600319011261059057600435808252600b60205260ff600160408420015460d01c16156106345760026040836001600160801b039360209552600b855220015416604051908152f35b5034610590576020366003190112610590576110a361304d565b6001600160a01b038083541633810361115d575081169081835260026020526001600160801b0360408420541690811561112c57816110fd918486526002602052604086206001600160801b0319815416905533906146e7565b6040519081527fca7a4a65a94ed2f37538814e00e1cd4c41a78261561e3f3794592f11409cf5af60203392a380f35b602483604051907f8410168c0000000000000000000000000000000000000000000000000000000082526004820152fd5b6040516331b339a960e21b81526001600160a01b03919091166004820152336024820152604490fd5b50346105905760603660031901126105905767ffffffffffffffff600435818111610988576111b99036906004016130ae565b916111c2613063565b9060443590811161046b576111db9036906004016130ae565b90936111e561468b565b81810361151757855b8181106111f9578680f35b611204818387614775565b3590611211818589614775565b35916001600160801b03831683036110325761122b61468b565b61123481613821565b6105785761125881600052600b6020526001600160a01b0360406000205416331490565b801580611507575b61054557818a5260056020526001600160a01b0360408b20541690806114f4575b6114c7576001600160a01b038716156104e9576001600160801b038416156114af576001600160801b036112b48361474d565b16806001600160801b0386161161148257508990828252600b8060205261131b60026103886112ec898360408920015460801c61479b565b918787528460205260408720019182906001600160801b036001600160801b031983549260801b169116179055565b6001600160801b0361133f8160208401511692826040818351169201511690613858565b161115611452575b8383526020526113716001600160801b038616896001600160a01b036001604087200154166146e7565b8033141580611448575b6113e2575b5050602060008051602061495f833981519152916001946001600160801b0360405191168152817ffa54f9f9bdcdd28778cbb9f78490df6691cc4e2729588e10f4cc0a26c465686a846001600160a01b038c1693a3604051908152a1016111ee565b803b1561046f57816001600160a01b0360848a8360405195869485936313375c3b60e01b85528a60048601523360248601521660448401526001600160801b038b1660648401525af11561138057611439906130df565b611444578838611380565b8880fd5b50803b151561137b565b838352806020526040832060018101600160c81b60ff60c81b1982541617905560ff60f01b198154169055611347565b826064916001600160801b03876040519363287ecaef60e21b855260048501521660248301526044820152fd5b6024826040519063d2aabcd960e01b82526004820152fd5b6064826001600160a01b038960405192632dcbf6b960e11b84526004840152336024840152166044820152fd5b50806001600160a01b0388161415611281565b50611511826147b6565b15611260565b604491604051917faec9344000000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b50346105905760403660031901126105905761156761304d565b60243590811515809203611032576001600160a01b0316908133146115da5733835260086020526040832082600052602052604060002060ff1981541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a380f35b606460405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152fd5b5034610590576101603660031901126105905761163961468b565b6040519061164682613110565b61164e61304d565b8252611658613063565b60208301526116656131a3565b60408301526001600160a01b03906064358281168103611032576060840152608435801515810361103257608084015260a43580151581036110325760a084015260603660c319011261059057506040516116bf8161312d565b64ffffffffff60c435818116810361103257825260e435818116810361103257602083015261010435908116810361103257604082015260c0830152604061012319360112611032576040519161171583613149565b610124359182168203611032578261102a9260209452610144358482015260e0820152613bff565b5034610590578060031936011261059057604051908060045491600183811c92818516948515611840575b602095868610811461182c5785885287949392918790821561180a5750506001146117b0575b505061179c92500383613165565b610907604051928284938452830190613028565b90859250600482527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b8583106117f257505061179c9350820101388061178e565b805483890185015287945086939092019181016117da565b925093505061179c94915060ff191682840152151560051b820101388061178e565b602483634e487b7160e01b81526022600452fd5b93607f1693611768565b503461059057602036600319011261059057600435808252600b60205260ff600160408420015460d01c161561063457600160408364ffffffffff9360209552600b855220015460a01c16604051908152f35b503461059057602036600319011261059057600435808252600b60205260ff600160408420015460d01c1615610634576118d690613afd565b9060058210159081611917576002831491821561192b575b8215611902575b6020836040519015158152f35b909150611917575060046020911438806118f5565b80634e487b7160e01b602492526021600452fd5b5060038314915060006118ee565b5034610590576020366003190112610590576004356001600160a01b0390818116809103610988578183541633810361115d575060015491816001600160a01b03198416176001556040519216825260208201527fdcb09aef4bf01068924ccce937981cbe59d25ba08380cf941aaaea4e4bd3960d60403392a280f35b5034610590576020366003190112610590576040516119d4816130f3565b8181528160208201528160408201528160608201528160808201528160a08201528160c08201528160e08201528161010082015281610120820152610140611a1a613797565b9101526004358152600b60205260ff600160408320015460d01c1615611bf2576004358152600b60205260408120611af3600260405192611a5a846130f3565b80546001600160a01b038116855264ffffffffff8160a01c16602086015264ffffffffff8160c81c16604086015260ff8160f01c161515606086015260f81c1515608085015260ff60018201546001600160a01b03811660a087015264ffffffffff8160a01c1660c0870152818160c81c16151560e0870152818160d01c16151561010087015260d81c161515610120850152016137b6565b610140820152611b04600435613afd565b6005811015610eea579160026101a09314611be7575b5061085c610140604051926001600160a01b03815116845264ffffffffff602082015116602085015264ffffffffff60408201511660408501526060810151151560608501526080810151151560808501526001600160a01b0360a08201511660a085015264ffffffffff60c08201511660c085015260e0810151151560e0850152610100810151151561010085015261012081015115156101208501520151610140830190604090816001600160801b0391828151168552826020820151166020860152015116910152565b606082015238611b1a565b602460405162b8e7e760e51b81526004356004820152fd5b503461059057602090816003193601126105905760043567ffffffffffffffff811161046f57611c3f839136906004016130ae565b90611c4861468b565b83915b808310611c56578480f35b611c6583828497959697614775565b3593611c6f61468b565b611c7885613821565b15611c955760248560405190634a5541ef60e01b82526004820152fd5b90919293611ca281613887565b611ffd57611cc681600052600b6020526001600160a01b0360406000205416331490565b1580611fdf575b611fbf57611cda816138b8565b818652600b90818852611cf2600260408920016137b6565b6001600160801b0391828251168382161015611fa757848952838a5260ff60408a205460f01c1615611f8f57928282611d4486838e611d3a8f9a829a60409e9d9a5116613858565b9401511690613858565b84875283865288872091611dca835494600160f81b7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff87161785556003818516958615611f75575b0190831699818b6001600160801b0319819454161790556001600160a01b0380971696879160058c52818f82205416998c5260019e8f91200154166146e7565b338403611eb357843b611e2c575b50507f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd2604060008051602061495f8339815191529786935b825191825288820152a4604051908152a1019190939293611c4b565b90919293809596503b15611eaf576040516372eba20360e01b8152600481018790526001600160a01b03851660248201526001600160801b039182166044820152911660648201528b94939291908b90818160848183895af115611dd857611e9a91929395979496506130df565b611eab57918a939194928a8d611dd8565b8980fd5b8b80fd5b833b611ef6575b50507f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd2604060008051602061495f833981519152978693611e10565b90919280949596503b15611eaf576040516372eba20360e01b8152600481018790526001600160a01b03861660248201526001600160801b039182166044820152911660648201528b94939291908b90818160848183885af115611eba57611f6491929395979496506130df565b611eab57918a939194928a8d611eba565b60018101600160c81b60ff60c81b19825416179055611d8a565b602485604051906339c6dc7360e21b82526004820152fd5b602485604051906322cad1af60e11b82526004820152fd5b60405163216caf0d60e01b81526004810191909152336024820152604490fd5b50808552600586526001600160a01b03604086205416331415611ccd565b6024906040519063fe19f19f60e01b82526004820152fd5b50346105905760208060031936011261046f576004359061203461468b565b818352600b815260ff600160408520015460d01c16156121ee5761205782613afd565b60058110156121da57600481036120805760248360405190634a5541ef60e01b82526004820152fd5b600381036120a0576024836040519063fe19f19f60e01b82526004820152fd5b6002146121c2576120c782600052600b6020526001600160a01b0360406000205416331490565b1561054557818352600b815260ff604084205460f01c16156121aa57818352600b81526040832060ff60f01b19815416905560058152826001600160a01b03604082205416803b612153575b505060405160008051602061495f83398151915292807f0eb069207093cd3e51cd1370d2d369770057fbe29947e577e5fb428c6c6fc78f8680a28152a180f35b803b1561046f578180916024604051809481937f341a0bd90000000000000000000000000000000000000000000000000000000083528960048401525af1156121135761219f906130df565b610988578238612113565b602482604051906339c6dc7360e21b82526004820152fd5b602482604051906322cad1af60e11b82526004820152fd5b602484634e487b7160e01b81526021600452fd5b6024826040519062b8e7e760e51b82526004820152fd5b5034610590576020366003190112610590576004356001600160a01b0390818116809103610988578183541633810361115d5750600a5491816001600160a01b0319841617600a556040519216825260208201527fa2548bd4b805e907c1558a47b5858324fe8bb4a2e1ddfca647eecbf65610eebc60403392a260095460001981019081116122c25760407f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c91815190600182526020820152a180f35b602482634e487b7160e01b81526011600452fd5b503461059057602036600319011261059057600435808252600b60205260ff600160408420015460d01c16156106345760408264ffffffffff9260209452600b8452205460c81c16604051908152f35b50346105905760203660031901126105905761234061304d565b9080546001600160a01b0380821693338503612392576001600160a01b03199394501691829116178255337fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808380a380f35b6040516331b339a960e21b81526001600160a01b0386166004820152336024820152604490fd5b5034610590576020366003190112610590576001600160a01b036123db61304d565b1680156123f8578160409160209352600683522054604051908152f35b608460405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152fd5b5034610590576020366003190112610590576001600160a01b0360406020926004356124a76108978260005260056020526001600160a01b0360406000205416151590565b815260058452205416604051908152f35b50346105905760203660031901126105905760206124d7600435613204565b6001600160a01b0360405191168152f35b503461059057806003193601126105905760206001600160a01b0360015416604051908152f35b50346105905760203660031901126105905760ff6001604060043593848152600b60205220015460d01c161561063457610701602091613b84565b50346105905760203660031901126105905760043590818152600b60205260ff600160408320015460d01c16156121ee578061258583613afd565b9260058410156125c0576002602094036125a6575b50506040519015158152f35b8152600b8352604090205460f01c60ff169050388061259a565b602482634e487b7160e01b81526021600452fd5b5034610590576020366003190112610590576004356125f161468b565b6125fa81613821565b156126fb57612608816147b6565b15611fbf5761261681613204565b61261f826137ea565b1590816126f3575b816126e0575b506126c85760208161264d60008051602061495f83398151915293613204565b90808552600783526001600160a01b0360408620926001600160a01b03199384815416905516918286526006845260408620600019815401905581865260058452604086209081541690558085604051937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a48152a180f35b602490604051906378630aa960e01b82526004820152fd5b6001600160a01b0391501615153861262d565b839150612627565b602490604051907f817cd6390000000000000000000000000000000000000000000000000000000082526004820152fd5b50346105905761273b36613079565b60405191602083019383851067ffffffffffffffff86111761276657610e76946040528584526132d7565b634e487b7160e01b600052604160045260246000fd5b50346105905760203660031901126105905760206105d8600435613821565b50346105905760208060031936011261046f57600435906127ba61468b565b6127c382613821565b156127e05760248260405190634a5541ef60e01b82526004820152fd5b6127e982613887565b612b1e5761280d82600052600b6020526001600160a01b0360406000205416331490565b1580612b00575b61054557612821826138b8565b91808452600b8252612838600260408620016137b6565b6001600160801b0393848251168582161015612ae857828652600b845260ff604087205460f01c1615612ad0578161287c828787611d3a6040968383995116613858565b848852600b845282882091612902835498600160f81b7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8b161785558a6003828616968715612ab6575b019184169a828c6001600160801b03198195541617905560016001600160a01b0380921698899360058c52600b8483832054169c52200154166146e7565b3384036129cd57908891853b612960575b5050507f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd2604060008051602061495f8339815191529786935b825191825288820152a4604051908152a180f35b853b15610988576040516372eba20360e01b8152600481018890526001600160a01b03861660248201526001600160801b03918216604482015291166064820152818160848183895af16129b5575b80612913565b6129be906130df565b6129c95786386129af565b8680fd5b83989792983b612a15575b50507f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd26040859260008051602061495f833981519152989961294c565b833b15612ab2576040516372eba20360e01b8152600481018790526001600160a01b03861660248201526001600160801b03918216604482015291166064820152868160848183875af1612a6a575b806129d8565b6040859260008051602061495f83398151915298612aa87f2971bd77136e1a620a6b1eb4ad5edd190e9fd391b26bfc5dea50b882fc6b9fd2946130df565b9850925050612a64565b8780fd5b60018101600160c81b60ff60c81b198254161790556128c4565b602483604051906339c6dc7360e21b82526004820152fd5b602483604051906322cad1af60e11b82526004820152fd5b50818352600581526001600160a01b03604084205416331415612814565b6024826040519063fe19f19f60e01b82526004820152fd5b5034610590576020366003190112610590576001600160801b0360406020926001600160a01b03612b6561304d565b16815260028452205416604051908152f35b503461059057610e76612b8936613079565b91612b9c612b97843361336d565b613266565b61344c565b50346105905780600319360112610590576020600954604051908152f35b503461059057602036600319011261059057600435808252600b60205260ff600160408420015460d01c161561063457612bf890613afd565b9060058210156119175760208215838115612c19575b506040519015158152f35b600191501482612c0e565b50346105905760203660031901126105905760043590818152600b60205260ff600160408320015460d01c16156121ee57602091604082828152600b85522060ff815460f01c1680612cb2575b612c89575b50506001600160801b0360405191168152f35b612cab92506001600160801b036002612ca592015416916138b8565b90613858565b3880612c76565b5060ff600182015460c81c1615612c71565b503461059057604036600319011261059057612cde61304d565b602435906001600160a01b038080612cf585613204565b16921691808314612de957803314908115612dc8575b5015612d5e57828452600760205260408420826001600160a01b0319825416179055612d3683613204565b167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258480a480f35b608460405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152fd5b9050845260086020526040842033855260205260ff60408520541638612d0b565b608460405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152fd5b50346105905760203660031901126105905760206124d7600435613229565b5034610590578060031936011261059057604051908060035491600183811c92818516948515612f2a575b602095868610811461182c5785885287949392918790821561180a575050600114612ed057505061179c92500383613165565b90859250600382527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b858310612f1257505061179c9350820101388061178e565b80548389018501528794508693909201918101612efa565b93607f1693612e9d565b90503461046f57602036600319011261046f576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361098857602092507f80ac58cd000000000000000000000000000000000000000000000000000000008114908115612fdb575b8115612fb1575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501438612faa565b7f5b5e139f0000000000000000000000000000000000000000000000000000000081149150612fa3565b60005b8381106130185750506000910152565b8181015183820152602001613008565b9060209161304181518092818552858086019101613005565b601f01601f1916010190565b600435906001600160a01b038216820361103257565b602435906001600160a01b038216820361103257565b6060906003190112611032576001600160a01b0390600435828116810361103257916024359081168103611032579060443590565b9181601f840112156110325782359167ffffffffffffffff8311611032576020808501948460051b01011161103257565b67ffffffffffffffff811161276657604052565b610160810190811067ffffffffffffffff82111761276657604052565b610100810190811067ffffffffffffffff82111761276657604052565b6060810190811067ffffffffffffffff82111761276657604052565b6040810190811067ffffffffffffffff82111761276657604052565b90601f8019910116810190811067ffffffffffffffff82111761276657604052565b67ffffffffffffffff811161276657601f01601f191660200190565b604435906001600160801b038216820361103257565b156131c057565b606460405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152fd5b60005260056020526001600160a01b03604060002054166132268115156131b9565b90565b61324c6108978260005260056020526001600160a01b0360406000205416151590565b60005260076020526001600160a01b036040600020541690565b1561326d57565b608460405162461bcd60e51b815260206004820152602d60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206f7220617070726f766564000000000000000000000000000000000000006064820152fd5b906132fb9392916132eb612b97843361336d565b6132f683838361344c565b613605565b1561330257565b60405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608490fd5b906001600160a01b03808061338184613204565b169316918383149384156133b4575b50831561339e575b50505090565b6133aa91929350613229565b1614388080613398565b909350600052600860205260406000208260005260205260ff604060002054169238613390565b156133e257565b608460405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152fd5b90613475929161345b83613204565b916001600160a01b039485938480941696879116146133db565b169081158061356c57613487846137ea565b159081613563575b508061355a575b61354257918084926134c460008051602061495f833981519152966020966134bd85613204565b16146133db565b60009382855260078652604085206001600160a01b031990818154169055818652600687526040862060001981540190558286526040862060018154019055838652600587528260408720918254161790557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6040519580a48152a1565b602483604051906378630aa960e01b82526004820152fd5b50831515613496565b9050153861348f565b608460405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152fd5b3d15613600573d906135e682613187565b916135f46040519384613165565b82523d6000602084013e565b606090565b9290803b1561378e5761366f916020916001600160a01b0394604051809581948293897f150b7a02000000000000000000000000000000000000000000000000000000009b8c86523360048701521660248501526044840152608060648401526084830190613028565b03916000968791165af19082908261372e575b5050613708576136906135d5565b805190816137035760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608490fd5b602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000161490565b909192506020813d8211613786575b8161374a60209383613165565b8101031261046f5751907fffffffff00000000000000000000000000000000000000000000000000000000821682036105905750903880613682565b3d915061373d565b50505050600190565b604051906137a48261312d565b60006040838281528260208201520152565b906040516137c38161312d565b6040819360018154916001600160801b0392838116865260801c6020860152015416910152565b80600052600b60205260ff60016040600020015460d01c161561063457600052600b60205260ff60016040600020015460d81c1690565b80600052600b60205260ff60016040600020015460d01c161561063457600052600b60205260ff60016040600020015460c81c1690565b6001600160801b03918216908216039190821161387157565b634e487b7160e01b600052601160045260246000fd5b80600052600b60205260ff60016040600020015460d01c161561063457600052600b60205260406000205460f81c90565b600090808252600b6020526040822091825464ffffffffff42818360c81c16116139665780600186015460a01c169182421015613950576139059394955060a01c1680910390420361396e565b90828152600b6020526001600160801b039261392b846002604085200154168094613a4e565b9283116139385750501690565b60029350604092508152600b60205220015460801c90565b505050505060026001600160801b039101541690565b505091505090565b670de0b6b3a7640000916000198383099280830292838086109503948086039514613a2a57828510156139ee57908291096001821901821680920460028082600302188083028203028083028203028083028203028083028203028083028203028092029003029360018380600003040190848311900302920304170290565b82606492604051927f63a05778000000000000000000000000000000000000000000000000000000008452600484015260248301526044820152fd5b505080925015613a38570490565b634e487b7160e01b600052601260045260246000fd5b90919060001983820983820291828083109203918083039214613aec57670de0b6b3a76400009081831015613ab557947faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac1066994950990828211900360ee1b910360121c170290565b60449086604051917f5173648d00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b5050670de0b6b3a764000090049150565b80600052600b602052604060002060ff600182015460c81c16600014613b24575050600490565b805460f81c613b7d575460a01c64ffffffffff164210613b7757613b47816138b8565b90600052600b6020526001600160801b038060026040600020015416911610600014613b7257600190565b600290565b50600090565b5050600390565b80600052600b602052613b9d60026040600020016137b6565b81600052600b602052604060002060ff600182015460c81c16600014613bd057506001600160801b039150602001511690565b5460f81c613be25750613226906138b8565b61322691506001600160801b036040818351169201511690613858565b906001600160a01b036001541660206001600160a01b036060850151166024604051809481937fdcf844a700000000000000000000000000000000000000000000000000000000835260048301525afa8015614422576000906143ee575b613c8091506001600160801b0360408501511690602060e086015101519161481f565b916001600160801b0383511660c082015190156143c45764ffffffffff815116602082019064ffffffffff8251169081811161438457505064ffffffffff604091511691019064ffffffffff825116908181101561434457505064ffffffffff8042169151169081811015614304575050600954926001600160801b0381511660405190613d0d8261312d565b815260006020820152600060408201526001600160a01b036060840151169060c08401519164ffffffffff6020840151169064ffffffffff604085015116906080870151151560a088015115159364ffffffffff6001600160a01b038a511697511660405197613d7c896130f3565b88526020880152604087015260608601526000608086015260a085015260c0840152600060e0840152600161010084015261012083015261014082015284600052600b60205260406000206001600160a01b038251166001600160a01b0319825416178155613e1364ffffffffff602084015116829064ffffffffff60a01b1964ffffffffff60a01b83549260a01b169116179055565b604082015181547eff0000000000000000000000000000000000000000000000000000000000006060850151151560f01b169078ffffffffffffffffffffffffffffffffffffffffffffffffff7dffffffffff000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000006080880151151560f81b169460c81b1691161717178155600181016001600160a01b0360a0840151166001600160a01b0319825416178155613f0a64ffffffffff60c085015116829064ffffffffff60a01b1964ffffffffff60a01b83549260a01b169116179055565b60e083015181546101008501516101208601517fffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff90921692151560c81b79ff00000000000000000000000000000000000000000000000000169290921791151560d01b7aff0000000000000000000000000000000000000000000000000000169190911790151560d81b7bff00000000000000000000000000000000000000000000000000000016179055610140909101518051602082015160801b6001600160801b03199081166001600160801b03928316176002850155926040906003019201511682825416179055600185016009556001600160a01b0360608401511660005260026020526001600160801b0380604060002054168160208501511601166001600160a01b036060850151166000526040600020918254161790556001600160a01b0360208301511680156142c05761408561407f8660005260056020526001600160a01b0360406000205416151590565b156145a8565b61408e856137ea565b15806142b7575b806142af575b61429757602060008051602061495f833981519152916140d461407f8860005260056020526001600160a01b0360406000205416151590565b806000526006825260406000206001815401905586600052600582526040600020816001600160a01b0319825416179055866040519160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4868152a16141646001600160a01b036060840151166001600160801b0380845116816020860151160116903090339061442e565b6001600160801b0360408201511680614268575b506001600160a01b038251167f075861cbceafeb777e8f15f357121b08f6f3adba387d599bb7b5278ca6192df5610160866001600160a01b036020870151169461425f6001600160a01b03606089015116976080810151151560a08201511515906142296001600160a01b0360e060c08601519501515116956040519788523360208901526040880190604090816001600160801b0391828151168552826020820151166020860152015116910152565b60a086015260c0850152805164ffffffffff90811660e08601526020820151811661010086015260409091015116610120840152565b610140820152a4565b614291906001600160a01b036060850151166001600160a01b0360e0860151511690339061442e565b38614178565b602485604051906378630aa960e01b82526004820152fd5b50600061409b565b50801515614095565b606460405162461bcd60e51b815260206004820152602060248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152fd5b6040517f210aec0e00000000000000000000000000000000000000000000000000000000815264ffffffffff918216600482015291166024820152604490fd5b6040517f9fee269100000000000000000000000000000000000000000000000000000000815264ffffffffff918216600482015291166024820152604490fd5b6040517f4c23297000000000000000000000000000000000000000000000000000000000815264ffffffffff918216600482015291166024820152604490fd5b60046040517f6095d3bc000000000000000000000000000000000000000000000000000000008152fd5b6020823d60201161441a575b8161440760209383613165565b810103126105905750613c809051613c5d565b3d91506143fa565b6040513d6000823e3d90fd5b9290604051927f23b872dd0000000000000000000000000000000000000000000000000000000060208501526001600160a01b03809216602485015216604483015260648201526064815260a081019181831067ffffffffffffffff8411176127665761449d9260405261449f565b565b6001600160a01b0316906144ff6040516144b881613149565b6020938482527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564858301526000808587829751910182855af16144f96135d5565b916145f3565b805191821591848315614584575b50505090501561451a5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152fd5b91938180945001031261046f5782015190811515820361059057508038808461450d565b156145af57565b606460405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152fd5b919290156146545750815115614607575090565b3b156146105790565b606460405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156146675750805190602001fd5b6105649060405191829162461bcd60e51b8352602060048401526024830190613028565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036146bd57565b60046040517fa1c0d6e5000000000000000000000000000000000000000000000000000000008152fd5b916001600160a01b03604051927fa9059cbb000000000000000000000000000000000000000000000000000000006020850152166024830152604482015260448152608081019181831067ffffffffffffffff8411176127665761449d9260405261449f565b6132269061475a81613b84565b90600052600b60205260026040600020015460801c90613858565b91908110156147855760051b0190565b634e487b7160e01b600052603260045260246000fd5b9190916001600160801b038080941691160191821161387157565b60009080825260056020526001600160a01b0380604084205416928333149384156147fb575b505082156147e957505090565b9091506147f63392613229565b161490565b60ff92945090604091815260086020528181203382526020522054169138806147dc565b90929161482a613797565b936001600160801b03928381169182156149365767016345785d8a00008082116148ff578085116148c8575061487485614865819386613a4e565b16946020890195865284613a4e565b16918461488b60408901948086528287511661479b565b1610156148b2576148a48491826148ad95511690613858565b91511690613858565b168252565b634e487b7160e01b600052600160045260246000fd5b84604491604051917f4fea5c1a00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b60449250604051917f47152d6700000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b505050505090506040516149498161312d565b6000815260006020820152600060408201529056fef8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7a164736f6c6343000815000a"; + hex"60a034620003e757601f196001600160401b03601f62004c633881900382810185168601919084831187841017620003ec57808792606094604052833981010312620003e75783516001600160a01b03928382169291839003620003e7576020918287015196858816809803620003e75760400151948516809503620003e7576200008962000402565b90601c82527f5361626c696572205632204c6f636b7570204c696e656172204e46540000000084830152620000bd62000402565b601181527029a0a116ab1916a627a1a5aaa816a624a760791b8582015230608052600080546001600160a01b031990811688178255600180548216909b178b5596817fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808180a38351858111620003d35760039485548c81811c91168015620003c8575b89821014620003b45790818684931162000361575b508890868311600114620002f8578492620002ec575b505060001982871b1c1916908b1b1784555b8151948511620002d8576004958654998b8b811c9b168015620002cd575b828c1014620002ba57848b1162000271575b869798999a50819487116001146200020a57505093620001fe575b505082871b92600019911b1c19161790555b600a541617600a5560095560405161484090816200042382396080518161454a0152f35b015191503880620001c8565b8883528183208c9890969594939116915b8282106200025757505085116200023c575b50505050811b019055620001da565b01519060f884600019921b161c19169055388080806200022d565b8484015187558c989096019593840193908101906200021b565b87835281832085880160051c81019b838910620002af575b860160051c019a8c905b8c8110620002a3575050620001ad565b848155018c9062000293565b909b508b9062000289565b634e487b7160e01b835260228852602483fd5b9a607f169a6200019b565b634e487b7160e01b81526041600452602490fd5b0151905038806200016b565b908c8e9416918886528a862092865b8c82821062000341575050841162000328575b505050811b0184556200017d565b015160001983891b60f8161c191690553880806200031a565b91929395968291958786015181550195019301908f959493929162000307565b9091508684528884208680850160051c8201928b8610620003aa575b918f91869594930160051c01915b8281106200039b57505062000155565b8681558594508f91016200038b565b925081926200037d565b634e487b7160e01b84526022600452602484fd5b90607f169062000140565b634e487b7160e01b82526041600452602482fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b60408051919082016001600160401b03811183821017620003ec5760405256fe608080604052600436101561001357600080fd5b600090813560e01c90816301ffc9a714612de95750806306fdde0314612d27578063081812fc14612d08578063095ea7b314612b795780631400ecec14612ad95780631c1cdd4c14612a745780631e99d56914612a5657806323b872dd14612a2c57806339a73c03146129eb57806340e58ee51461272b578063425d30dd1461270c57806342842e0e146126bc57806342966c68146125645780634857501f146124da5780634869e12d1461249f5780635fe3b567146124785780636352211e146124485780636d0cee75146123f257806370a082311461234957806375829def146122b6578063780a82c8146122665780637cad6cd1146121955780637de6b1db14611f865780638659c27014611c60578063894e9a0d14611a0c5780638bad38dd1461198f5780638f69b993146118f35780639067b677146118a057806395d89b411461179357806396ce143114611674578063a22cb465146115a3578063a2ffb897146111c8578063a6202bf2146110cb578063a80fc07114611079578063ab167ccc14610f40578063ad35efd414610ede578063b256456914610ebf578063b88d4fde14610e32578063b8a3be6614610dfd578063b971302a14610dae578063bc063e1a14610d8b578063bc2be1be14610d3b578063c156a11d146109af578063c87b56dd14610875578063cc364f48146107c7578063d4dbd20b14610775578063d511609f14610729578063d975dfed146106dd578063e985e9c514610688578063ea5ead1914610662578063eac8f5b8146105f9578063f590c176146105d0578063f851a440146105aa5763fdd46d601461027357600080fd5b346105a75760603660031901126105a75760043561028f612f18565b610297613058565b906102a0614540565b6102a9836136d6565b61058f576102cd83600052600b6020526001600160a01b0360406000205416331490565b9081158061057f575b61056057838552602092600584526001600160a01b0391826040882054169380610554575b61052e57828116928315610504576001600160801b038084169384156104ec5761032489614602565b82811686116104b85750938093926103ca9261038f6103578d9a99988d8c52600b8d52600260408d20015460801c614650565b8c8b52600b8c5261038a600260408d20019182906001600160801b036001600160801b031983549260801b169116179055565b61366b565b906103ab818c840151169282604081835116920151169061370d565b161115610488575b898852600b8952600160408920015416928361459c565b82877f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d88604051868152a4823314158061047e575b610420575b836000805160206148148339815191528688604051908152a180f35b823b1561047a57608484928360405195869485936313375c3b60e01b85528b6004860152336024860152604485015260648401525af1610462575b8080610404565b61046b90612f94565b61047657823861045b565b8280fd5b8380fd5b50823b15156103ff565b898852600b89526040882060018101600160c81b60ff60c81b1982541617905560ff60f01b1981541690556103b3565b60405163287ecaef60e21b8152600481018b90526001600160801b03928316602482015291166044820152606490fd5b0390fd5b6024896040519063d2aabcd960e01b82526004820152fd5b60046040517fc61a0e9e000000000000000000000000000000000000000000000000000000008152fd5b858360649260405192632dcbf6b960e11b84526004840152336024840152166044820152fd5b508383821614156102fb565b60405163216caf0d60e01b815260048101859052336024820152604490fd5b506105898461466b565b156102d6565b60248360405190634a5541ef60e01b82526004820152fd5b80fd5b50346105a757806003193601126105a7576001600160a01b036020915416604051908152f35b50346105a75760203660031901126105a75760206105ef60043561373c565b6040519015158152f35b50346105a75760203660031901126105a757600435808252600b60205260ff600160408420015460d01c161561064b5760016040836001600160a01b039360209552600b855220015416604051908152f35b6024906040519062b8e7e760e51b82526004820152fd5b50346105a75760403660031901126105a75760043561067f612f18565b61029782614602565b50346105a75760403660031901126105a7576106a2612f02565b60406106ac612f18565b926001600160a01b0380931681526008602052209116600052602052602060ff604060002054166040519015158152f35b50346105a75760203660031901126105a75760ff6001604060043593848152600b60205220015460d01c161561064b57610718602091614602565b6001600160801b0360405191168152f35b50346105a75760203660031901126105a757600435808252600b60205260ff600160408420015460d01c161561064b5760408260029260209452600b845220015460801c604051908152f35b50346105a75760203660031901126105a757600435808252600b60205260ff600160408420015460d01c161561064b5760036040836001600160801b039360209552600b855220015416604051908152f35b50346105a75760203660031901126105a7576004356107e461364c565b50808252600b60205260ff600160408420015460d01c161561064b578160409160609352600b60205220600181549164ffffffffff918291015460a01c16906040519261083084612fe2565b818160a01c16845260c81c166020830152604082015261087360405180926040908164ffffffffff91828151168552826020820151166020860152015116910152565bf35b50346105a75760208060031936011261099f576004356108b36108ae8260005260056020526001600160a01b0360406000205416151590565b61306e565b826001600160a01b03600a5416916044604051809481937fe9dc637500000000000000000000000000000000000000000000000000000000835230600484015260248301525afa9283156109a3578093610922575b505061091e604051928284938452830190612edd565b0390f35b909192503d8082843e610935818461301a565b820191838184031261099f5780519067ffffffffffffffff8211610476570182601f8201121561099f5780519161096b8361303c565b93610979604051958661301a565b8385528584840101116105a757509061099791848085019101612eba565b903880610908565b5080fd5b604051903d90823e3d90fd5b50346105a75760403660031901126105a7576004356109cc612f18565b906109d5614540565b808352602090600b825260ff600160408620015460d01c161561064b57808452600582526001600160a01b03928360408620541693843303610d1c57610a1a83614602565b906001600160801b0390818316918215938415610a59575b896000805160206148148339815191528989610a4f818b8f613301565b604051908152a180f35b610a61614540565b610a6a876136d6565b610d0457610a8e87600052600b6020526001600160a01b0360406000205416331490565b94851580610cf4575b610cd557878b52600589528360408c2054169580610ccb575b610ca757891561050457610c8f57610ac787614602565b8281168511610c5f575090610b27610af48b96959493898852600b8b52600260408920015460801c614650565b888752600b8a5261038a600260408920019182906001600160801b036001600160801b031983549260801b169116179055565b90610b43818a840151169282604081835116920151169061370d565b161115610c2f575b858452600b8752600160408520015416610b6682898361459c565b87867f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d89604051868152a48133141580610c25575b610bca575b50505081610a4f91600080516020614814833981519152958686604051858152a195819338610a32565b813b156104765782916084839260405194859384926313375c3b60e01b84528a60048501523360248501528c604485015260648401525af1610c0d575b80610ba0565b610c1690612f94565b610c21578438610c07565b8480fd5b50813b1515610b9b565b858452600b87526040842060018101600160c81b60ff60c81b1982541617905560ff60f01b198154169055610b4b565b60405163287ecaef60e21b8152600481018990526001600160801b03928316602482015291166044820152606490fd5b6024876040519063d2aabcd960e01b82526004820152fd5b6064888b60405191632dcbf6b960e11b835260048301523360248301526044820152fd5b50858a1415610ab0565b60405163216caf0d60e01b815260048101899052336024820152604490fd5b50610cfe8861466b565b15610a97565b60248760405190634a5541ef60e01b82526004820152fd5b60405163216caf0d60e01b815260048101849052336024820152604490fd5b50346105a75760203660031901126105a757600435808252600b60205260ff600160408420015460d01c161561064b5760408264ffffffffff9260209452600b8452205460a01c16604051908152f35b50346105a757806003193601126105a757602060405167016345785d8a00008152f35b50346105a75760203660031901126105a757600435808252600b60205260ff600160408420015460d01c161561064b576040826001600160a01b039260209452600b8452205416604051908152f35b50346105a75760203660031901126105a75760ff600160406020936004358152600b855220015460d01c166040519015158152f35b50346105a75760803660031901126105a757610e4c612f02565b610e54612f18565b906064359067ffffffffffffffff821161047a573660238301121561047a5781600401359284610e838561303c565b93610e91604051958661301a565b858552366024878301011161099f5785610ebc9660246020930183880137850101526044359161318c565b80f35b50346105a75760203660031901126105a75760206105ef60043561369f565b50346105a75760203660031901126105a757600435808252600b60205260ff600160408420015460d01c161561064b57610f17906139b2565b604051906005811015610f2c57602092508152f35b602483634e487b7160e01b81526021600452fd5b50346105a7576101403660031901126105a757610f5b614540565b610f6361364c565b9064ffffffffff80421680845260c43582811681036110745781018216602085015260e4359081831682036110745701166040830152606435916001600160a01b03918284168094036105a757506084358015158091036110745760a435908115158092036110745760243594848616809603611074576004359585871680970361107457604435906001600160801b038216809203611074576040519761100a89612fc5565b8852602088015260408701526060860152608085015260a084015260c0830152604061010319360112611074576040519161104483612ffe565b610104359182168203611074578261106c9260209452610124358482015260e0820152613ab4565b604051908152f35b600080fd5b50346105a75760203660031901126105a757600435808252600b60205260ff600160408420015460d01c161561064b5760026040836001600160801b039360209552600b855220015416604051908152f35b50346105a75760203660031901126105a7576110e5612f02565b6001600160a01b038083541633810361119f575081169081835260026020526001600160801b0360408420541690811561116e578161113f918486526002602052604086206001600160801b03198154169055339061459c565b6040519081527fca7a4a65a94ed2f37538814e00e1cd4c41a78261561e3f3794592f11409cf5af60203392a380f35b602483604051907f8410168c0000000000000000000000000000000000000000000000000000000082526004820152fd5b6040516331b339a960e21b81526001600160a01b03919091166004820152336024820152604490fd5b50346105a75760603660031901126105a75767ffffffffffffffff600435818111610476576111fb903690600401612f63565b90611204612f18565b92604435908111610c215761121d903690600401612f63565b611228949194614540565b80840361156c5791926001600160a01b038216159290865b81811061124b578780f35b61125681838861462a565b359061126381858a61462a565b356001600160801b03811681036110745761127c614540565b611285836136d6565b61058f576112a983600052600b6020526001600160a01b0360406000205416331490565b80158061155c575b61056057838b5260056020526001600160a01b0360408c2054169080611549575b61151c5787610504576001600160801b03821615611504576112f384614602565b6001600160801b0381166001600160801b038416116114d25750908a91848352600b80602052611363600261038a611334868360408a20015460801c614650565b918988528460205260408820019182906001600160801b036001600160801b031983549260801b169116179055565b6001600160801b03611387816020840151169282604081835116920151169061370d565b1611156114a2575b8584526020526001600160a01b036001604085200154166113ba6001600160801b0384168a8361459c565b6040516001600160801b0384168152867f40b88e5c41c5a97ffb7b6ef88a0a2d505aa0c634cf8a0275cb236ea7dd87ed4d60206001600160a01b038d1693a48033141580611498575b61142c575b5050506000805160206148148339815191526020600193604051908152a101611240565b803b15610476576001600160a01b036084898580946001600160801b0360405197889687956313375c3b60e01b87528d60048801523360248801521660448601521660648401525af1611480575b80611408565b61148990612f94565b61149457883861147a565b8880fd5b50803b1515611403565b858452806020526040842060018101600160c81b60ff60c81b1982541617905560ff60f01b19815416905561138f565b60405163287ecaef60e21b8152600481018690526001600160801b038481166024830152919091166044820152606490fd5b6024846040519063d2aabcd960e01b82526004820152fd5b6064846001600160a01b038960405192632dcbf6b960e11b84526004840152336024840152166044820152fd5b50806001600160a01b03881614156112d2565b506115668461466b565b156112b1565b83604491604051917faec9344000000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b50346105a75760403660031901126105a7576115bd612f02565b60243590811515809203611074576001600160a01b0316908133146116305733835260086020526040832082600052602052604060002060ff1981541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a380f35b606460405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152fd5b50346105a7576101603660031901126105a75761168f614540565b6040519061169c82612fc5565b6116a4612f02565b82526116ae612f18565b60208301526116bb613058565b60408301526001600160a01b03906064358281168103611074576060840152608435801515810361107457608084015260a43580151581036110745760a084015260603660c31901126105a7575060405161171581612fe2565b64ffffffffff60c435818116810361107457825260e435818116810361107457602083015261010435908116810361107457604082015260c0830152604061012319360112611074576040519161176b83612ffe565b610124359182168203611074578261106c9260209452610144358482015260e0820152613ab4565b50346105a757806003193601126105a757604051908060045491600183811c92818516948515611896575b602095868610811461188257858852879493929187908215611860575050600114611806575b50506117f29250038361301a565b61091e604051928284938452830190612edd565b90859250600482527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b8583106118485750506117f2935082010138806117e4565b80548389018501528794508693909201918101611830565b92509350506117f294915060ff191682840152151560051b82010138806117e4565b602483634e487b7160e01b81526022600452fd5b93607f16936117be565b50346105a75760203660031901126105a757600435808252600b60205260ff600160408420015460d01c161561064b57600160408364ffffffffff9360209552600b855220015460a01c16604051908152f35b50346105a75760203660031901126105a757600435808252600b60205260ff600160408420015460d01c161561064b5761192c906139b2565b906005821015908161196d5760028314918215611981575b8215611958575b6020836040519015158152f35b90915061196d5750600460209114388061194b565b80634e487b7160e01b602492526021600452fd5b506003831491506000611944565b50346105a75760203660031901126105a7576004356001600160a01b0390818116809103610476578183541633810361119f575060015491816001600160a01b03198416176001556040519216825260208201527fdcb09aef4bf01068924ccce937981cbe59d25ba08380cf941aaaea4e4bd3960d60403392a280f35b50346105a75760203660031901126105a757604051611a2a81612fa8565b8181528160208201528160408201528160608201528160808201528160a08201528160c08201528160e08201528161010082015281610120820152610140611a7061364c565b9101526004358152600b60205260ff600160408320015460d01c1615611c48576004358152600b60205260408120611b49600260405192611ab084612fa8565b80546001600160a01b038116855264ffffffffff8160a01c16602086015264ffffffffff8160c81c16604086015260ff8160f01c161515606086015260f81c1515608085015260ff60018201546001600160a01b03811660a087015264ffffffffff8160a01c1660c0870152818160c81c16151560e0870152818160d01c16151561010087015260d81c1615156101208501520161366b565b610140820152611b5a6004356139b2565b6005811015610f2c579160026101a09314611c3d575b50610873610140604051926001600160a01b03815116845264ffffffffff602082015116602085015264ffffffffff60408201511660408501526060810151151560608501526080810151151560808501526001600160a01b0360a08201511660a085015264ffffffffff60c08201511660c085015260e0810151151560e0850152610100810151151561010085015261012081015115156101208501520151610140830190604090816001600160801b0391828151168552826020820151166020860152015116910152565b606082015238611b70565b602460405162b8e7e760e51b81526004356004820152fd5b50346105a757602090816003193601126105a75760043567ffffffffffffffff811161099f57611c9583913690600401612f63565b90611c9e614540565b83915b808310611cac578480f35b611cbb8382849795969761462a565b3593611cc5614540565b611cce856136d6565b15611ceb5760248560405190634a5541ef60e01b82526004820152fd5b90919293611cf88161373c565b611f6e57611d1c81600052600b6020526001600160a01b0360406000205416331490565b15611f4e57611d2a8161376d565b90808652600b91828852611d436002604089200161366b565b926001600160801b0391828551168382161015611f3657838952818a5260ff60408a205460f01c1615611f1e579184939189611d9685848e611d8c81998360409e9d511661370d565b990151169061370d565b84825282865288822093898554600160f81b7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82161787556003838516978815611f04575b01928a1692836001600160801b03198254161790556001600160a01b0391828092169560058b522054169488528d60019b8c912001541694611e1c82858861459c565b843b611e8f575b5050604080518681526001600160801b0398891660208201529190971696810196909652600080516020614814833981519152957f5edb27d6c1a327513b90a792050debf074b7194444885e3144d4decc5caaaa5090606090a4604051908152a1019190939293611ca1565b9091929380959697503b15611f00578d9695949392918d91604051916372eba20360e01b835288600484015285602484015260448301526064820152818160848183895af115611e2357611eea919294969893959750612f94565b611efc57949290918b94928b8e611e23565b8a80fd5b8c80fd5b60018101600160c81b60ff60c81b19825416179055611dd9565b602484604051906339c6dc7360e21b82526004820152fd5b602484604051906322cad1af60e11b82526004820152fd5b60405163216caf0d60e01b81526004810191909152336024820152604490fd5b6024906040519063fe19f19f60e01b82526004820152fd5b50346105a75760208060031936011261099f5760043590611fa5614540565b818352600b815260ff600160408520015460d01c161561217e57611fc8826139b2565b600581101561216a5760048103611ff15760248360405190634a5541ef60e01b82526004820152fd5b60038103612011576024836040519063fe19f19f60e01b82526004820152fd5b6002146121525761203882600052600b6020526001600160a01b0360406000205416331490565b1561213357818352600b815260ff604084205460f01c161561211b57818352600b81526040832060ff60f01b19815416905560058152826001600160a01b03604082205416803b6120c4575b505060405160008051602061481483398151915292807f0eb069207093cd3e51cd1370d2d369770057fbe29947e577e5fb428c6c6fc78f8680a28152a180f35b803b1561099f578180916024604051809481937f341a0bd90000000000000000000000000000000000000000000000000000000083528960048401525af1156120845761211090612f94565b610476578238612084565b602482604051906339c6dc7360e21b82526004820152fd5b60405163216caf0d60e01b815260048101839052336024820152604490fd5b602482604051906322cad1af60e11b82526004820152fd5b602484634e487b7160e01b81526021600452fd5b6024826040519062b8e7e760e51b82526004820152fd5b50346105a75760203660031901126105a7576004356001600160a01b0390818116809103610476578183541633810361119f5750600a5491816001600160a01b0319841617600a556040519216825260208201527fa2548bd4b805e907c1558a47b5858324fe8bb4a2e1ddfca647eecbf65610eebc60403392a260095460001981019081116122525760407f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c91815190600182526020820152a180f35b602482634e487b7160e01b81526011600452fd5b50346105a75760203660031901126105a757600435808252600b60205260ff600160408420015460d01c161561064b5760408264ffffffffff9260209452600b8452205460c81c16604051908152f35b50346105a75760203660031901126105a7576122d0612f02565b9080546001600160a01b0380821693338503612322576001600160a01b03199394501691829116178255337fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808380a380f35b6040516331b339a960e21b81526001600160a01b0386166004820152336024820152604490fd5b50346105a75760203660031901126105a7576001600160a01b0361236b612f02565b168015612388578160409160209352600683522054604051908152f35b608460405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f74206120766160448201527f6c6964206f776e657200000000000000000000000000000000000000000000006064820152fd5b50346105a75760203660031901126105a7576001600160a01b0360406020926004356124376108ae8260005260056020526001600160a01b0360406000205416151590565b815260058452205416604051908152f35b50346105a75760203660031901126105a75760206124676004356130b9565b6001600160a01b0360405191168152f35b50346105a757806003193601126105a75760206001600160a01b0360015416604051908152f35b50346105a75760203660031901126105a75760ff6001604060043593848152600b60205220015460d01c161561064b57610718602091613a39565b50346105a75760203660031901126105a75760043590818152600b60205260ff600160408320015460d01c161561217e5780612515836139b2565b92600584101561255057600260209403612536575b50506040519015158152f35b8152600b8352604090205460f01c60ff169050388061252a565b602482634e487b7160e01b81526021600452fd5b50346105a75760203660031901126105a757600435612581614540565b61258a816136d6565b1561268b576125988161466b565b15611f4e576125a6816130b9565b6125af8261369f565b159081612683575b81612670575b50612658576020816125dd600080516020614814833981519152936130b9565b90808552600783526001600160a01b0360408620926001600160a01b03199384815416905516918286526006845260408620600019815401905581865260058452604086209081541690558085604051937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8280a48152a180f35b602490604051906378630aa960e01b82526004820152fd5b6001600160a01b039150161515386125bd565b8391506125b7565b602490604051907f817cd6390000000000000000000000000000000000000000000000000000000082526004820152fd5b50346105a7576126cb36612f2e565b60405191602083019383851067ffffffffffffffff8611176126f657610ebc9460405285845261318c565b634e487b7160e01b600052604160045260246000fd5b50346105a75760203660031901126105a75760206105ef6004356136d6565b50346105a757602090816003193601126105a7576004359161274b614540565b612754836136d6565b156127715760248360405190634a5541ef60e01b82526004820152fd5b61277a8361373c565b6129d35761279e83600052600b6020526001600160a01b0360406000205416331490565b15610d1c576127ac8361376d565b92808352600b82526127c36002604085200161366b565b936001600160801b03908186511682821610156129bb57828552600b845260ff604086205460f01c16156129a35780828561280461280e94838b511661370d565b980151169061370d565b828552600b84526040852091825491600160f81b7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84161784556003828216948515612989575b0191881691826001600160801b03198254161790556001600160a01b0380931691600587528360408920541693600b8852600160408a200154169461289982858861459c565b843b612907575b5050604080518681526001600160801b03998a1660208201529190981697810197909752949560008051602061481483398151915295907f5edb27d6c1a327513b90a792050debf074b7194444885e3144d4decc5caaaa5090606090a4604051908152a180f35b843b1561149457604051916372eba20360e01b835287600484015284602484015260448301526064820152878160848183885af1612946575b806128a0565b90600080516020614814833981519152976129817f5edb27d6c1a327513b90a792050debf074b7194444885e3144d4decc5caaaa5093612f94565b975090612940565b60018101600160c81b60ff60c81b19825416179055612853565b602483604051906339c6dc7360e21b82526004820152fd5b602483604051906322cad1af60e11b82526004820152fd5b6024836040519063fe19f19f60e01b82526004820152fd5b50346105a75760203660031901126105a7576001600160801b0360406020926001600160a01b03612a1a612f02565b16815260028452205416604051908152f35b50346105a757610ebc612a3e36612f2e565b91612a51612a4c8433613222565b61311b565b613301565b50346105a757806003193601126105a7576020600954604051908152f35b50346105a75760203660031901126105a757600435808252600b60205260ff600160408420015460d01c161561064b57612aad906139b2565b90600582101561196d5760208215838115612ace575b506040519015158152f35b600191501482612ac3565b50346105a75760203660031901126105a75760043590818152600b60205260ff600160408320015460d01c161561217e57602091604082828152600b85522060ff815460f01c1680612b67575b612b3e575b50506001600160801b0360405191168152f35b612b6092506001600160801b036002612b5a920154169161376d565b9061370d565b3880612b2b565b5060ff600182015460c81c1615612b26565b50346105a75760403660031901126105a757612b93612f02565b602435906001600160a01b038080612baa856130b9565b16921691808314612c9e57803314908115612c7d575b5015612c1357828452600760205260408420826001600160a01b0319825416179055612beb836130b9565b167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258480a480f35b608460405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152fd5b9050845260086020526040842033855260205260ff60408520541638612bc0565b608460405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152fd5b50346105a75760203660031901126105a75760206124676004356130de565b50346105a757806003193601126105a757604051908060035491600183811c92818516948515612ddf575b602095868610811461188257858852879493929187908215611860575050600114612d855750506117f29250038361301a565b90859250600382527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b858310612dc75750506117f2935082010138806117e4565b80548389018501528794508693909201918101612daf565b93607f1693612d52565b90503461099f57602036600319011261099f576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361047657602092507f80ac58cd000000000000000000000000000000000000000000000000000000008114908115612e90575b8115612e66575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501438612e5f565b7f5b5e139f0000000000000000000000000000000000000000000000000000000081149150612e58565b60005b838110612ecd5750506000910152565b8181015183820152602001612ebd565b90602091612ef681518092818552858086019101612eba565b601f01601f1916010190565b600435906001600160a01b038216820361107457565b602435906001600160a01b038216820361107457565b6060906003190112611074576001600160a01b0390600435828116810361107457916024359081168103611074579060443590565b9181601f840112156110745782359167ffffffffffffffff8311611074576020808501948460051b01011161107457565b67ffffffffffffffff81116126f657604052565b610160810190811067ffffffffffffffff8211176126f657604052565b610100810190811067ffffffffffffffff8211176126f657604052565b6060810190811067ffffffffffffffff8211176126f657604052565b6040810190811067ffffffffffffffff8211176126f657604052565b90601f8019910116810190811067ffffffffffffffff8211176126f657604052565b67ffffffffffffffff81116126f657601f01601f191660200190565b604435906001600160801b038216820361107457565b1561307557565b606460405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152fd5b60005260056020526001600160a01b03604060002054166130db81151561306e565b90565b6131016108ae8260005260056020526001600160a01b0360406000205416151590565b60005260076020526001600160a01b036040600020541690565b1561312257565b608460405162461bcd60e51b815260206004820152602d60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201527f72206f7220617070726f766564000000000000000000000000000000000000006064820152fd5b906131b09392916131a0612a4c8433613222565b6131ab838383613301565b6134ba565b156131b757565b60405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608490fd5b906001600160a01b038080613236846130b9565b16931691838314938415613269575b508315613253575b50505090565b61325f919293506130de565b161438808061324d565b909350600052600860205260406000208260005260205260ff604060002054169238613245565b1561329757565b608460405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152fd5b9061332a9291613310836130b9565b916001600160a01b03948593848094169687911614613290565b16908115806134215761333c8461369f565b159081613418575b508061340f575b6133f7579180849261337960008051602061481483398151915296602096613372856130b9565b1614613290565b60009382855260078652604085206001600160a01b031990818154169055818652600687526040862060001981540190558286526040862060018154019055838652600587528260408720918254161790557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6040519580a48152a1565b602483604051906378630aa960e01b82526004820152fd5b5083151561334b565b90501538613344565b608460405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152fd5b3d156134b5573d9061349b8261303c565b916134a9604051938461301a565b82523d6000602084013e565b606090565b9290803b1561364357613524916020916001600160a01b0394604051809581948293897f150b7a02000000000000000000000000000000000000000000000000000000009b8c86523360048701521660248501526044840152608060648401526084830190612edd565b03916000968791165af1908290826135e3575b50506135bd5761354561348a565b805190816135b85760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608490fd5b602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000161490565b909192506020813d821161363b575b816135ff6020938361301a565b8101031261099f5751907fffffffff00000000000000000000000000000000000000000000000000000000821682036105a75750903880613537565b3d91506135f2565b50505050600190565b6040519061365982612fe2565b60006040838281528260208201520152565b9060405161367881612fe2565b6040819360018154916001600160801b0392838116865260801c6020860152015416910152565b80600052600b60205260ff60016040600020015460d01c161561064b57600052600b60205260ff60016040600020015460d81c1690565b80600052600b60205260ff60016040600020015460d01c161561064b57600052600b60205260ff60016040600020015460c81c1690565b6001600160801b03918216908216039190821161372657565b634e487b7160e01b600052601160045260246000fd5b80600052600b60205260ff60016040600020015460d01c161561064b57600052600b60205260406000205460f81c90565b600090808252600b6020526040822091825464ffffffffff42818360c81c161161381b5780600186015460a01c169182421015613805576137ba9394955060a01c16809103904203613823565b90828152600b6020526001600160801b03926137e0846002604085200154168094613903565b9283116137ed5750501690565b60029350604092508152600b60205220015460801c90565b505050505060026001600160801b039101541690565b505091505090565b670de0b6b3a76400009160001983830992808302928380861095039480860395146138df57828510156138a357908291096001821901821680920460028082600302188083028203028083028203028083028203028083028203028083028203028092029003029360018380600003040190848311900302920304170290565b82606492604051927f63a05778000000000000000000000000000000000000000000000000000000008452600484015260248301526044820152fd5b5050809250156138ed570490565b634e487b7160e01b600052601260045260246000fd5b909190600019838209838202918280831092039180830392146139a157670de0b6b3a7640000908183101561396a57947faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac1066994950990828211900360ee1b910360121c170290565b60449086604051917f5173648d00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b5050670de0b6b3a764000090049150565b80600052600b602052604060002060ff600182015460c81c166000146139d9575050600490565b805460f81c613a32575460a01c64ffffffffff164210613a2c576139fc8161376d565b90600052600b6020526001600160801b038060026040600020015416911610600014613a2757600190565b600290565b50600090565b5050600390565b80600052600b602052613a52600260406000200161366b565b81600052600b602052604060002060ff600182015460c81c16600014613a8557506001600160801b039150602001511690565b5460f81c613a9757506130db9061376d565b6130db91506001600160801b03604081835116920151169061370d565b906001600160a01b036001541660206001600160a01b036060850151166024604051809481937fdcf844a700000000000000000000000000000000000000000000000000000000835260048301525afa80156142d7576000906142a3575b613b3591506001600160801b0360408501511690602060e08601510151916146d4565b916001600160801b0383511660c082015190156142795764ffffffffff815116602082019064ffffffffff8251169081811161423957505064ffffffffff604091511691019064ffffffffff82511690818110156141f957505064ffffffffff80421691511690818110156141b9575050600954926001600160801b0381511660405190613bc282612fe2565b815260006020820152600060408201526001600160a01b036060840151169060c08401519164ffffffffff6020840151169064ffffffffff604085015116906080870151151560a088015115159364ffffffffff6001600160a01b038a511697511660405197613c3189612fa8565b88526020880152604087015260608601526000608086015260a085015260c0840152600060e0840152600161010084015261012083015261014082015284600052600b60205260406000206001600160a01b038251166001600160a01b0319825416178155613cc864ffffffffff602084015116829064ffffffffff60a01b1964ffffffffff60a01b83549260a01b169116179055565b604082015181547eff0000000000000000000000000000000000000000000000000000000000006060850151151560f01b169078ffffffffffffffffffffffffffffffffffffffffffffffffff7dffffffffff000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000006080880151151560f81b169460c81b1691161717178155600181016001600160a01b0360a0840151166001600160a01b0319825416178155613dbf64ffffffffff60c085015116829064ffffffffff60a01b1964ffffffffff60a01b83549260a01b169116179055565b60e083015181546101008501516101208601517fffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff90921692151560c81b79ff00000000000000000000000000000000000000000000000000169290921791151560d01b7aff0000000000000000000000000000000000000000000000000000169190911790151560d81b7bff00000000000000000000000000000000000000000000000000000016179055610140909101518051602082015160801b6001600160801b03199081166001600160801b03928316176002850155926040906003019201511682825416179055600185016009556001600160a01b0360608401511660005260026020526001600160801b0380604060002054168160208501511601166001600160a01b036060850151166000526040600020918254161790556001600160a01b03602083015116801561417557613f3a613f348660005260056020526001600160a01b0360406000205416151590565b1561445d565b613f438561369f565b158061416c575b80614164575b61414c57602060008051602061481483398151915291613f89613f348860005260056020526001600160a01b0360406000205416151590565b806000526006825260406000206001815401905586600052600582526040600020816001600160a01b0319825416179055866040519160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4868152a16140196001600160a01b036060840151166001600160801b038084511681602086015116011690309033906142e3565b6001600160801b036040820151168061411d575b506001600160a01b038251167f075861cbceafeb777e8f15f357121b08f6f3adba387d599bb7b5278ca6192df5610160866001600160a01b03602087015116946141146001600160a01b03606089015116976080810151151560a08201511515906140de6001600160a01b0360e060c08601519501515116956040519788523360208901526040880190604090816001600160801b0391828151168552826020820151166020860152015116910152565b60a086015260c0850152805164ffffffffff90811660e08601526020820151811661010086015260409091015116610120840152565b610140820152a4565b614146906001600160a01b036060850151166001600160a01b0360e086015151169033906142e3565b3861402d565b602485604051906378630aa960e01b82526004820152fd5b506000613f50565b50801515613f4a565b606460405162461bcd60e51b815260206004820152602060248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152fd5b6040517f210aec0e00000000000000000000000000000000000000000000000000000000815264ffffffffff918216600482015291166024820152604490fd5b6040517f9fee269100000000000000000000000000000000000000000000000000000000815264ffffffffff918216600482015291166024820152604490fd5b6040517f4c23297000000000000000000000000000000000000000000000000000000000815264ffffffffff918216600482015291166024820152604490fd5b60046040517f6095d3bc000000000000000000000000000000000000000000000000000000008152fd5b6020823d6020116142cf575b816142bc6020938361301a565b810103126105a75750613b359051613b12565b3d91506142af565b6040513d6000823e3d90fd5b9290604051927f23b872dd0000000000000000000000000000000000000000000000000000000060208501526001600160a01b03809216602485015216604483015260648201526064815260a081019181831067ffffffffffffffff8411176126f65761435292604052614354565b565b6001600160a01b0316906143b460405161436d81612ffe565b6020938482527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564858301526000808587829751910182855af16143ae61348a565b916144a8565b805191821591848315614439575b5050509050156143cf5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152fd5b91938180945001031261099f578201519081151582036105a75750803880846143c2565b1561446457565b606460405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152fd5b9192901561450957508151156144bc575090565b3b156144c55790565b606460405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b82519091501561451c5750805190602001fd5b6104e89060405191829162461bcd60e51b8352602060048401526024830190612edd565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361457257565b60046040517fa1c0d6e5000000000000000000000000000000000000000000000000000000008152fd5b916001600160a01b03604051927fa9059cbb000000000000000000000000000000000000000000000000000000006020850152166024830152604482015260448152608081019181831067ffffffffffffffff8411176126f65761435292604052614354565b6130db9061460f81613a39565b90600052600b60205260026040600020015460801c9061370d565b919081101561463a5760051b0190565b634e487b7160e01b600052603260045260246000fd5b9190916001600160801b038080941691160191821161372657565b60009080825260056020526001600160a01b0380604084205416928333149384156146b0575b5050821561469e57505090565b9091506146ab33926130de565b161490565b60ff9294509060409181526008602052818120338252602052205416913880614691565b9092916146df61364c565b936001600160801b03928381169182156147eb5767016345785d8a00008082116147b45780851161477d57506147298561471a819386613903565b16946020890195865284613903565b169184614740604089019480865282875116614650565b161015614767576147598491826147629551169061370d565b9151169061370d565b168252565b634e487b7160e01b600052600160045260246000fd5b84604491604051917f4fea5c1a00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b60449250604051917f47152d6700000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b505050505090506040516147fe81612fe2565b6000815260006020820152600060408201529056fef8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7a164736f6c6343000815000a"; bytes public constant BYTECODE_NFT_DESCRIPTOR = hex"6080806040523461001757615dac90816200001d8239f35b600080fdfe6080604052600436101561001257600080fd5b60003560e01c63e9dc63751461002757600080fd5b346142f85760403660031901126142f8576001600160a01b0360043516600435036142f857610056608061486e565b60006080819052606060a081905260c082905260e0819052610120819052610140819052610160819052610180919091526101a0526004356001600160a01b03166101008190526100a690614c58565b61012052610100516040517feac8f5b80000000000000000000000000000000000000000000000000000000081526024803560048301529091602091839182906001600160a01b03165afa908115614305576000916147dd575b506001600160a01b03610117911680608052615669565b60a052610100516040517fa80fc0710000000000000000000000000000000000000000000000000000000081526024803560048301529091602091839182906001600160a01b03165afa8015614305576fffffffffffffffffffffffffffffffff916000916147be575b501660c052610100516040517fad35efd40000000000000000000000000000000000000000000000000000000081526024803560048301529091602091839182906001600160a01b03165afa801561430557600090614781575b6101e59150615889565b61014052610100516040517f4869e12d0000000000000000000000000000000000000000000000000000000081526024803560048301529091602091839182906001600160a01b03165afa90811561430557600091614752575b5060c0516fffffffffffffffffffffffffffffffff16801561473c576fffffffffffffffffffffffffffffffff612710819302160416610100608001526102876004356153c7565b610120608001526040514660208201526bffffffffffffffffffffffff1960043560601b16604082015260243560548201526054815280608081011067ffffffffffffffff60808301111761431157608081016040526020815191012061041a602963ffffffff61032e6103078261016861ffff8860101c160616614b08565b91601e604660ff6103248460146050848d60081c16060116614b08565b9816060116614b08565b6040519485927f68736c2800000000000000000000000000000000000000000000000000000000602085015261036e815180926020602488019101614826565b83017f2c0000000000000000000000000000000000000000000000000000000000000060248201526103aa825180936020602585019101614826565b017f252c00000000000000000000000000000000000000000000000000000000000060258201526103e5825180936020602785019101614826565b017f252900000000000000000000000000000000000000000000000000000000000060278201520360098101845201826148df565b6104526fffffffffffffffffffffffffffffffff6040608001511660ff61044b6001600160a01b03608051166155dc565b1690614e89565b6104666001600160a01b0360805116614c58565b60a051610100516040517fbc2be1be0000000000000000000000000000000000000000000000000000000081526024803560048301529091602091839182906001600160a01b03165afa80156143055760249160009161471d575b5060206001600160a01b03608080015116604051938480927f9067b677000000000000000000000000000000000000000000000000000000008252823560048301525afa801561430557610528926000916146ee575b5064ffffffffff80911691166151d5565b61012051610180519092916105b2602161054f6064610548818706615744565b9504614b08565b6040519481610568879351809260208087019101614826565b820161057d8251809360208085019101614826565b017f250000000000000000000000000000000000000000000000000000000000000060208201520360018101855201836148df565b610100608001519260c060800151956101206080015197604051996105d68b61486e565b8a5260208a015260408901526060880152608087015260a086015260c085015260e0840152610100830152610120820152604051806101c081011067ffffffffffffffff6101c083011117614311576101c0810160405260608152600060208201526000604082015260608082015260006080820152606060a0820152600060c0820152600060e08201526060610100820152600061012082015260006101408201526060610160820152600061018082015260006101a082015260a08201516106a660c0840151845190615a7a565b906109b361015c604051926106ba846148c3565b600884527f50726f677265737300000000000000000000000000000000000000000000000060208501526107236040516106f38161488b565b60009052855160208701207fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4701490565b156146e6576090945b61073586614b08565b916040519586938493661e339034b21e9160c91b60208601526109818351958692610767846027840160208901614826565b6d11103334b6361e9111b33333111f60911b602785840101526c1e3932b1ba103bb4b23a341e9160991b603585840101526107ae8551809660206042888701019101614826565b7f22206865696768743d22313030222066696c6c2d6f7061636974793d222e3033828501860160428101919091527f222072783d223135222072793d22313522207374726f6b653d2223666666222060628201527f7374726f6b652d6f7061636974793d222e3122207374726f6b652d77696474686082820152651e911a11179f60d11b60a28201527f3c7465787420783d2232302220793d2233342220666f6e742d66616d696c793d60a88201527f2227436f7572696572204e6577272c417269616c2c6d6f6e6f7370616365222060c8820152703337b73a16b9b4bd329e911919383c111f60791b60e88201528651966108b491889160f990910190602001614826565b661e17ba32bc3a1f60c91b8285018601870160f98101919091527f3c7465787420783d2232302220793d2237322220666f6e742d66616d696c793d6101008201527f2227436f7572696572204e6577272c417269616c2c6d6f6e6f73706163652220610120820152703337b73a16b9b4bd329e91191b383c111f60791b61014082015287519761094f91899161015190910190602001614826565b661e17ba32bc3a1f60c91b6101518888888887010101010152602061015888888885519c8d9701010101019101614826565b631e17b39f60e11b90860190910190910190910190910161015881019190915281900361013c810190915201826148df565b6101008301526101208201526028610100830151604051906109d48261488b565b60008252610c7a61015c604051926109eb846148c3565b600684527f53746174757300000000000000000000000000000000000000000000000000006020850152610a1e84615cba565b610a2782615d37565b808211156146de5750945b610a3d878701614b08565b91604051958693661e339034b21e9160c91b60208601528151610a67816027880160208601614826565b85016d11103334b6361e9111b33333111f60911b60278201526c1e3932b1ba103bb4b23a341e9160991b6035820152610aaa825180936020604285019101614826565b017f22206865696768743d22313030222066696c6c2d6f7061636974793d222e303360428201527f222072783d223135222072793d22313522207374726f6b653d2223666666222060628201527f7374726f6b652d6f7061636974793d222e3122207374726f6b652d77696474686082820152651e911a11179f60d11b60a28201527f3c7465787420783d2232302220793d2233342220666f6e742d66616d696c793d60a88201527f2227436f7572696572204e6577272c417269616c2c6d6f6e6f7370616365222060c8820152703337b73a16b9b4bd329e911919383c111f60791b60e8820152610ba682518093602060f985019101614826565b01661e17ba32bc3a1f60c91b60f98201527f3c7465787420783d2232302220793d2237322220666f6e742d66616d696c793d6101008201527f2227436f7572696572204e6577272c417269616c2c6d6f6e6f73706163652220610120820152703337b73a16b9b4bd329e91191b383c111f60791b610140820152610c3582518093602061015185019101614826565b01661e17ba32bc3a1f60c91b610151820152610c5c82518093602061015885019101614826565b01631e17b39f60e11b6101588201520361013c8101845201826148df565b610160840152016101808201526028602083015160405190610c9b8261488b565b60008252610ce561015c60405192610cb2846148c3565b600684527f416d6f756e7400000000000000000000000000000000000000000000000000006020850152610a1e84615cba565b835201602082015261102060808301516030604051610d038161488b565b60008152610faa61015c60405194610d1a866148c3565b600886527f4475726174696f6e0000000000000000000000000000000000000000000000006020870152610d4d86615cba565b610d5682615d37565b808211156146d65750935b610d6d60288601614b08565b91604051978893661e339034b21e9160c91b60208601528151610d97816027880160208601614826565b85016d11103334b6361e9111b33333111f60911b60278201526c1e3932b1ba103bb4b23a341e9160991b6035820152610dda825180936020604285019101614826565b017f22206865696768743d22313030222066696c6c2d6f7061636974793d222e303360428201527f222072783d223135222072793d22313522207374726f6b653d2223666666222060628201527f7374726f6b652d6f7061636974793d222e3122207374726f6b652d77696474686082820152651e911a11179f60d11b60a28201527f3c7465787420783d2232302220793d2233342220666f6e742d66616d696c793d60a88201527f2227436f7572696572204e6577272c417269616c2c6d6f6e6f7370616365222060c8820152703337b73a16b9b4bd329e911919383c111f60791b60e8820152610ed682518093602060f985019101614826565b01661e17ba32bc3a1f60c91b60f98201527f3c7465787420783d2232302220793d2237322220666f6e742d66616d696c793d6101008201527f2227436f7572696572204e6577272c417269616c2c6d6f6e6f73706163652220610120820152703337b73a16b9b4bd329e91191b383c111f60791b610140820152610f6582518093602061015185019101614826565b01661e17ba32bc3a1f60c91b610151820152610f8c82518093602061015885019101614826565b01631e17b39f60e11b6101588201520361013c8101865201846148df565b8260a08601526028810160c0860152602085015190610120860151809161018088015192839185010101605881016080890152605719906103e8030160011c8061014089015201601081016101a088015201602081016040870152010160e0840152610100830151610160840151845191614e1f565b6060820152604051908161010081011067ffffffffffffffff6101008401111761431157610100820160405260c782527f3c726563742077696474683d223130302522206865696768743d22313030252260208301527f2066696c7465723d2275726c28234e6f69736529222f3e3c7265637420783d2260408301527f37302220793d223730222077696474683d2238363022206865696768743d223860608301527f3630222066696c6c3d2223666666222066696c6c2d6f7061636974793d222e3060808301527f33222072783d223435222072793d22343522207374726f6b653d22236666662260a08301527f207374726f6b652d6f7061636974793d222e3122207374726f6b652d7769647460c08301527f683d2234222f3e0000000000000000000000000000000000000000000000000060e083015282519161010084015191606081015194604051611176816148a7565b603381527f3c636972636c652069643d22476c6f772220723d22353030222066696c6c3d2260208201527f75726c282352616469616c476c6f7729222f3e000000000000000000000000006040820152604051966111d38861486e565b61011c88527f3c66696c7465722069643d224e6f697365223e3c6665466c6f6f6420783d223060208901527f2220793d2230222077696474683d223130302522206865696768743d2231303060408901527f252220666c6f6f642d636f6c6f723d2268736c283233302c3231252c3131252960608901527f2220666c6f6f642d6f7061636974793d22312220726573756c743d22666c6f6f60808901527f6446696c6c222f3e3c666554757262756c656e6365206261736546726571756560a08901527f6e63793d222e3422206e756d4f6374617665733d22332220726573756c743d2260c08901527f4e6f6973652220747970653d226672616374616c4e6f697365222f3e3c66654260e08901527f6c656e6420696e3d224e6f6973652220696e323d22666c6f6f6446696c6c22206101008901527f6d6f64653d22736f66742d6c69676874222f3e3c2f66696c7465723e0000000061012089015260405197886103a081011067ffffffffffffffff6103a08b011117614311576103a0890160405261037b89527f3c706174682069643d224c6f676f222066696c6c3d2223666666222066696c6c60208a01527f2d6f7061636974793d222e312220643d226d3133332e3535392c3132342e303360408a01527f34632d2e3031332c322e3431322d312e3035392c342e3834382d322e3932332c60608a01527f362e3430322d322e3535382c312e3831392d352e3136382c332e3433392d372e60808a01527f3838382c342e3939362d31342e34342c382e3236322d33312e3034372c31322e60a08a01527f3536352d34372e3637342c31322e3536392d382e3835382e3033362d31372e3860c08a01527f33382d312e3237322d32362e3332382d332e3636332d392e3830362d322e373660e08a01527f362d31392e3038372d372e3131332d32372e3536322d31322e3737382d31332e6101008a01527f3834322d382e3032352c392e3436382d32382e3630362c31362e3135332d33356101208a01527f2e323635683063322e3033352d312e3833382c342e3235322d332e3534362c366101408a01527f2e3436332d352e323234683063362e3432392d352e3635352c31362e3231382d6101608a01527f322e3833352c32302e3335382c342e31372c342e3134332c352e3035372c382e6101808a01527f3831362c392e3634392c31332e39322c31332e373334682e30333763352e37336101a08a01527f362c362e3436312c31352e3335372d322e3235332c392e33382d382e34382c306101c08a01527f2c302d332e3531352d332e3531352d332e3531352d332e3531352d31312e34396101e08a01527f2d31312e3437382d35322e3635362d35322e3636342d36342e3833372d36342e6102008a01527f3833376c2e3034392d2e303337632d312e3732352d312e3630362d322e3731396102208a01527f2d332e3834372d322e3735312d362e3230346830632d2e3034362d322e3337356102408a01527f2c312e3036322d342e3538322c322e3732362d362e32323968306c2e3138352d6102608a01527f2e3134386830632e3039392d2e3036322c2e3232322d2e3134382c2e33372d2e6102808a01527f323539683063322e30362d312e3336322c332e3935312d322e3632312c362e306102a08a01527f34342d332e3834324335372e3736332d332e3437332c39372e37362d322e33346102c08a01527f312c3132382e3633372c31382e3333326331362e3637312c392e3934362d32366102e08a01527f2e3334342c35342e3831332d33382e3635312c34302e3139392d362e3239392d6103008a01527f362e3039362d31382e3036332d31372e3734332d31392e3636382d31382e38316103208a01527f312d362e3031362d342e3034372d31332e3036312c342e3737362d372e3735326103408a01527f2c392e3735316c36382e3235342c36382e33373163312e3732342c312e3630316103608a01527f2c322e3731342c332e38342c322e3733382c362e3139325a222f3e00000000006103808a0152604051978860a081011067ffffffffffffffff60a08b01111761431157611cb1611d129160a08b0160405260758b527f3c706174682069643d22466c6f6174696e6754657874222066696c6c3d226e6f60208c01527f6e652220643d224d31323520343568373530733830203020383020383076373560408c01527f307330203830202d3830203830682d373530732d38302030202d3830202d383060608c01527f762d3735307330202d3830203830202d3830222f3e000000000000000000000060808c0152611868615a41565b906040517f3c72616469616c4772616469656e742069643d2252616469616c476c6f77223e6020820152611d0d60d87f3c73746f70206f66667365743d223025222073746f702d636f6c6f723d22000093846040850152805161199a60b88660208501936118da81605e840187614826565b8101997f222073746f702d6f7061636974793d222e36222f3e0000000000000000000000605e8c01527f3c73746f70206f66667365743d2231303025222073746f702d636f6c6f723d229a8b607382015261193f825180936020609385019101614826565b017f222073746f702d6f7061636974793d2230222f3e00000000000000000000000060938201527f3c2f72616469616c4772616469656e743e00000000000000000000000000000060a78201520360988101885201866148df565b6119a2615a41565b90604051967f3c6c696e6561724772616469656e742069643d2253616e64546f70222078313d60208901527f223025222079313d223025223e000000000000000000000000000000000000006040890152604d8801528251611a0881606b8a0184614826565b8701917f222f3e00000000000000000000000000000000000000000000000000000000009283606b82015289606e820152611a4d825180936020608e85019101614826565b019082608e830152611a9160a2897f3c2f6c696e6561724772616469656e743e0000000000000000000000000000009485609182015203608281018b5201896148df565b611bd7610108611a9f615a41565b6040519b8c917f3c6c696e6561724772616469656e742069643d2253616e64426f74746f6d222060208401527f78313d2231303025222079313d2231303025223e00000000000000000000000060408401527f3c73746f70206f66667365743d22313025222073746f702d636f6c6f723d22006054840152611b2b815180926020607387019101614826565b8201908760738301526076820152875190611b4a826096830188614826565b018660968201527f3c616e696d617465206174747269627574654e616d653d22783122206475723d60998201527f2236732220726570656174436f756e743d22696e646566696e6974652220766160b98201527f6c7565733d223330253b3630253b313230253b3630253b3330253b222f3e000060d98201528560f78201520360e881018c52018a6148df565b611bdf615a41565b906040519a8b957f3c6c696e6561724772616469656e742069643d22486f7572676c61737353747260208801527f6f6b6522206772616469656e745472616e73666f726d3d22726f74617465283960408801527f302922206772616469656e74556e6974733d227573657253706163654f6e557360608801527f65223e000000000000000000000000000000000000000000000000000000000060808801527f3c73746f70206f66667365743d22353025222073746f702d636f6c6f723d2200608388015251809260a2880190614826565b84018360a28201527f3c73746f70206f66667365743d22383025222073746f702d636f6c6f723d220060a5820152611cf382518093602060c485019101614826565b019160c483015260c78201520360b88101875201856148df565b614e1f565b92611d32611d1e615817565b896020815191012090602081519101201490565b9788156146ad575b506040518060c081011067ffffffffffffffff60c0830111176143115760c08101604052609081527f3c7061746820643d224d2035302c3336302061203330302c333030203020312c60208201527f31203630302c302061203330302c333030203020312c31202d3630302c30222060408201527f66696c6c3d2223666666222066696c6c2d6f7061636974793d222e303222207360608201527f74726f6b653d2275726c2823486f7572676c6173735374726f6b65292220737460808201527f726f6b652d77696474683d2234222f3e0000000000000000000000000000000060a082015260405193846102c081011067ffffffffffffffff6102c087011117614311576102c0850160405261029885527f3c7061746820643d226d3536362c3136312e323031762d35332e39323463302d60208601527f31392e3338322d32322e3531332d33372e3536332d36332e3339382d35312e3160408601527f39382d34302e3735362d31332e3539322d39342e3934362d32312e3037392d3160608601527f35322e3538372d32312e303739732d3131312e3833382c372e3438372d31353260808601527f2e3630322c32312e303739632d34302e3839332c31332e3633362d36332e343160a08601527f332c33312e3831362d36332e3431332c35312e3139387635332e39323463302c60c08601527f31372e3138312c31372e3730342c33332e3432372c35302e3232332c34362e3360e08601527f3934763238342e383039632d33322e3531392c31322e39362d35302e3232332c6101008601527f32392e3230362d35302e3232332c34362e3339347635332e39323463302c31396101208601527f2e3338322c32322e35322c33372e3536332c36332e3431332c35312e3139382c6101408601527f34302e3736332c31332e3539322c39342e3935342c32312e3037392c3135322e6101608601527f3630322c32312e303739733131312e3833312d372e3438372c3135322e3538376101808601527f2d32312e3037396334302e3838362d31332e3633362c36332e3339382d33312e6101a08601527f3831362c36332e3339382d35312e313938762d35332e39323463302d31372e316101c08601527f39362d31372e3730342d33332e3433352d35302e3232332d34362e34303156326101e08601527f30372e3630336333322e3531392d31322e3936372c35302e3232332d32392e326102008601527f30362c35302e3232332d34362e3430315a6d2d3334372e3436322c35372e37396102208601527f336c3133302e3935392c3133312e3032372d3133302e3935392c3133312e30316102408601527f33563231382e3939345a6d3236322e3932342e303232763236322e3031386c2d6102608601527f3133302e3933372d3133312e3030362c3133302e3933372d3133312e3031335a6102808601527f222066696c6c3d2223313631383232223e3c2f706174683e00000000000000006102a0860152896000146144885760405161218c8161488b565b60008152995b1561432757604051806101e081011067ffffffffffffffff6101e083011117614311576101e081016040526101b181527f3c7061746820643d226d3438312e34362c3438312e35347638312e3031632d3260208201527f2e33352e37372d342e38322c312e35312d372e33392c322e32332d33302e332c60408201527f382e35342d37342e36352c31332e39322d3132342e30362c31332e39322d353360608201527f2e362c302d3130312e32342d362e33332d3133312e34372d31362e3136762d3860808201527f316c34362e332d34362e3331683137302e33336c34362e32392c34362e33315a60a08201527f222066696c6c3d2275726c282353616e64426f74746f6d29222f3e3c7061746860c08201527f20643d226d3433352e31372c3433352e323363302c312e31372d2e34362c322e60e08201527f33322d312e33332c332e34342d372e31312c392e30382d34312e39332c31352e6101008201527f39382d38332e38312c31352e3938732d37362e372d362e392d38332e38322d316101208201527f352e3938632d2e38372d312e31322d312e33332d322e32372d312e33332d332e6101408201527f3434762d2e30346c382e33342d382e33352e30312d2e30316331332e37322d366101608201527f2e35312c34322e39352d31312e30322c37362e382d31312e30327336322e39376101808201527f2c342e34392c37362e37322c31316c382e34322c382e34325a222066696c6c3d6101a08201527f2275726c282353616e64546f7029222f3e0000000000000000000000000000006101c0820152995b60405196876107e081011067ffffffffffffffff6107e08a01111761431157613b9f9c612e5a6036602d9960819f97631e17b39f60e11b8d7f3c2f646566733e000000000000000000000000000000000000000000000000009a612f2b9f6107e0016040526107a782527f3c672066696c6c3d226e6f6e6522207374726f6b653d2275726c2823486f757260208301527f676c6173735374726f6b652922207374726f6b652d6c696e656361703d22726f60408301527f756e6422207374726f6b652d6d697465726c696d69743d22313022207374726f60608301527f6b652d77696474683d2234223e3c7061746820643d226d3536352e3634312c3160808301527f30372e323863302c392e3533372d352e35362c31382e3632392d31352e36373660a08301527f2c32362e393733682d2e303233632d392e3230342c372e3539362d32322e313960c08301527f342c31342e3536322d33382e3139372c32302e3539322d33392e3530342c313460e08301527f2e3933362d39372e3332352c32342e3335352d3136312e3733332c32342e33356101008301527f352d39302e34382c302d3136372e3934382d31382e3538322d3139392e3935336101208301527f2d34342e393438682d2e303233632d31302e3131352d382e3334342d31352e366101408301527f37362d31372e3433372d31352e3637362d32362e3937332c302d33392e3733356101608301527f2c39362e3535342d37312e3932312c3231352e3635322d37312e3932317332316101808301527f352e3632392c33322e3138352c3231352e3632392c37312e3932315a222f3e3c6101a08301527f7061746820643d226d3133342e33362c3136312e32303363302c33392e3733356101c08301527f2c39362e3535342c37312e3932312c3231352e3635322c37312e3932317332316101e08301527f352e3632392d33322e3138362c3231352e3632392d37312e393231222f3e3c6c6102008301527f696e652078313d223133342e3336222079313d223136312e323033222078323d6102208301527f223133342e3336222079323d223130372e3238222f3e3c6c696e652078313d226102408301527f3536352e3634222079313d223136312e323033222078323d223536352e3634226102608301527f2079323d223130372e3238222f3e3c6c696e652078313d223138342e353834226102808301527f2079313d223230362e383233222078323d223138342e353835222079323d22356102a08301527f33372e353739222f3e3c6c696e652078313d223231382e313831222079313d226102c08301527f3231382e313138222078323d223231382e313831222079323d223536322e35336102e08301527f37222f3e3c6c696e652078313d223438312e383138222079313d223231382e316103008301527f3432222078323d223438312e383139222079323d223536322e343238222f3e3c6103208301527f6c696e652078313d223531352e343135222079313d223230372e3335322220786103408301527f323d223531352e343136222079323d223533372e353739222f3e3c70617468206103608301527f643d226d3138342e35382c3533372e353863302c352e34352c342e32372c31306103808301527f2e36352c31322e30332c31352e3432682e303263352e35312c332e33392c31326103a08301527f2e37392c362e35352c32312e35352c392e34322c33302e32312c392e392c37386103c08301527f2e30322c31362e32382c3133312e38332c31362e32382c34392e34312c302c396103e08301527f332e37362d352e33382c3132342e30362d31332e39322c322e372d2e37362c356104008301527f2e32392d312e35342c372e37352d322e33352c382e37372d322e38372c31362e6104208301527f30352d362e30342c32312e35362d392e3433683063372e37362d342e37372c316104408301527f322e30342d392e39372c31322e30342d31352e3432222f3e3c7061746820643d6104608301527f226d3138342e3538322c3439322e363536632d33312e3335342c31322e3438356104808301527f2d35302e3232332c32382e35382d35302e3232332c34362e3134322c302c392e6104a08301527f3533362c352e3536342c31382e3632372c31352e3637372c32362e393639682e6104c08301527f30323263382e3530332c372e3030352c32302e3231332c31332e3436332c33346104e08301527f2e3532342c31392e3135392c392e3939392c332e3939312c32312e3236392c376105008301527f2e3630392c33332e3539372c31302e3738382c33362e34352c392e3430372c386105208301527f322e3138312c31352e3030322c3133312e3833352c31352e3030327339352e336105408301527f36332d352e3539352c3133312e3830372d31352e3030326331302e3834372d326105608301527f2e37392c32302e3836372d352e3932362c32392e3932342d392e3334392c312e6105808301527f3234342d2e3436372c322e3437332d2e3934322c332e3637332d312e3432342c6105a08301527f31342e3332362d352e3639362c32362e3033352d31322e3136312c33342e35326105c08301527f342d31392e313733682e3032326331302e3131342d382e3334322c31352e36376105e08301527f372d31372e3433332c31352e3637372d32362e3936392c302d31372e3536322d6106008301527f31382e3836392d33332e3636352d35302e3232332d34362e3135222f3e3c70616106208301527f746820643d226d3133342e33362c3539322e373263302c33392e3733352c39366106408301527f2e3535342c37312e3932312c3231352e3635322c37312e393231733231352e366106608301527f32392d33322e3138362c3231352e3632392d37312e393231222f3e3c6c696e656106808301527f2078313d223133342e3336222079313d223539322e3732222078323d223133346106a08301527f2e3336222079323d223533382e373937222f3e3c6c696e652078313d223536356106c08301527f2e3634222079313d223539322e3732222078323d223536352e3634222079323d6106e08301527f223533382e373937222f3e3c706f6c796c696e6520706f696e74733d223438316107008301527f2e383232203438312e393031203438312e373938203438312e383737203438316107208301527f2e373735203438312e383534203335302e303135203335302e303236203231386107408301527f2e313835203231382e313239222f3e3c706f6c796c696e6520706f696e74733d6107608301527f223231382e313835203438312e393031203231382e323331203438312e3835346107808301527f203335302e303135203335302e303236203438312e383232203231382e3135326107a08301527f222f3e3c2f673e000000000000000000000000000000000000000000000000006107c0830152604051998a957f3c672069643d22486f7572676c617373223e00000000000000000000000000006020880152603295612df68151809260208a8c019101614826565b8701612e0b8251809360208a85019101614826565b01612e1f8251809360208985019101614826565b01612e338251809360208885019101614826565b01612e478251809360208785019101614826565b01918201520360168101865201846148df565b6040519e8f9788977f3c646566733e000000000000000000000000000000000000000000000000000060208a0152612e9f6026998260208c9451948593019101614826565b8901612eb48251809360208c85019101614826565b01612ec88251809360208b85019101614826565b01612edc8251809360208a85019101614826565b01612ef08251809360208985019101614826565b01612f048251809360208885019101614826565b01612f188251809360208785019101614826565b019182015203600d8101895201876148df565b6137be604c60e08301516101208401519361351a61314d6060604084015193015196612f578186615985565b9461314861012b604051612f6a816148c3565b600581527f2d3130302500000000000000000000000000000000000000000000000000000060208201526040519889917f3c74657874506174682073746172744f66667365743d220000000000000000006020840152612fd4815180926020603787019101614826565b7f2220687265663d2223466c6f6174696e6754657874222066696c6c3d2223666683820160378101919091527f662220666f6e742d66616d696c793d2227436f7572696572204e6577272c417260578201527f69616c2c6d6f6e6f7370616365222066696c6c2d6f7061636974793d222e3822607782015271103337b73a16b9b4bd329e91191b383c111f60711b60978201527f3c616e696d6174652061646469746976653d2273756d2220617474726962757460a98201527f654e616d653d2273746172744f66667365742220626567696e3d22307322206460c98201527f75723d22353073222066726f6d3d2230252220726570656174436f756e743d2260e98201527f696e646566696e6974652220746f3d2231303025222f3e00000000000000000061010982015282519261311891849161012090910190602001614826565b6a1e17ba32bc3a2830ba341f60a91b90830190910161012081019190915281900361010b810190915201876148df565b615985565b9561332c61012b604051613160816148c3565b600281527f30250000000000000000000000000000000000000000000000000000000000006020820152604051998a917f3c74657874506174682073746172744f66667365743d2200000000000000000060208401526131ca815180926020603787019101614826565b82017f2220687265663d2223466c6f6174696e6754657874222066696c6c3d2223666660378201527f662220666f6e742d66616d696c793d2227436f7572696572204e6577272c417260578201527f69616c2c6d6f6e6f7370616365222066696c6c2d6f7061636974793d222e3822607782015271103337b73a16b9b4bd329e91191b383c111f60711b60978201527f3c616e696d6174652061646469746976653d2273756d2220617474726962757460a98201527f654e616d653d2273746172744f66667365742220626567696e3d22307322206460c98201527f75723d22353073222066726f6d3d2230252220726570656174436f756e743d2260e98201527f696e646566696e6974652220746f3d2231303025222f3e00000000000000000061010982015261330782518093602061012085019101614826565b016a1e17ba32bc3a2830ba341f60a91b6101208201520361010b81018a5201886148df565b61333681846159ed565b9261351561012b604051613349816148c3565b600481527f2d3530250000000000000000000000000000000000000000000000000000000060208201526040519687917f3c74657874506174682073746172744f66667365743d2200000000000000000060208401526133b3815180926020603787019101614826565b82017f2220687265663d2223466c6f6174696e6754657874222066696c6c3d2223666660378201527f662220666f6e742d66616d696c793d2227436f7572696572204e6577272c417260578201527f69616c2c6d6f6e6f7370616365222066696c6c2d6f7061636974793d222e3822607782015271103337b73a16b9b4bd329e91191b383c111f60711b60978201527f3c616e696d6174652061646469746976653d2273756d2220617474726962757460a98201527f654e616d653d2273746172744f66667365742220626567696e3d22307322206460c98201527f75723d22353073222066726f6d3d2230252220726570656174436f756e743d2260e98201527f696e646566696e6974652220746f3d2231303025222f3e0000000000000000006101098201526134f082518093602061012085019101614826565b016a1e17ba32bc3a2830ba341f60a91b6101208201520361010b8101875201856148df565b6159ed565b906136f961012b60405161352d816148c3565b600381527f353025000000000000000000000000000000000000000000000000000000000060208201526040519485917f3c74657874506174682073746172744f66667365743d220000000000000000006020840152613597815180926020603787019101614826565b82017f2220687265663d2223466c6f6174696e6754657874222066696c6c3d2223666660378201527f662220666f6e742d66616d696c793d2227436f7572696572204e6577272c417260578201527f69616c2c6d6f6e6f7370616365222066696c6c2d6f7061636974793d222e3822607782015271103337b73a16b9b4bd329e91191b383c111f60711b60978201527f3c616e696d6174652061646469746976653d2273756d2220617474726962757460a98201527f654e616d653d2273746172744f66667365742220626567696e3d22307322206460c98201527f75723d22353073222066726f6d3d2230252220726570656174436f756e743d2260e98201527f696e646566696e6974652220746f3d2231303025222f3e0000000000000000006101098201526136d482518093602061012085019101614826565b016a1e17ba32bc3a2830ba341f60a91b6101208201520361010b8101855201836148df565b6040519586937f3c7465787420746578742d72656e646572696e673d226f7074696d697a65537060208601527f656564223e000000000000000000000000000000000000000000000000000000604086015261375f815180926020604589019101614826565b8401613775825180936020604585019101614826565b0161378a825180936020604585019101614826565b0161379f825180936020604585019101614826565b01661e17ba32bc3a1f60c91b604582015203602c8101845201826148df565b613a9e61019a6101408401516101a0850151906137ff6137f96137f36137ed60e060408b01519a015194614b08565b94614b08565b97614b08565b91614b08565b956040519687937f3c75736520687265663d2223476c6f77222066696c6c2d6f7061636974793d2260208601527f2e39222f3e00000000000000000000000000000000000000000000000000000060408601527f3c75736520687265663d2223476c6f772220783d22313030302220793d22313060458601527f3030222066696c6c2d6f7061636974793d222e39222f3e00000000000000000060658601527f3c75736520687265663d22234c6f676f2220783d223137302220793d22313730607c8601527f22207472616e73666f726d3d227363616c65282e3629222f3e3c757365206872609c8601527f65663d2223486f7572676c6173732220783d223135302220793d22393022207460bc8601527f72616e73666f726d3d22726f746174652831302922207472616e73666f726d2d60dc8601527f6f726967696e3d2235303020353030222f3e000000000000000000000000000060fc8601527f3c75736520687265663d222350726f67726573732220783d220000000000000061010e8601526101279061399a815180926020858a019101614826565b8501937f2220793d22373930222f3e00000000000000000000000000000000000000000080948180948801527f3c75736520687265663d22235374617475732220783d2200000000000000000061013288015261014996613a048251809360208b85019101614826565b01958601527f3c75736520687265663d2223416d6f756e742220783d2200000000000000000061015486015261016b94613a478251809360208985019101614826565b01938401527f3c75736520687265663d22234475726174696f6e2220783d220000000000000061017684015261018f92613a8a8251809360208785019101614826565b01918201520361017a8101855201836148df565b6040519586937f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323060208601527f30302f737667222077696474683d223130303022206865696768743d2231303060408601527f30222076696577426f783d2230203020313030302031303030223e00000000006060860152613b2a815180926020607b89019101614826565b8401613b40825180936020607b85019101614826565b01613b55825180936020607b85019101614826565b01613b6a825180936020607b85019101614826565b017f3c2f7376673e0000000000000000000000000000000000000000000000000000607b8201520360618101845201826148df565b6101605260a051610100516040517fb971302a0000000000000000000000000000000000000000000000000000000081526024803560048301529091602091839182906001600160a01b03165afa908115614305576000916142ba575b6142b661424f614154614245609487613d3b6089613c198a614c58565b9260c0608001516040519485927f5b7b2274726169745f74797065223a224173736574222c2276616c7565223a226020850152613c60815180926020604088019101614826565b8301907f227d2c7b2274726169745f74797065223a2253656e646572222c2276616c756560408301527f223a22000000000000000000000000000000000000000000000000000000000091826060820152613cc5825180936020606385019101614826565b01907f227d2c7b2274726169745f74797065223a22537461747573222c2276616c756560638301526083820152613d06825180936020608685019101614826565b017f227d5d000000000000000000000000000000000000000000000000000000000060868201520360698101845201826148df565b6101a05160a05161403e61017e613d53602435614b08565b9360a060800151613d6e6001600160a01b0360805116614c58565b90604051968793613f2b60208601987f54686973204e465420726570726573656e74732061207061796d656e742073748a527f7265616d20696e2061205361626c696572205632200000000000000000000000604088015282516020840190613ddb8160558b0184614826565b8801947f20636f6e74726163742e20546865206f776e6572206f662074686973204e465460558701527f2063616e207769746864726177207468652073747265616d656420617373657460758701527f732c207768696368206172652064656e6f6d696e6174656420696e2000000000609587015282516020840196613e658260b183018a614826565b017f2e5c6e5c6e2d2053747265616d2049443a20000000000000000000000000000060b1820152613ea082518093602060c385019101614826565b01613ed97f5c6e2d2000000000000000000000000000000000000000000000000000000000958660c384015251809360c7840190614826565b01947f20416464726573733a2000000000000000000000000000000000000000000000958660c7820152613f1782518093602060d185019101614826565b019260d184015251809360d5840190614826565b019060d5820152613f4682518093602060df85019101614826565b017f5c6e5c6e0000000000000000000000000000000000000000000000000000000060df8201527fe29aa0efb88f205741524e494e473a205472616e7366657272696e672074686560e38201527f204e4654206d616b657320746865206e6577206f776e657220746865207265636101038201527f697069656e74206f66207468652073747265616d2e205468652066756e6473206101238201527f617265206e6f74206175746f6d61746963616c6c792077697468647261776e206101438201527f666f72207468652070726576696f757320726563697069656e742e00000000006101638201520361015e8101855201836148df565b6101a051906141af614051602435614b08565b916140d0602d604051809560208201976a029b0b13634b2b9102b19160ad1b8952614086815180926020602b87019101614826565b82017f2023000000000000000000000000000000000000000000000000000000000000602b8201526140c18251809360208785019101614826565b0103600d8101865201846148df565b610160516140dd90614994565b94604051998a977f7b2261747472696275746573223a00000000000000000000000000000000000060208a015261411e815180926020602e8d019101614826565b8801917f2c226465736372697074696f6e223a2200000000000000000000000000000000602e840152518093603e840190614826565b01917f222c2265787465726e616c5f75726c223a2268747470733a2f2f7361626c6965603e8401527f722e636f6d222c226e616d65223a220000000000000000000000000000000000605e840152518093606d840190614826565b017f222c22696d616765223a22646174613a696d6167652f7376672b786d6c3b6261606d8201527f736536342c000000000000000000000000000000000000000000000000000000608d820152614210825180936020609285019101614826565b017f227d00000000000000000000000000000000000000000000000000000000000060928201520360748101845201826148df565b60e0819052614994565b6142a2603d60405180937f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000060208301526142928151809260208686019101614826565b810103601d8101845201826148df565b604051918291602083526020830190614849565b0390f35b90506020813d6020116142fd575b816142d5602093836148df565b810103126142f85751906001600160a01b03821682036142f85790614154613bfc565b600080fd5b3d91506142c8565b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b6040518061012081011067ffffffffffffffff6101208301111761431157610120810160405260f881527f3c7061746820643d226d3438312e34362c3530342e3130317635382e3434396360208201527f2d322e33352e37372d342e38322c312e35312d372e33392c322e32332d33302e60408201527f332c382e35342d37342e36352c31332e39322d3132342e30362c31332e39322d60608201527f35332e362c302d3130312e32342d362e33332d3133312e34372d31362e31367660808201527f2d35382e343339683236322e39325a222066696c6c3d2275726c282353616e6460a08201527f426f74746f6d29222f3e3c656c6c697073652063783d22333530222063793d2260c08201527f3530342e313031222072783d223133312e343632222072793d2232382e31303860e08201527f222066696c6c3d2275726c282353616e64546f7029222f3e0000000000000000610100820152996123df565b604051806101c081011067ffffffffffffffff6101c083011117614311576101c0810160405261019981527f3c706f6c79676f6e20706f696e74733d22333530203335302e3032362034313560208201527f2e3033203238342e39373820323835203238342e39373820333530203335302e60408201527f303236222066696c6c3d2275726c282353616e64426f74746f6d29222f3e3c7060608201527f61746820643d226d3431362e3334312c3238312e39373563302c2e3931342d2e60808201527f3335342c312e3830392d312e3033352c322e36382d352e3534322c372e30373660a08201527f2d33322e3636312c31322e34352d36352e32382c31322e34352d33322e36323460c08201527f2c302d35392e3733382d352e3337342d36352e32382d31322e34352d2e36383160e08201527f2d2e3837322d312e3033352d312e3736372d312e3033352d322e36382c302d2e6101008201527f3931342e3335342d312e3830382c312e3033352d322e3637362c352e3534322d6101208201527f372e3037362c33322e3635362d31322e34352c36352e32382d31322e34352c336101408201527f322e3631392c302c35392e3733382c352e3337342c36352e32382c31322e34356101608201527f2e3638312e3836372c312e3033352c312e3736322c312e3033352c322e3637366101808201527f5a222066696c6c3d2275726c282353616e64546f7029222f3e000000000000006101a082015299612192565b6146cf9198506146bb615850565b906020815191012090602081519101201490565b9638611d3a565b905093610d61565b905094610a32565b60d09461072c565b614710915060203d602011614716575b61470881836148df565b810190614929565b38610517565b503d6146fe565b614736915060203d6020116147165761470881836148df565b386104c1565b634e487b7160e01b600052601260045260246000fd5b614774915060203d60201161477a575b61476c81836148df565b810190614901565b3861023f565b503d614762565b506020813d6020116147b6575b8161479b602093836148df565b810103126142f8575160058110156142f8576101e5906101db565b3d915061478e565b6147d7915060203d60201161477a5761476c81836148df565b38610181565b90506020813d60201161481e575b816147f8602093836148df565b810103126142f857516001600160a01b03811681036142f8576001600160a01b03610100565b3d91506147eb565b60005b8381106148395750506000910152565b8181015183820152602001614829565b9060209161486281518092818552858086019101614826565b601f01601f1916010190565b610140810190811067ffffffffffffffff82111761431157604052565b6020810190811067ffffffffffffffff82111761431157604052565b6060810190811067ffffffffffffffff82111761431157604052565b6040810190811067ffffffffffffffff82111761431157604052565b90601f8019910116810190811067ffffffffffffffff82111761431157604052565b908160209103126142f857516fffffffffffffffffffffffffffffffff811681036142f85790565b908160209103126142f8575164ffffffffff811681036142f85790565b67ffffffffffffffff811161431157601f01601f191660200190565b9061496c82614946565b61497960405191826148df565b828152809261498a601f1991614946565b0190602036910137565b805115614af4576040516149a7816148a7565b604081527f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208201527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f60408201528151600292838201809211614ade5760038092047f3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168103614ade57614a41908594951b614962565b936020850193829183518401925b838110614a8d5750505050510680600114614a7a57600214614a6f575090565b603d90600019015390565b50603d9081600019820153600119015390565b85600491979293949701918251600190603f9082828260121c16880101518453828282600c1c16880101518385015382828260061c1688010151888501531685010151878201530195929190614a4f565b634e487b7160e01b600052601160045260246000fd5b50604051614b018161488b565b6000815290565b806000917a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000080821015614c4a575b506d04ee2d6d415b85acef810000000080831015614c3b575b50662386f26fc1000080831015614c2c575b506305f5e10080831015614c1d575b5061271080831015614c0e575b506064821015614bfe575b600a80921015614bf4575b600190816021614b9f828701614962565b95860101905b614bb1575b5050505090565b600019019083907f30313233343536373839616263646566000000000000000000000000000000008282061a835304918215614bef57919082614ba5565b614baa565b9160010191614b8e565b9190606460029104910191614b83565b60049193920491019138614b78565b60089193920491019138614b6b565b60109193920491019138614b5c565b60209193920491019138614b4a565b604093508104915038614b31565b6001600160a01b031660405190614c6e826148a7565b602a8252602082016040368237825115614d8657603090538151600190811015614d8657607860218401536029905b808211614d0b575050614cad5790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f81166010811015614d71577f3031323334353637383961626364656600000000000000000000000000000000901a614d478486614d9c565b5360041c918015614d5c576000190190614c9d565b60246000634e487b7160e01b81526011600452fd5b60246000634e487b7160e01b81526032600452fd5b634e487b7160e01b600052603260045260246000fd5b908151811015614d86570160200190565b60405190614dba826148c3565b600482527f2667743b000000000000000000000000000000000000000000000000000000006020830152565b60405190614df3826148c3565b600482527f266c743b000000000000000000000000000000000000000000000000000000006020830152565b90614e87929493604051958692602094614e4181518092888089019101614826565b8401614e5582518093888085019101614826565b01614e6882518093878085019101614826565b01614e7b82518093868085019101614826565b010380855201836148df565b565b801561519a5760009180615175575090505b6001908082811015614f0857505050614eb2614de6565b614f05602260405183614ecf829551809260208086019101614826565b81017f203100000000000000000000000000000000000000000000000000000000000060208201520360028101845201826148df565b90565b66038d7ea4c6800011156151185760409081519060a0820182811067ffffffffffffffff82111761431157808452614f3f8161488b565b600081528252825190614f51826148c3565b8482526020917f4b0000000000000000000000000000000000000000000000000000000000000083820152828401528351614f8b816148c3565b8581527f4d0000000000000000000000000000000000000000000000000000000000000083820152848401528351614fc2816148c3565b8581527f42000000000000000000000000000000000000000000000000000000000000008382015260608401528351614ffa816148c3565b8581527f54000000000000000000000000000000000000000000000000000000000000008382015260808401526000918583965b6150ec575b50845194615040866148c3565b6007908187527f2623383830353b0000000000000000000000000000000000000000000000000083880152519560005b8281106150d957505050506150ba6150c0917f20000000000000000000000000000000000000000000000000000000000000006027870152600886526150b5866148c3565b614b08565b91615744565b916005851015614d8657614f059460051b015192614e1f565b8181018401518882018501528301615070565b9591926103e89081851061510f57508680916064600a870406950493019661502e565b93929650615033565b5050615122614dad565b614f0560286040518361513f829551809260208086019101614826565b81017f203939392e39395400000000000000000000000000000000000000000000000060208201520360088101845201826148df565b600a0a918215615186575004614e9b565b80634e487b7160e01b602492526012600452fd5b50506040516151a8816148c3565b600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b620151809103048061523d57506151ea614de6565b614f05602660405183615207829551809260208086019101614826565b81017f203120446179000000000000000000000000000000000000000000000000000060208201520360068101845201826148df565b61270f811161530c57600181036152c957614f056020615291604051615262816148c3565b600481527f20446179000000000000000000000000000000000000000000000000000000008382015293614b08565b60405193816152a98693518092868087019101614826565b82016152bd82518093868085019101614826565b010380845201826148df565b614f0560206152916040516152dd816148c3565b600581527f20446179730000000000000000000000000000000000000000000000000000008382015293614b08565b50615315614dad565b614f05602a60405183615332829551809260208086019101614826565b81017f2039393939204461797300000000000000000000000000000000000000000000602082015203600a8101845201826148df565b6020818303126142f85780519067ffffffffffffffff82116142f8570181601f820112156142f857805161539b81614946565b926153a960405194856148df565b818452602082840101116142f857614f059160208085019101614826565b6001600160a01b031660409081516395d89b4160e01b8152600081600481855afa9081156155a157600091615580575b5061545c8351615406816148c3565b601181527f5341422d56322d4c4f434b55502d4c494e0000000000000000000000000000006020918201528251908301207fc66b376a19264d832c1bc254000c18944ca5aa57ed50f4ea637c4da424d4c3bb1490565b1561549a5750505161546d816148c3565b600d81527f4c6f636b7570204c696e65617200000000000000000000000000000000000000602082015290565b6154fe83516154a8816148c3565b601181527f5341422d56322d4c4f434b55502d44594e0000000000000000000000000000006020918201528251908301207f6ab655856fa5352de8c05542b1937ac63c59342da992602767c02734cc5391651490565b1561553c5750505161550f816148c3565b600e81527f4c6f636b75702044796e616d6963000000000000000000000000000000000000602082015290565b61557c9083519384937f814a8a2e000000000000000000000000000000000000000000000000000000008552600485015260248401526044830190614849565b0390fd5b61559b913d8091833e61559381836148df565b810190615368565b386153f7565b83513d6000823e3d90fd5b3d156155d7573d906155bd82614946565b916155cb60405193846148df565b82523d6000602084013e565b606090565b60405160208101907f313ce56700000000000000000000000000000000000000000000000000000000825260048152615614816148c3565b6000928392839251915afa6156276155ac565b908061565e575b1561565a5760208180518101031261565657602001519060ff82168203615653575090565b80fd5b5080fd5b5090565b50602081511461562e565b6000809160405160208101906395d89b4160e01b82526004815261568c816148c3565b51915afa6156986155ac565b90158015615738575b6156fe57806020806156b893518301019101615368565b601e815111600014614f0557506040516156d1816148c3565b600b81527f4c6f6e672053796d626f6c000000000000000000000000000000000000000000602082015290565b5060405161570b816148c3565b600581527f4552433230000000000000000000000000000000000000000000000000000000602082015290565b506040815111156156a1565b806157565750604051614b018161488b565b600a8110156157bb5761576890614b08565b614f05602260405180937f2e3000000000000000000000000000000000000000000000000000000000000060208301526157ab8151809260208686019101614826565b81010360028101845201826148df565b6157c490614b08565b614f05602160405180937f2e0000000000000000000000000000000000000000000000000000000000000060208301526158078151809260208686019101614826565b81010360018101845201826148df565b60405190615824826148c3565b600782527f536574746c6564000000000000000000000000000000000000000000000000006020830152565b6040519061585d826148c3565b600882527f4465706c657465640000000000000000000000000000000000000000000000006020830152565b600581101561596f57600481036158a35750614f05615850565b600381036158e557506040516158b8816148c3565b600881527f43616e63656c6564000000000000000000000000000000000000000000000000602082015290565b6001810361592757506040516158fa816148c3565b600981527f53747265616d696e670000000000000000000000000000000000000000000000602082015290565b60020361593657614f05615817565b604051615942816148c3565b600781527f50656e64696e6700000000000000000000000000000000000000000000000000602082015290565b634e487b7160e01b600052602160045260246000fd5b6030614e879193929360405194816159a7879351809260208087019101614826565b820164010714051160dd1b60208201526a029b0b13634b2b9102b19160ad1b60258201526159de8251809360208785019101614826565b010360108101855201836148df565b6025614e87919392936040519481615a0f879351809260208087019101614826565b820164010714051160dd1b6020820152615a328251809360208785019101614826565b010360058101855201836148df565b60405190615a4e826148c3565b601082527f68736c283233302c3231252c31312529000000000000000000000000000000006020830152565b8015615cac57615a88615a41565b90612710908103908111614ade57614f0591615aa661013692614b08565b6040519485927f3c672066696c6c3d226e6f6e65223e000000000000000000000000000000000060208501527f3c636972636c652063783d22313636222063793d2235302220723d2232322220602f8501527f7374726f6b653d22000000000000000000000000000000000000000000000000604f850152615b32815180926020605788019101614826565b83017f22207374726f6b652d77696474683d223130222f3e000000000000000000000060578201527f3c636972636c652063783d22313636222063793d2235302220706174684c656e606c8201527f6774683d2231303030302220723d22323222207374726f6b653d220000000000608c820152615bba82518093602060a785019101614826565b017f22207374726f6b652d6461736861727261793d22313030303022207374726f6b60a78201527f652d646173686f66667365743d2200000000000000000000000000000000000060c7820152615c1b82518093602060d585019101614826565b017f22207374726f6b652d6c696e656361703d22726f756e6422207374726f6b652d60d58201527f77696474683d223522207472616e73666f726d3d22726f74617465282d39302960f58201527f22207472616e73666f726d2d6f726967696e3d22313636203530222f3e000000610115820152631e17b39f60e11b610132820152036101168101845201826148df565b5050604051614b018161488b565b60009080518015615d2f579060009182915b818310615cde57505050600d02900390565b909193603b60f81b7fff00000000000000000000000000000000000000000000000000000000000000615d118785614d9c565b511614615d27575b600d01936001019190615ccc565b849350615d19565b505050600090565b60009080518015615d2f579060009182915b818310615d5b5750505060041b900390565b909193603b60f81b7fff00000000000000000000000000000000000000000000000000000000000000615d8e8785614d9c565b511614615da4575b601001936001019190615d49565b849350615d9656";